Add colgroup for each table column - php

There are probably other similar posts, but here goes nothing.
I am currently reworking on an existing site and some of the changes required involves column and row highlighting, like here (tutorial / demo).
Since there are several web pages to go through, I would like to have some kind of shortcut to dynamically add <colgroup></colgroup> like in the example without having to go through each page and table by hand.
I've considered php's preg_replace function, but I doubt that's the simplest way to go around it. In an optimal scenario, I would be able to verify if there is an existing <colgroup></colgroup> array for each column.

Using jQuery you could dynamically prepend the <colgroup></colgroup> to each table before your highlight script. Something like -
if($("table > colgroup").length == 0){ // If the table does not have <colgroup></colgroup>
var colCount = 0;
$('tr:nth-child(1) td').each(function () { // Get the count of table columns
if ($(this).attr('colspan')) { // if there is a <td colspan>
colCount += +$(this).attr('colspan');
} else {
colCount++;
}
});
var colgroupList = '';
for (i=0;i<colCount;i++){ // Add a <colgroup></colgroup> for each <td>
colgroupList += '<colgroup></colgroup>';
}
$("table").prepend(colgroupList);
}
$("table").delegate('td','mouseover mouseleave', function(e) {
...
jsFiddle example http://jsfiddle.net/BGR22/1/
Edit
If you have multiple tables on a page, you need to add a selector to only get the parent table -
var $table = $(this).closest("table");
So now your $("table").delegate() would look like
$("table").delegate('td','mouseover mouseleave', function(e) {
var $table = $(this).closest("table");
if (e.type == 'mouseover') {
$(this).parent().addClass("hover");
$table.children("colgroup").eq($(this).index()).addClass("hover");
} else {
$(this).parent().removeClass("hover");
$table.children("colgroup").eq($(this).index()).removeClass("hover");
}
});
Updated jsFiddle - http://jsfiddle.net/BGR22/3/
and with 3 tables - http://jsfiddle.net/BGR22/4/

Related

array of same id using getElementById error

i want to create array of same id or name using getElementById..
i have a "add button", when the user press this button, its generate a dropdown list(dynamic) which the value is get from mysql..
and its looks like this when the user press 3 times..
i want to create an array of this id, and store it to mysql..
this is my JS code :
var menu_paket_array = document.getElementById('menu_paket').value;
alert(menu_paket_array);
the problem is, when i try to create this array(menu_paket_array), the value in this array is just the first id (Test 1) only..
how can i fix this?
thanks...
Using the same id for more than one element is wrong. Id is to uniquely identify certain element. Using it for more elements defeats its -purpose. If you need that for i.e. CSS styling, then use class instead, which is designed just for such scenarios.
An ID must be unique on a page. You can only use it on one element.
Instead, use a CSS class or element type to iterate (here's a fiddle demonstrating this code):
function alertValues() {
var select, selects = document.getElementsByTagName('select');
var out = "";
for (var i = 0; i < selects.length; i++) {
select = selects[i];
if (select.className && select.className.match(/CLASSNAME_TO_INCLUDE/)) {
out += select.options[select.selectedIndex].value;
}
}
alert(out);
}
A better solution, of course, would be to utilize a dom library like jQuery or mootools, with which you could do something like this:
jQuery(function($) {
vals = [];
$('select.CLASSNAME').each(function() { vals.push($(this).val()); });
alert(vals.join(','));
});
document.getElementsByClassName(names);
Where names is the classname u generate for each one.
Instead of assigning each element with id='menu_paket' (for the reasons #WebnetMobile.com explained) assign class='menu_paket'.
Instead of var menu_paket_array=document.getElementById('menu_paket').value;, do
var temp_array = document.getElementsByClassName('menu_paket');
var menu_paket_array = [];
for(i in temp_array){
menu_paket_array[] = temp_array[i].value;
}

Getting a record row in php using javascript

Coming from Adobe Flex I am used to having data available in an ArrayCollection and when I want to display the selected item's data I can use something like sourcedata.getItemAt(x) which gives me all the returned data from that index.
Now working in php and javascript I am looking for when a user clicks a row of data (in a table with onClick on the row, to get able to look in my data variable $results, and then populate a text input with the values from that row. My problem is I have no idea how to use javascript to look into the variable that contains all my data and just pull out one row based on either an index or a matching variable (primary key for instance).
Anyone know how to do this. Prefer not firing off a 'read' query to have to bang against the mySQL server again when I can deliver the data in the original pull.
Thanks!
I'd make a large AJAX/JSON request and modify the given data by JavaScript.
The code below is an example of an actual request. The JS is using jQuery, for easier management of JSON results. The container object may be extended with some methods for entering the result object into the table and so forth.
PHP:
$result = array();
$r = mysql_query("SELECT * FROM table WHERE quantifier = 'this_section'");
while($row = mysql_fetch_assoc($r))
$result[$row['id']] = $row;
echo json_encode($result);
JavaScript + jQuery:
container.result = {};
container.doStuff = function () {
// do something with the this.result
console.debug(this.result[0]);
}
// asynchronus request
$.ajax({
url: url,
dataType: 'json',
data: data,
success: function(result){
container.result = result;
}
});
This is a good question! AJAXy stuff is so simple in concept but when you're working with vanilla code there are so many holes that seem impossible to fill.
The first thing you need to do is identify each row in the table in your HTML. Here's a simple way to do it:
<tr class="tablerow" id="row-<?= $row->id ">
<td><input type="text" class="rowinput" /></td>
</tr>
I also gave the row a non-unique class of tablerow. Now to give them some actions! I'm using jQuery here, which will do all of the heavy lifting for us.
<script type="text/javascript">
$(function(){
$('.tablerow').click(function(){
var row_id = $(this).attr('id').replace('row-','');
$.getJSON('script.php', {id: row_id}, function(rs){
if (rs.id && rs.data) {
$('#row-' + rs.id).find('.rowinput').val(rs.data);
}
});
});
});
</script>
Then in script.php you'll want to do something like this:
$id = (int) $_GET['id'];
$rs = mysql_query("SELECT data FROM table WHERE id = '$id' LIMIT 1");
if ($rs && mysql_num_rows($rs)) {
print json_encode(mysql_fetch_array($rs, MYSQL_ASSOC));
}
Maybe you can give each row a radio button. You can use JavaScript to trigger an action on selections in the radio button group. Later, when everything is working, you can hide the actual radio button using CSS and make the entire row a label which means that a click on the row will effectively click the radio button. This way, it will also be accessible, since there is an action input element, you are just hiding it.
I'd simply store the DB field name in the td element (well... a slightly different field name as there's no reason to expose production DB field names to anyone to cares to view the page source) and then extract it with using the dataset properties.
Alternatively, you could just set a class attribute instead.
Your PHP would look something like:
<tr>
<td data-name="<?=echo "FavoriteColor"?>"></td>
</tr>
or
<tr>
<td class="<?=echo "FavoriteColor"?>"></td>
</tr>
The javascript would look a little like:
var Test;
if (!Test) {
Test = {
};
}
(function () {
Test.trClick = function (e) {
var tdCollection,
i,
field = 'FavoriteColor',
div = document.createElement('div');
tdCollection = this.getElementsByTagName('td');
div.innerText = function () {
var data;
for (i = 0; i < tdCollection.length; i += 1) {
if (tdCollection[i].dataset['name'] === field) { // or tdCollection[i].className.indexOf(field) > -1
data = tdCollection[i].innerText;
return data;
}
}
}();
document.body.appendChild(div);
};
Test.addClicker = function () {
var table = document.getElementById('myQueryRenderedAsTable'),
i;
for (i = 0; i < table.tBodies[0].children.length; i += 1) {
table.tBodies[0].children[i].onclick = Test.trClick;
}
};
Test.addClicker();
}());
Working fiddle with dataset: http://jsfiddle.net/R5eVa/1/
Working fiddle with class: http://jsfiddle.net/R5eVa/2/

compare values of cells in different rows in table using jquery

I have a dynamically generated table with php that has same rows. Need to get value from cell 1 in row 1 and value from cell 1 in row 2 and compare them. If they are the same remove entire row or hide... Do that for the whole table... Any help is appreciated.. Thanks!!
Haave this so far:
var numRows = $('table#changeSubjectKatedra tr').lenght;
var i = 0;
do {
var cur = $('input#'+i).val();
var next = $('input#'+(i+1)).val();
if(cur == next){
$('tr#'+i).remove();
}
i++;
} while(i<numRows);
The row in table looks like this:
<tr id='idNum'><td>someText<input type='hidden' value='someData' id='idNum'>
</td><td>someText</td></tr>
Note 1. You should do in on server side with PHP, not with JavaScript.
Note 2. You must use unique id for each element.
Note 3. Avoid using numerical ids of elements.
Note 4. You don't need ids at all for doing what you want.
If you still want to do it in JavaScript, I suggest you to do it this way: (live demo here)
var rows = $("#changeSubjectKatedra tr");
for(var i = 0; i <= rows.length - 2; i++) {
if ($(rows[i]).find("input").val() ==
$(rows[i+1]).find("input").val()) {
$(rows[i]).remove();
}
}
You can use jQuery's .each function. This should work according to the description you provided:
$('table#changeSubjectKatedra tr').each(function() {
if (repeat == $(this).children("input")[0].value) {
$(this).remove();
}
repeat = $(this).children("input")[0].value;
});

is there a better way to code a quotation form?

i am seeking advise and probably example code, links that will help me improve my quotation form. the current scenario is like that:-
dynamic (select combo) rows are generated for items(from mysql database) along with empty input boxes for price and quantity. the user adds or deletes the rows based on no. if items required and fills up the price, quantity etc and then is taken to a second form with all calculated values, etc so he can print the same or send it through email.
now the items count is approx 3500 so when the user reaches 5th or 6th row, it starts becoming extremely slow to add a new row. i need to pull mysql items from database since they keep increasing every now and then.
any help is much appreciated. thanks in advance.
following is the javascript code for dynamic lines that i am currently using:-
<SCRIPT language="javascript">
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var colCount = table.rows[0].cells.length;
for(var i=0; i<colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
//alert(newcell.childNodes);
switch(newcell.childNodes[0].type) {
case "text":
newcell.childNodes[0].value = "";
break;
case "checkbox":
newcell.childNodes[0].checked = false;
break;
case "select-one":
newcell.childNodes[0].selectedIndex = 0;
break;
}
}
}
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
for(var i=0; i<rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox && true == chkbox.checked) {
if(rowCount <= 1) {
alert("Cannot delete all the rows.");
break;
}
table.deleteRow(i);
rowCount--;
i--;
}
}
}catch(e) {
alert(e);
}
}
</SCRIPT>
following is the php code that i am using to pull mysql items to the select combo box
<?php
$con = mysql_connect('connection details');
if (!$con) {
die('Could not connect: ' . mysql_error());}
$db=mysql_select_db('database',$con);
$extract1=mysql_query("query")
OR die(mysql_error());
$numrows1=mysql_num_rows($extract1);
echo "<select name='item[]' title='selectItemName'>";
echo "
<option>Select Item Description</option>
";
while ($row1=mysql_fetch_assoc($extract1))
{
$ic[]=$row1['ItemName'];
}
foreach ($ic as $i){
echo "<option>".$i."</option>";
}
echo "</select>";
mysql_close($con);
?>
i also tried the following example from jquery which is pretty neat. but i am new and do'nt know how to populate the rest of the boxes along with the select box. here's the code
<script type="text/javascript">
$(document).ready(function() {
$("select[multiple]").asmSelect({
addItemTarget: 'bottom',
animate: true,
highlight: true,
sortable: true
});
});
</script>
I don't see where addRow and deleteRow are being called, but I will say here is where some of your inefficiencies may come:
1. var table = document.getElementById(tableID);
2. var rowCount = table.rows.length;
3. var row = table.insertRow(rowCount);
4. var colCount = table.rows[0].cells.length;
Every time you add a row, you're searching the document for the table, which is expensive if you're only working on one table; consider a global variable and doing something like var table = glob_table || document.getElementById(..);
Even though it's a property and isn't as expensive to fetch, this could still be tedious when you could increment/decrement another global variable.
I'm not sure it's proper to add a row to a table, before you add the cells to the row. I'd have to look into this update: I guess it is
(same as #2)
BTW, you're using jQuery at the bottom. Personally, I don't like using jQuery, but if you're going to load it, you've already done most of the damage in slowing down your page, so you might as well use it. It's actually pretty good at adding/removing elements, so I would advise you read some jQuery tutorials.
Also, if your database is increasing, then instead of re-creating the options, you'll only want to update it with items that aren't already loaded. Therefore, you need to use a timpestamp on your database records and store that timestamp in your JavaScript/page in order to "refresh since" (where update_ts >= $last_update_param)
A select combo with ~3500 items? Ouch. (times N for number of rows? Double Ouch.)
Think it may be time to rethink the implementation. I'd probably do a popup window or something for selecting the item that [when closed] populates the form field. Keep the form only holding the value, not value+3500 (times row count).
(Best example I can give is phpBB and when you're in the Admin Control Panel selecting a user you want to manage. They pop-out with the entire [filterable] database then bring the value back to the parent window. I can see this also being advantageous for the user to find an item within 3500 entries, and not scrolling through a select combo)

Printing results from function on page onclick?

Honestly, I'm not even sure the best way to go about this, but essentially, I have a function in an include file that takes a $type parameter and then will retrieve/print results from my db based on the $type passed into it... What I'm trying to do is have a series of links on a page that, when you click on a certain link, will run the function and display the results accordingly...
So, on the initial load of the page, there is a table that displays everything (and I'm simplifying the table greatly...)
<table>
<tr><th>Item</th><th>Type</th></tr>
<tr><td>Milk</td><td>Dairy</td></tr>
<tr><td>Yogurt</td><td>Dairy</td></tr>
<tr><td>Chicken</td><td>Meat</td></tr>
<tr><td>Zucchini</td><td>Vegetable</td></tr>
<tr><td>Cucumber</td><td>Vegetable</td></tr>
</table>
And, then, in a sidebar, I have a series of links:
Dairy
Meat
Vegetable
I'd like to filter the initial table (and back and forth, etc.) based on the link that is clicked, so that if the user clicks "Vegetable", the function from my include file will run and filter the table to show only "Vegetable" types...
The first idea that comes to mind is to add a class attribute to the <tr> tags and id attribs to the <a> tags so that you can easily filter that way:
<tr class="dairy"><td>Milk</td><td>Dairy</td></tr>
<tr class="meat"><td>Chicken</td><td>Meat</td></tr>
Dairy
Meat
Then in your JavaScript (I'm using jQuery here):
$('a').click(function(evt){
var myId = $(this).attr('id');
$('tr').each(function(idx, el){
if ($(el).hasClass(myId))
{
$(el).show();
}
else
{
$(el).hide();
}
});
});
This has the added benefit of allowing you to localize the text without having to change your code.
Ok I created a proper answer. You can do it the way Darrel proposed it. This is just an extension for the paging thing to avoid cookies:
$('a').click(function(evt){
var myId = $(this).attr('id');
// append a idndicator to the current url
var location = "" + document.location + "";
location = location.split('#',1);
document.location = location + '#' + $(this).attr('id');
//append to next and previous links
$('#nextlink').attr({
'href': $('#nextlink').attr('href') + '#' + $(this).attr('id')
});
$('#previouslink').attr({
'href': $('#previouslink').attr('href') + '#' + $(this).attr('id')
});
$('tr').each(function(idx, el){
if ($(el).hasClass(myId))
{
$(el).show();
}
else
{
$(el).hide();
}
});
});
Some code that is executed after page load:
var filter = window.location.hash ? '[id=' + window.location.hash.substring(1, window.location.hash.length) + ']' : false;
if(filter)
$('a').filter(filter).click();
This simulates/executes a click on page load on the link with the specific id.
But in general, if you have a large database, you should filter it directly with SQL in the backend. This would make the displayed table more consistent. For example if page 1 may only have 3 rows of class 'dairy' and on page 2 10 of class 'dairy'.
If youre printing out the whole tabel up front there is no need to go back to the server you can simple hide all teh rows of a given type. For example with jQuery:
$('#sidebar a').click(function(){
// grab the text content of the a tag conver to lowercase
var type = $(this).text().toLowerCase();
/* filter all the td's in the table looking for our specified type then hid the
* row that they are in
*/
$('#my_data_table td').contents().filter(function(){
return this.nodeType == 3 && this.toLowerCase() == type;
}).parent('tr').hide();
return false;
});
Really though the suggestion abotu adding a class to the TR is better because filtering on text content can get tricky if there is content youre not expecting for some reason (hence my conversion to all lower case to help with this).

Categories