I’ve been struggling with this issue for a while now. Maybe you can help.
I have a table with a checkbox at the beginning of each row. I defined a function which reloads the table at regular intervals. It uses jQuery’s load() function on a JSP which generates the new table.
The problem is that I need to preserve the checkbox values until the user makes up his mind on which items to select. Currently, their values are lost between updates.
The current code I use that tries to fix it is:
refreshId = setInterval(function()
{
var allTicks = new Array();
$('#myTable input:checked').each(function() {
allTicks.push($(this).attr('id'));
});
$('#myTable').load('/get-table.jsp', null,
function (responseText,textStatus, req ){
$('#my-table').tablesorter();
//alert(allTicks + ' length ' + allTicks.length);
for (i = 0 ; i < allTicks.length; i++ )
$("#my-table input#" + allTicks[i]).attr('checked', true);
});
}, $refreshInterval);
The id of each checkbox is the same as the table entry next to it.
My idea was to store all the checked checkboxes’ ids into an array before the update and to change their values after the update is done, as most of the entries will be preserved, and the ones that are new won’t really matter.
‘#myTable’ is the div in which the table is loaded and ‘#my-table’ is the id of the table which is generated. The checkbox inputs are generated along with the new table and with the same ids as before.
The weird thing is that applying tablesorter to the newly generated table works, but getting the elements with the stored ids doesn’t.
Any solutions?
P.S: I know that this approach to table generation isn’t really the best, but my JS skills were limited back then. I’d like to keep this solution for now and fix the problem.
EDIT:
Applied the syntax suggested by Didier G. and added some extra test blocks that check the status before and after the checkbox ticking.
Looks like this now:
refreshId = setInterval(function()
{
var allTicks = []
var $myTable = $('#my-table');
allTicks = $myTable.find('input:checked').map(function() { return this.id; });
$('#myTable').load('/get-table.jsp', null,
function (responseText,textStatus, req ){
$myTable = $('#my-table');
$('#my-table').tablesorter();
var msg = 'Before: \n';
$myTable.find('input').each(function(){
msg = msg + this.id + " " + $(this).prop('checked') + '\n';
});
//alert(msg);
//alert(allTicks + ' length ' + allTicks.length);
for (i = 0 ; i < allTicks.length; i++ ){
$myTable.find('#' + allTicks[i]).prop('checked', true);
}
msg = 'After: '
$myTable.find('input').each(function(){
msg = msg + this.id + " " + $(this).prop('checked') + '\n';
});
//alert(msg);
});
}, $refreshInterval);
If I uncomment the alert lines, and check 2 checkboxes, on the next update I get (for 3 row table):
Before: host2 false
host3 false
host4 false
object [Object] length 2
After: host2 false
host3 false
host4 false
Also did a previous check on the contents of the array and it has all the correct entries.
Can the DOM change or working with an entirely new table instance be a cause of this?
EDIT2:
Here’s a sample of the table generated by the JSP (edited for confidentiality purposes):
<table id="my-table" class="tablesorter">
<thead>
<tr>
<th>Full Name</th>
<th>IP Address</th>
<th>Role</th>
<th>Job Slots</th>
<th>Status</th>
<th>Management</th>
</tr>
</thead>
<tbody>
<tr>
<td>head</td>
<td>10.20.1.14</td>
<td>H</td>
<td>4</td>
<td>ON</td>
<td>Permanent</td>
</tr>
<tr>
<td>
<input type="checkbox" id="host2" name="host2"/>
host2
</td>
<td>10.20.1.7</td>
<td>C</td>
<td>4</td>
<td>BSTART</td>
<td>Dynamic</td>
</tr>
<tr>
<td><input type="checkbox" id="host3" name="host3"/>
host3</td>
<td>10.20.1.9</td>
<td>C</td>
<td>4</td>
<td>BSTART</td>
<td>Dynamic</td>
</tr>
<tr>
<td><input type="checkbox" id="host4" name="host4"/>
host4</td>
<td>10.20.1.11</td>
<td>C</td>
<td>4</td>
<td>BSTART</td>
<td>Dynamic</td>
</tr>
</tbody>
</table>
Note that the id and name of the checkbox coincide with the host name. Also note that the first td does not have a checkbox. That’s the expected behavior.
After lots of painful hours of digging up every small detail, I realized that my problem was not how I coded the thing, nor was it stuff like unexpected DOM changes, but a simple detail I failed to see:
The id I was trying to assign to the checkbox contained a period (“.”) character.
This causes lots of problems for jQuery when trying to look up that sort of id, because a period as-is acts as a class descriptor. To avoid this, the period character must be escaped using 2 backslashes.
For example:
So then the fix in my case would be:
… and it finally works.
Thanks everyone for all your helping hands!