Ajax for valueChangeListener

22,922

Solution 1

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

Solution 2

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 3

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.

Share:
22,922
Danubian Sailor
Author by

Danubian Sailor

I prefer to be anonymouse.

Updated on January 25, 2022

Comments

  • Danubian Sailor
    Danubian Sailor almost 2 years

    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?

  • Danubian Sailor
    Danubian Sailor almost 11 years
    No, submit can't be done (because of validation) and the changes must be visible to other components after changing the field, so it's not a solution)
  • Matt Handy
    Matt Handy almost 11 years
    @lechlukasz: You can do a partial submit as stated in the "EDIT"-part of kolossus answer. Then the valueChangeListener will be invoked and you can access the old and the new value. All other form elements will not be evaluated/processed (unless you put it in the execute attribute of the ajax call.)
  • Danubian Sailor
    Danubian Sailor almost 11 years
    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...
  • Danubian Sailor
    Danubian Sailor almost 11 years
    do you know how to made also the bean changes visible to the server code? with p:ajax I have the process option, to send the UI control's content, with that way they are in state from last submit...
  • Matt Handy
    Matt Handy almost 11 years
    @lechlukasz: Take a look at BalusC's answer.
  • Daniel
    Daniel about 10 years
    +1, Someone should do "BalusC IS AWESOME" video (just like "PEOPLE ARE AWESOME" videos)
  • xwinus
    xwinus about 9 years
    Bauke you're amazing guy :D You just saved me hours of head scratching.
  • BalusC
    BalusC almost 9 years
    OP is interested in "old value" as it was before update model values phase has taken place. The ajax listener, however, runs after update model values phase. See the currently accepted answer for the proper approach.
  • Herick
    Herick over 8 years
    As usual BalusC has solved my problem for me years before I had it.
  • gannu_lee
    gannu_lee almost 5 years
    @BalusC, thank you for this answer, 'JSF is religion-BalusC is god.'