Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 665
Danubian Sailor Avatar asked Feb 07 '13 11:02

Danubian Sailor


3 Answers

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...

Use a valueChangeListener.


Unfortunatelly, valueChangeListener is invoked before p:ajax, so I don't have actual data from forms in that method, so in theory I could use valueChangeListener to remember the old value and then wait for p:ajax to process...

Queue the value change event to the invoke application phase.

public void valueChangeListenerMethod(ValueChangeEvent event) {
    if (event.getPhaseId() != PhaseId.INVOKE_APPLICATION) {
        event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        event.queue();
        return;
    }

    // Do your original job here. 
    // It will only be invoked when current phase ID is INVOKE_APPLICATION.
}
like image 50
BalusC Avatar answered Nov 06 '22 12:11

BalusC


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

like image 35
Matt Handy Avatar answered Nov 06 '22 11:11

Matt Handy


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.

like image 26
kolossus Avatar answered Nov 06 '22 11:11

kolossus