Filtering a table row with javascript

I am trying to filter information read from a database. I am using JSTL to iterate through a bean and display all the results. I then want to be able to filter those results with an input box, letter by letter. I have this working but it is really slow when I have a large result set (800 rows). I realize it is slow because it is reading every row and then the <td> with the id=desc. I also alternate the row color class.

Please let me know if you can help speed this up.

I pasted my javascript code below and attached a txt file.
function filter (phrase, _id){
	var words = phrase.value.toLowerCase().split(" ");
	var table = document.getElementById(_id);
	var ele;
	for (var r = 1; r < table.rows.length; r++){;
		ele = $('desc'+r).innerHTML;
	        var displayStyle = 'none';
	        for (var i = 0; i < words.length; i++) {
		    if (ele.toLowerCase().indexOf(words[i])>=0)
			displayStyle = '';
		    else {
			displayStyle = 'invisibleRow';
			break;
		    }
	        }
		table.rows[r].className = displayStyle;
	}
	alternate(_id);
}
 
function alternate(id) {
	var i,j,tab,rows,row,tr;
	rows = document.getElementById(id).rows;	
	row=0;
	for(i=0,tr; tr=rows[i]; i++) {
		if (rows[i].className != 'invisibleRow') {
			row++;
			tr.className = (row % 2 == 0) ? "even" : "odd";
		}
	}
}

Open in new window

table-filter.txt
stinklefinkAsked:
Who is Participating?
 
MorcalavinConnect With a Mentor Commented:
As for optimization, I see three major things you can do:
  1. Follow ChristoferDutz suggestions.  However, this won't give you that "dynamic" affect you are looking for, since you would have to type in your filter, submit it to the server, have the server return the new data based on the filter you provided, unless you implement it via AJAX
  2. You are re-evaluating your length in your loops.  Instead of:
    for(var i = 0; i < array.length; i++)
    do
    for(var i = 0, e = array.length; i < e; i++)
    This doesn't provide a lot of optimization, but every little bit helps.
  3. I see no need for 2 separate loops, both of these could be combined into one.  Every time you change the CSS value, the browser has to "repaint" or "reflow" the entire document.  Doing this 1600 times is slow.  800 times is slow as well, but not as slow as 1600 times.
0
 
ChristoferDutzConnect With a Mentor Commented:
Well I think if you are working with a table you will not be able to speed this up very much.
In general there are two problems:
1. Parsing the HTML for the large table simply takes its time and even more memory
2. The browser starts "drawing" a table as soon as it reads the closing table-tag.

I'd recomend a combination of these:
1. doing the filtering on the server side
2. Loading the table raw by using something like a Dojo Datagrid
3. Using Divs instead of Table, TR and TD or TH

First thing simply reduces the amount of code the browser has to process.
Second reduces the memory and network load. As it's Tables are based on Divs, this makes the third tip obsolete.
The last tip (the one with the divs) simply lets the browser start drawing as soon as it reads the first cell. Divs can be dynamically layouted and the user will not recognize, that the table is still loading after the screen is full of table ;-)

Id' suggest a combination of 1. and 2. ... that's what I always use.
0
 
HonorGodCommented:
How static is your table?
If it is changing all the time, the following may not help.

Instead of using document.getElementById() to locate the different table rows,
I would consider building a dictionary indexed by the table rowId, and have the associated value be a reference to the specific table row in question.

Are you building the table dynamically?
If so, you should be able to build this dictionary very easily.

Does this make sense?
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
ChristoferDutzCommented:
Well the Dojo Grid does exactly this using AJAX.

In one of my last projects I had to tune an existing application that displayed HTML tables with 400-700 rows. When hitting "Save As..." and looking at the size of this HTML sizes of 15-30MB were quite common. When having a look at the IE memory consumption (I know this is no good reference) it jumped up about 50-75MB just for displaying the data. No matter if it was hidden or displayed.

No matter which approach I had, As long as the data is sent along with the page, you will be having problems. You could reduce this load (If you want to avoid AJAX stuff) and use a Dojo DataGrid and let it use a local datasource and initialize this datasource as an Array of JavaScript Arrays. This way memory and network load should be greatly reduced and the JavaScript Parser is a lot faster than the Html Rederer ;-)

My suggestion is to separate the View (HTML Page) and the Data (Table content). There are quite a lot of DataGrids available. I can only recomend the Dojo DataGrid.
0
 
stinklefinkAuthor Commented:
Morcalavin,

Could you please attach the changes to the javascript? I change the loop but receive an error. I would like to remove one loop and see if any faster.
0
 
stinklefinkAuthor Commented:
Is there a way to directly respond back to a comment/expert?
0
All Courses

From novice to tech pro — start learning today.