6

I am using PrimeFaces and have a p:inputText field where I need to update some components on the view based on the latest keystroke inside that p:inputText. Here's the code:

<p:inputText value="#{customerLController.surnameFilterConstraint}"
             id="surnamefilterfield">
    <p:ajax event="keyup" 
            update=":custForm:custDataTable"
            listener="#{customerLController.focusSurname}"
            oncomplete="primeFacesId('surnamefilterfield')"/>
</p:inputText>

The thing is, the above code fires up Ajax even in the case of arrow keystrokes (which I would rather avoid given the costly update). Ideally I would like a different version of p:ajax event="change" with the qualification that change is pronounced on keystrokes and not when the user hits Enter (which is what happens now).

If the p:ajax component doesn't allow a way to filter out certain keyup events, then I gather that the only (?) alternative would be to call JavaScript on the client side and then implement the Ajax call in Javascript but then I would forsake the convenience of using the PrimeFaces p:ajax component, wouldn't I?

Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331
  • im not familiar with PrimeFaces, but if you can subscribe to the `keypress` instead of `keyup` event, it should fix this problem. key press will only fire for keys that map directly to a printable character. – jbabey Jul 27 '12 at 12:52
  • no, that doesn't do the trick, at least not in Firefox and Konkeror that I tried. – Marcus Junius Brutus Jul 29 '12 at 17:18
  • 2
    There is an answer right here at SO: http://stackoverflow.com/questions/8401218/primefaces-keyup-event-delay – Dominik Sandjaja Mar 01 '13 at 10:20

1 Answers1

2

Since JSF 2.2, I am using elegant way to solve this issue.

Solution is based on combination of p:remoteCommand (as pointed out in one of comments) and namespace http://xmlns.jcp.org/jsf/passthrough which allows you to define native HTML event attributes in JSF components.

In this case it would be:

  1. First add new namespace to your page

    xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
    
  2. Modify p:inputText and add p:remoteCommand

    <p:inputText id="surnamefilterfield" 
              value="#{customerLController.surnameFilterConstraint}" 
              pt:onkeyup="onKeyUpFilterKeyCode(event)"/>
    <p:remoteCommand delay="300" name="onFilteredKeyUp" 
                  actionListener="#{customerLController.focusSurname}" /> 
    
  3. add JavaScript function

       function onKeyUpFilterKeyCode(event){
            var keyCode=event.keyCode;
            console.log("Key code = " + keyCode);
            //if key is not ENTER and not cursor/arrow keys
            if ((keyCode != 13) && !((keyCode >= 37) && keyCode <= 40)){
                //call remoteCommand
                onFilteredKeyUp();
            }
        }
    

(since this JS function contains "special" XML chars follow BalusC recommendations about how to add it to JSF/XML web page)

The advantage of this approach is that you can ajaxify any native HTML event supported by component (and WEB browser) while still using JSF/Primefaces components and "JSF way" of creating WEB pages.

Dusan Kovacevic
  • 1,377
  • 1
  • 13
  • 19