Wednesday, January 14, 2009

Filtering Table Results with jQuery

A few weeks ago, I was looking for a way to filter records in a table.  The screen that I was going to use this one was a composite/advanced search screen to where after the results are populated, the user can continue typing in search results into other fields and it would auto-filter.

 

There are a large amount of jQuery plug-ins that offer table filtering features.  I reviewed the TableSorter plug-in; however, I didn't want a filtering system where 1 text box would filter all columns.  That plug-in works extremely well and I am using it in other areas, but I'm looking for a text box-to-column filtering mechanism instead. Bill Beckelmen, who has a lot of great posts and examples on the TableSoter plug-in, suggested trying the jQuery Column Filter or tablefilter plug-ins.  Both were better; however, also auto-created the text boxes in another header row for the table.  After looking a bit more, I came to the conclusion that I would need to write my own functionality.  If I continue working on refining this code, I will probably see about turning it into a plug-in for easier use.

 

Post Downloads:

Table Filtering with jQuery Example - TableFilter.zip

 

The filterColumn Function:

At the heart of the filtering process is a JavaScript function called filterColumn.  This function takes 2 parameters.  The first parameter takes the text name of the table column that is being evaluated.  The second parameter is the text value to filter on.  For the sake of the example, the filterColumn function will be bound to each text box's onKeyUp event; passing it's current value for the filtering text.

Inside of the filterColumn function, 3 things occur to make the filtering mechanism work.  First, the two input parameters are inserted into regular expression patterns that will be used to locate the table column header as well as the records in that column once found.  The second thing it does is loop through the column header (first table row in the thead tag that contains th tags...or "#resultsTable thead tr:first th" in jQuery selector syntax) to locate the column's index.  Lastly, it loop through the table's records using the column's index and sets the row's display style to "none" if it doesn't match the filtering criteria.

   1: function filterColumn(columnHeader, value){
   2:  
   3:     // set regex objects with the appropriate patterns.
   4:     var headerPattern = new RegExp('^' + columnHeader + '$', 'i');
   5:     var filterPattern = new RegExp('^' + value + '', 'i');
   6:  
   7:     // initialize the column identifier
   8:     var colIndex = -1;
   9:     
  10:     // loop through the header's first row of cells
  11:     var headerRow = $("#resultsTable thead tr:first th");
  12:     headerRow.each(function(n){
  13:         if (headerPattern.test($.trim(this.innerHTML))){
  14:             colIndex = n;        
  15:         }    
  16:     });
  17:     
  18:     // check to see if the column was found.
  19:     if (colIndex > -1){
  20:         
  21:         // loop through each table body row and evaulate the proper cell.
  22:         var bodyRows = $("#resultsTable tbody tr");
  23:         bodyRows.each(function(n){
  24:             if(!filterPattern.test($.trim(this.childNodes[colIndex].innerHTML))){
  25:                 this.style.display = 'none';
  26:             }
  27:             else {
  28:                 this.style.display = '';
  29:             }
  30:         });
  31:     }
  32: }

Next Steps:

I have a lot of refinement to go on this function if I am thinking about converting it into a plug-in at some point.  I need to make the table's id not hard coded and bind the onKeyUp events when the search button is pressed instead of having it attached all the time in the HTML.  In addition, I need to look into incorporating a zebra-striping plug-in as well to have it address the row styling after the filtering. 

The code is a great starting point and it's very useful as is.  With a little refinement, it can provide a very robust mechanism for simple table filtering without having to learn and use a very complex plug-in.


kick it on DotNetKicks.com

4 comments:

  1. Already done with jQuery. Google "Allan Jardine" tables

    ReplyDelete
  2. While the DataTables plug-in is good, it didn't fit the same model that I presented here where a single column could be mapped to a text box. The DataTables plug-in appears to allow specific columns to be searched/filtered; however, still is based on a single textbox. This design works great in a large number of instances; however, didn't give the level of granularity that I was needing for the project that sparked this blog post.

    ReplyDelete
  3. Good and simple implementation using regex. Instead of

    var filterPattern = new RegExp('^' + value + '', 'i');

    you can use

    var filterPattern = new RegExp('(' + value + ')', 'i');

    which searches for occurrences throughout the string. ie. the second expression matches 'order' in 'purchaseorder' whilst the first don't.

    ReplyDelete
  4. Hey thanks it really worked awesome.....

    ReplyDelete