YUI DataTable with jQuery Filter

The YUI DataTable component is pretty good at most things, but filtering is not one of them. The examples on the YUI website show how to implement server-side filtering via an auto-complete box which updates the data-source URL, re-queries the data-source, and refreshes the table contents upon receiving the results.

But what if your data sets are not large enough to warrant another async call. That is, you want a simple, fast client-side filtering function.

This is where some jQuery data-tables excel (e.g. datatables.net/). I wanted to combine the best of both worlds and have a simple filter that worked with my YUI tables without writing 20 lines of code or doing unnecessary processing. Luckily, this is pretty easy to do.

Have a look at this page to see a self-contained working version of this approach. The key parts are:

<b>Filter:</b> <input type="text" id="filter" onkeyup="yuiDtFilter('dt-container', this.value)" />
<div id="dt-container"></div>

<script type="text/javascript">
yuiDtFilter = function(tableDivId, filter) {
//custom jQuery function defines case-insensitive fn:Contains, use default fn:contains for case-sensitive search
jQuery.expr[':'].Contains = function(a,i,m){
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};
$("#" + tableDivId + " .yui-dt-data").find('tr').hide();
$("#" + tableDivId + " .yui-dt-data").find('td:Contains("' + filter + '")').parents('tr').show();
}
</script>


  • The first line is a filter box with an event handler pointing to our sort function and passing in the div id of the YUI datatable, along with the filter string.
  • The second line is our datatable place-holder.
  • The script block defines the filter function using jQuery. This will perform a case-insensitive search for the filter string in every cell of every row. If found, the row is displayed, otherwise the row is hidden. For a case-sensitive search, just change fn:Contains to fn:contains.
Note that this filter function can be applied to any HTML table by modifying the jQuery selector. The above example uses the fact that tbody within a YUI data-table has the yui-dt-data class attached. You can construct your own tables with your own classes as needed.

Comments

  1. Cool trick! I'm looking into getting this to work with the YUI paginator (ie. to filter entire data set).

    ReplyDelete
  2. Good luck. I actually gave up on the YUI DataTables all together. They're nice but I didn't need any of the data-source functionality and configuring them was to verbose. I'm now just building regular HTML tables in the backend (PHP) and refreshing the whole table via Ajax. Using a bit of jQuery for highlightable rows and filtering.

    ReplyDelete
  3. Thank you a lot, this helped me but how can the filter search for a string in a specific column only not in the table?
    or can it filter a whole table which has been paginated?
    friend

    ReplyDelete
  4. Hi, the first can be done by updating the jQuery filter with the class corresponding to the table column. For the above example, if you wanted to only filter the title column, add 'yui-dt0-col-title' as a class selector. Something like this should probably work:

    $("#" + tableDivId + " .yui-dt-data").find('td.yui-dt0-col-title:Contains("' + filter + '")').parents('tr').show();

    No idea about the pagination, you?d have to refer to YUI docs.

    ReplyDelete
  5. Hi,

    I guess this will fail when datatable has pagination. YUI only defines the dom for the current page displayed so for the whole resultset it will fail.

    ReplyDelete
  6. I change script . now it working with pagination. Some lifehack.

    var RealrowsPerPage=myDataTable.configs.paginator.getRowsPerPage();
    var TotalRows=myDataTable.configs.paginator.getTotalRecords();

    //listening 'input' with id='filter'
    $('#filter').keyup(function (){
    var tableDivId=myDataTable.configs.element;
    var filter=$.trim($('#filter').val().toString());

    if(RealrowsPerPage!=TotalRows)
    myDataTable.configs.paginator.setRowsPerPage(TotalRows);

    jQuery.expr[':'].Contains = function(a,i,m){
    return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
    }
    $("#" + tableDivId + " .yui-dt-data").find('tr').hide();
    $("#" + tableDivId + " .yui-dt-data").find('td:Contains("' + filter + '")').parents('tr').show();

    if(!filter)
    myDataTable.configs.paginator.setRowsPerPage(RealrowsPerPage);
    });

    put that in YUI constructor

    ReplyDelete
  7. How to work with filtering with pagination?
    Can you help me please...

    ReplyDelete
  8. Awesome! Thanks very much.

    ReplyDelete
  9. How can I do this in yui3 based table? Anyone.

    ReplyDelete

Post a Comment

Popular posts from this blog

Wkhtmltopdf font and sizing issues

Import Google Contacts to Nokia PC Suite

Can't delete last blank page from Word