Thursday, April 7, 2011

How to filter p:dataTable on enter event

PrimeFaces' datatable doesn't support the filtering for "onenter" event. It's not a DOM event, but it makes sense for large datatables to filter a dataset when the enter (return) key was pressed. Many users complain that they can't filter large datasets on each keystroke, only hitting of return key makes sense for them. That's exactly my case too. I use "onenter" event for filtering because a datatable sends too many requests if user inputs and removes characters very quickly. An update of the table is very slow then. The solution is not difficult. Use filterEvent="enter" in any p:column needing a filtering like this
 
<p:dataTable id="myTable" var="user" value="#{myBean.users}"
             widgetVar="myTblWidget">
  ...
  <p:column filterBy="#{user.name}" filterEvent="enter">
    ...
  </p:column>
  ...
</p:dataTable>
 
and place this little JavaScript direct after p:dataTable (can be also placed into an ui:include for better reusing)
 
<script type="text/javascript">
/* <![CDATA[ */
  jQuery(myTblWidget.jqId).find('th .ui-column-filter[onenter]').each(function(idx) {
  var curEl = jQuery(this);
  curEl.unbind('keydown');

  curEl.keydown(function(event) {
    var e = (window.event) ? window.event : event;
    if(e.keyCode == 13) {
      event.preventDefault();
      eval(curEl.attr('onenter'));
    }
  })
});
/* ]]> */
</script>
 
The script binds "keydown" event for the enter key on every input field using for the filtering (select boxes using for this purpose don't matter here). If the enter key has been detected, the built-in client-side callback being executed (by means of the JS eval function) and sends an Ajax request to filter the table. It works like a charm. I also have a meaningful tooltip for every input field using for the filtering. The reason is clear - this kind of the filtering is not always easy to understand for end users. A tooltip seems to be very handy.

17 comments:

  1. Nice work around Oleg.
    Do you have any idea how to implement a customized filter, i want to write a customized filter on enter key event.

    Thanks
    Pravin.

    ReplyDelete
  2. Hi,

    Hmm... I know that you can add your own sort function with PrimeFaces on-board means, but a custom filter... No idea.

    ReplyDelete
  3. Hey Oleg, how did you add those tooltips to the search boxes in the Datatable?

    ReplyDelete
  4. i got the error: tblWidget is not defined
    i put the script just after de datatable, can you help me?

    ReplyDelete
  5. What is your widgetVar? The variable in widgetVar attribute (s. p:dataTable) should be the same as in the script - see jQuery(myTblWidget.jqId) in my case.

    ReplyDelete
  6. Hello Oleg, that's okay with you?

    I wonder what should I do when I have two datatable on the same page?

    Thank you and congratulations

    Jomello

    ReplyDelete
  7. Hello Oleg, do you have any idea on how to implement a global search in Primefaces? your example is a search by name. But, what if I want a search that filters all columns?

    ReplyDelete
  8. I think PrimeFaces has already this feature. You can see in docu (PDF) how to filter all columns via client side API.

    ReplyDelete
  9. Is it possible to use your workaround with Primefaces 3.0.M4

    ReplyDelete
  10. I have override the setupFiltering mode and put it after the p:datatable, that works for me:

    PrimeFaces.widget.DataTable.prototype.setupFiltering=
    function(){
    var a=this;
    $(this.jqId+" thead:first th.ui-filter-column .ui-dt-c .ui-column-filter").each(
    function(b){
    var c=$(this);
    if(c.is("input:text")){
    c.keyup(function(d){
    var e = (window.event) ? window.event : d;
    if(e.keyCode == 13) {
    a.filter(d)
    }
    })
    } else{
    c.change(function(d){a.filter(d)})
    }
    }
    )
    };

    ReplyDelete
  11. Hi Lorenz,

    My workaround doesn't work with Primefaces 3.0.M4. Thanks for the sharing! We will probably provide this hack as attachable ClientBehavior in the PrimeFaces extensions project http://code.google.com/p/primefaces-extensions/

    ReplyDelete
  12. Working great on 3.0.RC1, Thanks Lorenz.

    ReplyDelete
  13. Ok, now you can use the table attribute <p:dataTable filterEvent="enter" ...

    ReplyDelete
  14. Hi Oleg

    this method not working PF 3.5

    IDEA Console show this error :

    "WARNING: DataTable dataTable has filtering enabled but no filteredValue model reference is defined, for backward compatibility falling back to page viewstate method to keep filteredValue. It is highly suggested to use filtering with a filteredValue model reference as viewstate method is deprecated and will be removed in future."

    what can I do?
    thank you....

    ReplyDelete
  15. Hey Are you there? Please help me. I converted My Primefaces app 2.2 to 3.5 and this code not working.

    Now, I m using PF 3.5 and Firebug console always show jquery error.

    Please help me

    ReplyDelete
  16. Hi Oleg,
    In my primefaces datatable filter is not working properly, since i am adding dynamic rows to the datatable.
    Is there any solution to overcome the problem.

    ReplyDelete
  17. The best!
    http://www.coderanch.com/t/582700/JSF/java/Primefaces-datatable-filter-event

    ReplyDelete

Note: Only a member of this blog may post a comment.