Reputation: 165
I got this code
$(document).ready(function() {
var activeSystemClass = $('.list-group-item.active');
//something is entered in search form
$('#searchfor').keyup( function() {
var that = this;
// affect all table rows on in systems table
var tableBody = $('.table-list-search').find('tbody');
var tableRowsClass = $('.table-list-search tbody').find('tr');
$('.search-sf').remove();
tableRowsClass.each( function(i, val) {
//Lower text for case insensitive
var rowText = $(val).text().toLowerCase();
var inputText = $(that).val().toLowerCase();
if(inputText != '')
{
$('.search-query-sf').remove();
tableBody.prepend('<tr class="search-query-sf"><td colspan="6"><strong>Searching for: "'
+ $(that).val()
+ '"</strong></td></tr>');
}
else
{
$('.search-query-sf').remove();
}
if( rowText.indexOf( inputText ) == -1 )
{
//hide rows
tableRowsClass.eq(i).hide();
}
else
{
$('.search-sf').remove();
tableRowsClass.eq(i).show();
}
});
//all tr elements are hidden
if(tableRowsClass.children(':visible').length == 0)
{
tableBody.append('<tr class="search-sf"><td class="text-muted" colspan="6">No entries found.</td></tr>');
}
});
});
From http://bootsnipp.com/snippets/featured/js-table-filter-simple-insensitive . The purpose of the code is to scan a table and filtering ("searching") for the keyword entered. I already followed a guide on how to speed the code up. But still for a table of >400 records the code freezes the browser. Is there a way to rewrite this code so it will run quicker. I alreay tried to remove the each() but as I am not to good with JavaScript I failed terribly.
Upvotes: 0
Views: 139
Reputation: 46
The issue in performance is no doubt caused by accessing the DOM so many times on every key up. If you must access the table data this way (rather than JSON, for example), your best bet would be indexing the table rows into an array first that can be searched more efficiently.
Before that, you will typically want to cache the DOM elements you're accessing outside of an event handler if possible, otherwise jQuery has to find these elements every time the event is triggered. Also take advantage of existing selectors (e.g. tableBody
) for getting child elements.
First, we have:
var tableBody = $('.table-list-search').find('tbody');
var tableRowsClass = tableBody.find('tr');
We then index the table, adding the text from the rows into the tableData
array one at a time. Outside of and before the keyup event you have this:
// store the table data in an array
var tableData = [];
tableRowsClass.each(function(i, val) {
tableData.push($(val).text().toLowerCase());
});
Finally, we dig through the table data array in the keyup event using each() to find multiple instances of a search term.
// scan the table data array on each keyup
$('#searchfor').keyup(function() {
var inputText = $(this).val().toLowerCase();
// use each instead of indexOf to get multiple instances
$(tableData).each(function(i, val){
if (val.indexOf(inputText) > -1) {
// the index of the data in the array will be the same
// as the corresponding table row
tableRowsClass.eq(i).show();
} else {
tableRowsClass.eq(i).hide();
}
});
});
This will no doubt result in significantly more efficient table searching. Accessing data stored in JavaScript will always be quicker than retrieving it from the DOM, simply due to less processing overhead.
See a working example using the code above here: http://jsfiddle.net/ah88w55k/
Upvotes: 3