Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Valuechangelistener Doubt in JSF

Tags:

jsf

HI,

Please see the following code:

                <h:selectOneMenu id="countries" value="#{countryBean.selectedCountry}" onchange="submit()
                                    valueChangeListener="#{countryBean.changeCountry}">
                    <f:selectItems value="#{countryBean.countries }" />
                </h:selectOneMenu>  

Backing Bean

public void changeCountry(ValueChangeEvent event){      
    String newValue = (String)event.getNewValue();
    String oldValue = (String)event.getOldValue();

    System.out.println("New Value : " + newValue);
    System.out.println("Old Value : " + oldValue);

    if ("1".equals(newValue)){
        this.countries = new ArrayList<SelectItem>();
        this.cities.add(new SelectItem("1","Delhi"));
        this.cities.add(new SelectItem("2","Mumbai"));
    }
    if ("2".equals(newValue)){
        this.cities = new ArrayList<SelectItem>();
        this.cities.add(new SelectItem("1","Mossco"));
    }       
}

Please let me know if the implementation is correct. It is working fine. My questions are:

  • What is the advantage of adding the f:valueChangeListener tag inside the h:selectOneMenu tag. I have used the normal attribute valueChangeListener="#{countryBean.changeCountry}".
  • Is it necessary to use onchange="submit() this code to change the values.
  • What is difference between writing the custom listeners by implementing the ActionListener interface and just using the attribute in the UIComponent tags (action="methodName"). Please explain me.
like image 946
Krishna Avatar asked Jan 26 '11 05:01

Krishna


1 Answers

The ValueChangeListener will only be called when the form is submitted, not when the value of the input is changed. Thus, if you want to run this listener when the value is modified, you have two solutions:

  1. Submit your form when the onchange event is fired (this is what you did in your code);
  2. Use an Ajax call instead, by using some dedicated components (already integrated in JSF2, with <f:ajax>, or third-parties libraries such as Richfaces, Primefaces...).

Here is an example with Richfaces:

<h:selectOneMenu id="countries" value="#{countryBean.selectedCountry}" valueChangeListener="#{countryBean.changeCountry}">
    <a4j:support event="onchange" .../>
    <f:selectItems value="#{countryBean.countries }" />
</h:selectOneMenu>

Regarding the code of your listener, it seems correct, but why question is why do you need a ValueChangeListener here? Indeed, this listener is usefull when you want to track a modification of a value. That's why the ValueChangeEvent provides both getOldValue() and getNewValue() methods.

In your code, you do not care about the old value, so basically, you could "simply" do an action instead of a valueChangeListener (ex. with Richfaces):

<h:selectOneMenu id="countries" value="#{countryBean.selectedCountry}">
    <a4j:support event="onchange" actionListener="#{countryBean.changeCountry}"/>
    <f:selectItems value="#{countryBean.countries }" />
</h:selectOneMenu>

Finally, regarding the difference between the valueChangeListener attribute and <f:valueChangeListener> is that the first binds a Java method (#{myBean.myMethod}), while the second binds a Java class (type="com.foo.MyListenerClass") which implements the ValueChangeListener interface. So the second one could be more generic than the first one...

like image 180
Romain Linsolas Avatar answered Oct 05 '22 22:10

Romain Linsolas