如何在更改第一个selectOneMenu时加载第二个selectOneMenu?

时间:2012-02-07 04:33:43

标签: jsf

我有2个<h:selectOneMenu>个组件,其中一个组件取决于另一个组件的选择。当您选择第一个菜单组件的一个值时,第二个菜单组件会更改第一个菜单的onchange="submit()"valueChangeListener="#{Usuario.cmbDatos_action}"事件:

<h:selectOneMenu id="cmbCombo" binding="#{Usuario.cmbDatos}" value="#{Usuario.id}" 
    onchange="submit()" valueChangeListener="#{Usuario.cmbDatos_action}">
    <f:selectItems value="#{beanCombos.datos}"></f:selectItems>
</h:selectOneMenu>

就像所选国家的国家和城市一样。第一个菜单加载如下:

@ManagedBean
@RequestScoped
public class BeanCombos {

    private List<SelectItem> Datos;

    public BeanCombos() {
        try {
            clsConexion objConexion = new clsConexion();
            String strSQL = "SELECT * FROM Usuarios";            
            objConexion.ResultSetSQL = objConexion.EjecutarConsulta(strSQL);
            Datos = new ArrayList<SelectItem>();

            while (objConexion.ResultSetSQL.next()) {
                Usuario objUsuario = new Usuario();                
                objUsuario.setId(String.valueOf(objConexion.ResultSetSQL.getInt("Codigo")));
                objUsuario.setNombre(objConexion.ResultSetSQL.getString("Nombres").toUpperCase());
                Datos.add(new SelectItem(objUsuario.getId(), objUsuario.getNombre()));
            }
        } catch(Exception ex) {
            String strError = ex.getMessage().toString();            
        }
    }

    public List<SelectItem> getDatos() {
        return Datos;
    }
}

但是当我选择第一个菜单的一个值时,我不知道如何加载下一个菜单。我尝试过如下:

public String cmbDatos_action() {
    try {
        int intValor = Integer.parseInt(cmbDatos.getValue().toString());
    } catch(Exception ex) {

    }

    return null;
}

我可以在方法cmbDatos_action()的哪个部分加载代码来加载第二个菜单?

1 个答案:

答案 0 :(得分:10)

valueChangeListener应该引用一个采用ValueChangeEvent参数并返回void的方法。

public void cmbDatos_action(ValueChangeEvent event) {
    // ...
}

但是您在验证方面会遇到麻烦,因为您基本上是使用onchange="submit()"提交整个表单。您还需要将immediate="true"添加到第一个菜单组件中。另请参阅this article以获取具体示例的详细说明。

由于您似乎已经在使用JSF 2.x,我建议忘记这个基于JSF 1.x的解决方法,并直接使用JSF 2.x <f:ajax>方法,这对于编程来说简单得多。

这是一个基于&#34;国家&#34;的启动示例。和&#34;城市&#34;例如:

<h:selectOneMenu value="#{bean.country}" converter="countryConverter">
    <f:selectItems value="#{bean.countries}" var="country" itemValue="#{country}" itemLabel="#{country.name}" />
    <f:ajax listener="#{bean.changeCountry}" render="cities" />
</h:selectOneMenu>
<h:selectOneMenu id="cities" value="#{bean.city}" converter="cityConverter">
    <f:selectItems value="#{bean.cities}" var="city" itemValue="#{city}" itemLabel="#{city.name}" />
</h:selectOneMenu>

例如

@ManagedBean
@ViewScoped
public class Bean {

    private List<Country> countries;
    private Country country;
    private List<City> cities;
    private City city;

    @EJB
    private DataService service;

    @PostConstruct
    public void init() {
        countries = service.getCountries();
    }

    public void changeCountry() {
        cities = service.getCities(country);
    }

    // ...
}