Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

valueChangeListener and ajax execution order problem on selectOneMenu

Tags:

jsf

jsf-2

I'm currently experiencing a strange phenomena, where setting the value to the model happens before executing valueChangeListener.

Basically what i would like to happen is :

  1. I change the select menu
  2. The new value get submitted using Ajax to update the myBean (using f:ajax)
  3. Execute a query based on the newly submitted value (using valueChangeListener)
  4. Render the table based on the result from the last query

But what happens when i run it is in this order, 1 - 3 - 2 - 4 (not 1 - 2 - 3 - 4 as i imagined)

Here's the part of the UI :

<h:selectOneMenu label="budget" id="budget"
    converter="genericConverter"
    value="#{myBean.budget}" 
    valueChangeListener="#{myBean.actionSearch}">

    <f:ajax render="myGrid" />
    <f:selectItem itemLabel="Choose one .." noSelectionOption="true" />

    <f:selectItems ... />
</h:selectOneMenu>

And this is the excerpt from the bean :

public void actionSearch() {
    System.out.println("searching with this.budget == " + this.budget);
    ...
}
public void setBudget(String budget) {
    System.out.println("setting budget : " + budget);
    this.budget = budget;
}

And this is the output :

searching with this.budget == xxxx
setting budget : yyyy

What i would like is, setting the budget first from the new value selected in the UI, and then start searching based on the new UI. But i dont know how to achieve that.

And im using Tomcat 7 along with these :

<dependency>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.0.4-b09</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.0.4-b09</version>
    <scope>compile</scope>
</dependency>

I wonder what i did wrong ?

Thank you !

like image 887
Albert Gan Avatar asked Apr 18 '11 03:04

Albert Gan


1 Answers

The valueChangeListener is executed during Validations phase, before the Update Model Values phase. It is intented to be able to get a handle of both the old and new value so that you can if necessary do some business stuff (logging?) based on the real change. In JSF 1.x this was however more than often (ab)used to invoke actions on a dropdown change only, but it has to be used in combination with onchange="submit()", immediate="true", FacesContext#renderResponse() and other stuffs. The selected value is to be obtained by ValueChangeEvent#getNewValue() (the ValueChangeEvent is supposed to be definied as method's argument).

For JSF 2.x you don't need the valueChangeListener anymore in such case. You're also not interested in the old value anyway. Use the listener attribute of <f:ajax> instead.

<f:ajax listener="#{bean.actionSearch}" />

This will be executed during Invoke Action phase, after Update Model Values phase.

like image 138
BalusC Avatar answered Sep 29 '22 09:09

BalusC