Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

valueChangeListener method is called on selectOneMenu even though I have not changed the value

Tags:

jsf

jsf-2

I have the following problem. When I click the button "Enviar", this calls another method that is associated to a selectOneMenu (in the attribute valueChangeListener called "validarSelect"), and later, calls the method that this button has associated in the attribute actionListener called "validarBoton". I wonder, why this happens. I expect the valueChangeListener to be not called since I have not changed the dropdown.

This is my page JSF:

<?xml version='1.0' encoding='windows-1252'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
    <h:head></h:head>
    <h:body>
        <h:form>
            <h:commandButton value="Enviar..." id="validar" actionListener="#{Domiciliacion.validarBoton}"/>
            <h:selectOneMenu valueChangeListener="#{Domiciliacion.validarSelect}"
                             binding="#{Domiciliacion.selectCombo}">
                <f:selectItems value="#{Domiciliacion.lista}"/>
                <f:ajax event="valueChange" render="@this"/>
            </h:selectOneMenu>
        </h:form>
    </h:body>
</html>

And this, is the ManagedBean:

package domiciliaciontest;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;

@ManagedBean(name = "Domiciliacion")
@ViewScoped

public class MB0001 {


private HtmlSelectOneMenu selectCombo;
private List<String> lista = new ArrayList<String>();

public MB0001() {
    super();
    System.out.println("Entro al constructor...");
    lista.add("Caracas");
    lista.add("Bogota");
    lista.add("Santiago");
}


public void validarBoton(ActionEvent actionEvent) {
    System.out.println("Entro a validarBoton...");
    // Add event code here...
}

public void validarSelect(ValueChangeEvent valueChangeEvent) {
    // Add event code here...
    System.out.println("Entro a validarSelect...");
}

public void setSelectCombo(HtmlSelectOneMenu selectCombo) {
    this.selectCombo = selectCombo;
}

public HtmlSelectOneMenu getSelectCombo() {
    return selectCombo;
}

public void setLista(List<String> lista) {
    this.lista = lista;
}

public List<String> getLista() {
    return lista;
}
}

this is the output when I click the button "Enviar":

  • Entro a validarSelect...
  • Entro a validarBoton...
like image 814
Carlos Avatar asked Apr 16 '12 21:04

Carlos


1 Answers

The valueChangeListener method will be invoked when the submitted value is different from the initial value, regardless of whether you have changed it yourself or not. So, if the currently submitted value (which is "Caracas" in your case) is different from the initial value (which is null in your case), then the valueChangeListener method will be invoked.

See also:

  • When to use valueChangeListener or f:ajax listener?
  • Best way to add a "nothing selected" option to a selectOneMenu in JSF

Unrelated to the concrete problem, seeing this in combination with binding attribute gives me the impression that you're trying to achieve something which you've read in an article or answer targeted on JSF 1.x. This is namely recognizeable as part of a hack to populate child dropdowns in JSF 1.x. You do not need this approach for JSF 2.x. Further, your method names with "validar" ("validate") are misleading. Don't you actually need a fullworthy Validator? But as said, that's a different problem.

See also:

  • Make multiple dependent / cascading selectOneMenu dropdown lists in JSF
like image 74
BalusC Avatar answered Sep 28 '22 05:09

BalusC