'Ajax for valueChangeListener

I'm using the p:ajax listener to handle value change events (because valueChangeListener is launched on form submit):

<p:ajax event="change" listener="#{bean.onNameChanged}"/>

Handle method:

public void onNameChanged(final AjaxBehaviorEvent event)

The problem is, I can't find in AjaxBehaviorEvent nor its class hierarchy the place to read the old value of the input. Neither could I find hint in google, how to get the old value...

How to access the old value in the p:ajax onChange event?



Solution 1:[1]

The ValueChangeListener should work this way:

The view:

<h:form>
  <h:inputText value="#{sessionBean.hello}" 
               valueChangeListener="#{sessionBean.valueChangeListener}">
    <p:ajax/>
  </h:inputText>
</h:form>

The bean:

public void valueChangeListener(ValueChangeEvent e) {
  System.out.println("valueChangeListener invoked:" 
                      + " OLD: " + e.getOldValue() 
                      + " NEW: " + e.getNewValue());
}

The above code will print if I change the text field from "hello" to "world":

valueChangeListener invoked: OLD: hello NEW: world

Solution 2:[2]

You could try the following:

  1. Implement the value change event in your bean

     public void processValueChange(ValueChangeEvent e){
     //foo the bar
     }
    
  2. Define a valueChangeListener on your selection component

     <p:selectOneMenu value="#{yourBean.value}" onchange="submit()" valueChangeListener="{#yourBean.processValueChange}">
    

    The key piece there is the submit() bit that processes the enclosing form on change of the value. You can then getNewValue() and getOldValue() as necessary.

EDIT: Now that I think about it, I see no reason why you cannot leave your setup as-is and simply define the valueChangeListener. It should still be processed during the change event in the <p:ajax/>, in fact, it will be processed before the listener for the ajax event itself.

Solution 3:[3]

you can use this:

public void onNameChanged(AjaxBehaviorEvent event)
 {
    String myVal = (String) ((UIOutput) event.getSource()).getValue();
    System.out.println("myVal: " + myVal);
 }

Solution 4:[4]

Workaround is possible (tested with Primefaces 10):

<p:inputText id="name" value="bean.name">
     <p:ajax event="valueChange" update="name"
             listener="#{bean.onNameChanged}"
             onstart="cfg.ext={params:[{name:'oldValue', value:'#{bean.name}'}]};"/>
</p:inputText>

update="name" is important, to get each time the new value into the javascript event handler.

Bean Method:

public void onNameChanged(final AjaxBehaviorEvent event) {
    String oldValue = getFacesContext().getExternalContext().getRequestParameterMap()
                      .get("oldValue");
    //Do with oldValue, whatever you want
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Matt Handy
Solution 2
Solution 3 Abed Kanbar
Solution 4 Gábor Lipták