I have a function that checks each cell in each row of a table for the edit-error class. If this is found in any cell of a particular row (The cell value hasn’t passed through validation) then I remove the edit-submit class from the entire row and unselect a checkbox which is in the first td of that row.
When there are a large number of rows (1,000+) I am struggling with performance so I thought I could try for loops but I am not an expert in JavaScript so am looking for help with this.
The original code is as follows:
var checkErrors = function () {
$('#results tr:not(:first)').each(function () {
$('td:first input:checkbox', $(this)).attr('checked', 'checked');
$(this).addClass('edit-submit');
$(this).find('td').each(function () {
if ($(this).hasClass('edit-error')) {
$('td:first input:checkbox', $(this).parent('tr')).removeAttr('checked');
$(this).parent().removeClass('edit-submit');
}
});
});
}
The table has an id of #results. What I do first is check all the checkboxes and add the edit-submit class to each row then loop through all the cells checking for errors.
I am looking for any help with performance improvements on this function please.
EDIT
It would have made sense to add the table html. Apologies for that here it is:
<table id="results">
<tbody>
<tr>
<th> </th>
<th>Policy Number</th>
<th>Quota Code</th>
<th>Contract Date</th>
</tr>
<tr>
<td><input type="checkbox"></td>
<td class="edit-error">ABC123%</td>
<td>123</td>
<td class="edit-error">99/99/9999</td>
</tr>
<tr class="edit-submit">
<td><input type="checkbox" checked="checked"></td>
<td>ABC123</td>
<td>123</td>
<td>16/03/2012</td>
</tr>
</tbody>
</table>
This would show on the page:
-------------------------------------------------- | | Policy Number | Quota Code | Contract Date | -------------------------------------------------- | | ABC123% | 123 | 99/99/9999 | -------------------------------------------------- | X | ABC123 | 123 | 16/03/2012 | --------------------------------------------------
There are several ways to speed up your code without going to a plain JS for loop. To name just a few:
.each()loop so use that rather than calling$(this).parent()within the inner loop..hasClass().$()you can pass a DOM element orthisdirectly, no need to wrap it in another$()call.So:
However, the inner loop on the tds isn’t needed at all since you just need to test whether there are any tds in the row with the error class – you don’t need to actually loop through them all. Plus for good measure here’s one way to use a for loop rather than
.each()– note that you can avoid the complicate not-first selector if you simply select all rows then loop from the second onwards: