jQuery Auto-Filtering Table
Posted At : October 2, 2008 6:47 AM | Posted By : Bob Silverberg
Related Categories: jQuery
I've been using jQuery for about a year now and I must admit that pretty much any JavaScript that I wrote prior to that looks ugly to me now. I know I'm nowhere near the first person to say this, but if you write JavaScript and you aren't using jQuery, you should check it out. Now.
Anyway, I wanted to show you how easy it is to do something cool with jQuery. The next thing I'll admit is that much of what I'm doing with jQuery involves using existing plugins written by other, more seasoned JavaScripters than me. But enough talk, here's the table:
Country | Province/State | City |
---|---|---|
Canada | Alberta | Calgary |
Canada | Alberta | Edmonton |
Canada | British Columbia | Vancouver |
Canada | British Columbia | Victoria |
Canada | Ontario | Ajax |
Canada | Ontario | Kingston |
Canada | Ontario | London |
Canada | Ontario | Ottawa |
Canada | Ontario | Toronto |
United States | California | Los Angeles |
United States | California | San Francisco |
United States | California | San Jose |
United States | Texas | Dallas |
United States | Texas | Houston |
United States | Texas | Lubbock |
You'll notice that you can sort the table by any of the columns, in both ascending and descending order, and even by multiple columns if you hold down the Shift key while clicking. That sortable behaviour, and the nice zebra striping is all part of the awesome tablesorter plugin, written by Christian Bach.
Now see what happens when you click on a Country or a Province/State in the table. That's right, the table filters itself based on your selection. Clicking on the same Country or Province/State removes the filter. Once the table is filtered you can still sort on any or all of the columns. This filtering functionality is provided by the only slightly less awesome uiTableFilter plugin, written by Greg Weber.
All I had to do was write a few lines of code to implement the plugins and set up the events to be fired when clicking the data in the table:
2$(document).ready(function() {
3 $table = $("#myTable")
4 .tablesorter({widthFixed: true, widgets: ['zebra']});
5 FilterText = "";
6 ColumnArray = ["Country","Province/State"];
7 for (i=0;i<ColumnArray.length;i++) {
8 $("#myTable tbody tr").find("td:eq(" + i + ")").click( function() {
9 clickedText = $(this).text();
10 FilterText = ((FilterText == clickedText) ? "" : clickedText );
11 $.uiTableFilter( $table, FilterText, ColumnArray[i]);
12 });
13 }
14});
15</script>
First I make the table, which has an id of "myTable", sortable using the tablesorter plugin. Next I create a couple of local variables:
- FilterText will hold the current value that is being used to filter the table.
- ColumnArray is an array of column headings that I want to be clickable.
I then loop through the ColumnArray assigning a click event to the proper column of each table row. The click event captures the text that was clicked on and saves it to clickedText. clickedText is then compared to FilterText to determine whether to apply a new filter (if a new value was clicked) or remove the filter (if the same value was clicked). Finally the new filter is applied to the proper column of the table.
And there you have it, a pretty neat trick accomplished with very few lines of JavaScript Code.
Regarding the tablesorter plugin, it truly is awesome and can do a lot more that I have described in this post. In addition to being incredibly configurable, it also has a paging addon that gives you a full featured paging control for your table.
http://tablesorter.com/docs/example-pager.html
http://extjs.com/playpen/ext-2.0/examples/grid/gri...
yummy
Thanks
when I click on the first record over text "service" I expect only the 1° record but I have the 1° and 2° because the text in second column contains "service" too.
Sorry for my english but I hope that you understand my problem and you can solve it.
Thank
$.uiTableFilter( $table, FilterText, ColumnArray[i]);
may not be passing a valid ColumnArray element. In particular, if you have the same text in a different column, the respective row will be included in the filtered results.
I changed the code to the following, which seemed to work properly ...
for (i=0;i<ColumnArray.length;i++) {
$("#first_table tbody tr").find("td:eq(" + i + ")").click( function() {
clickedText = $(this).text();
FilterText = ((FilterText == clickedText) ? "" : clickedText );
ColumnHeader = ColumnArray[this.cellIndex];
$.uiTableFilter( $table, FilterText, ColumnHeader);
});
thank you, your code work properly.
Now to solve the problem I have splitted the code for each column
$("#myTable tbody tr").find("td:eq(" + 0 + ")").click( function() {
clickedText = $(this).text();
FilterText = ((FilterText == clickedText) ? "" : clickedText );
$.uiTableFilter( $table, FilterText, "MyColumn");
});
but your code is better.
I have one question though. I have a row with dates and I would like to filter on those. Now when I have for example "Aug. 1, 2010" and "Aug. 31, 2010" in that row, it shows both when I click on "Aug. 1, 2010". This can be solved by formatting the date such that it has a 0 in front of the 1-digit days, but I prefer the non-zero version. Do you have any idea how this could be solved?
In the example presented above, if you sort by city and then filter to only Canada you'll notice that the background ("zebra") striping is wrong. It happens because the tablesorter plugin doesn't get the message that its data has been updated.
Here's sample code with the appropriate fix in place :
$table = $("#myTable")
.tablesorter({widthFixed: true, widgets: ['zebra']});
FilterText = "";
ColumnArray = ["Country","Province/State"];
for (i=0;i<ColumnArray.length;i++) {
$("#myTable tbody tr").find("td:eq(" + i + ")").click( function() {
clickedText = $(this).text();
FilterText = ((FilterText == clickedText) ? "" : clickedText );
$.uiTableFilter( $table, FilterText, ColumnArray[i]);
$("myTable").trigger("applyWidgets");
});
}
Hope someone out there finds this handy! Thanks again for the great post.
-Matt
And I missed a #
So here's the short version. Add the following line after the call to $.uiTableFilter(...) :
$("#myTable").trigger("applyWidgets");
Hope that helps,
-Matt
All I can see is a sorter plugin - a filter plugin provides a drop-down list on the field title, allowing you to select specific results...this does not do that, and is incorrectly named.
How to make subtotal of values of filtered rows.
ABCD
1XOOO
2OOOO
3OOXO
4OXOO
With a table of repeat values, eg naughts and crosses as above. Is there a way to code tablefilter to return just row 1 if I click on the X in column A, rather than getting rows 1,3,4, i.e. all rows with an X?