How to update a selectonemenu depending on other one selected value?

AlexLezama picture AlexLezama · Nov 12, 2012 · Viewed 25.7k times · Source

I've been having a trouble trying to make my selectOneMenu content, depend on the value selected on the other. The content from the first one comes from a table in my DataBase and works perfectly, but the second one is supposed to come from another table, but I can't make it work. Here is my index.html, where I'm just trying to prove how this works:


        <h:outputLabel value="Estado" styleClass="requiredLbl"/>
        <p:selectOneMenu id="Estado" value="#{beanInscripcion.id_estado}" valueChangeListener="#{beanInscripcion.buscarMunicipios(event)}" >  
            <f:selectItem itemLabel="Elegir Estado" itemValue="" />
            <f:selectItems value="#{beanInscripcion.estados}"  
                           var="edo" itemLabel="#{edo.nombre_estado}" itemValue="#{edo.id_estado}" />  
            <p:ajax update="Municipio"  listener="#{beanInscripcion.buscarMunicipios(event)}" />
        </p:selectOneMenu> 
        <p:separator /> 
        <h:outputLabel value="Municipio" styleClass="requiredLbl"/>
        <p:selectOneMenu id="Municipio" value="municipio">  
            <f:selectItems value="#{beanInscripcion.municipios}"  
                           var="mun" itemLabel="#{mun.nombre_municipio}" itemValue="#{mun.nombre_municipio}" />  
        </p:selectOneMenu>

And here is the section of my Bean where I'm supposed to get the content for the second menu:


@ManagedBean(name = "beanInscripcion")
@ViewScoped
public class BeanInscripcion implements Serializable {

    static String strURL;
    private List<Estado> estados; 
    private List<Municipio> municipios;
    private int id_estado;
    public BeanInscripcion() throws SQLException{
            estados = new ArrayList<Estado>();
            buscarEstados();
    }

    public void buscarEstados() throws SQLException {
        Connection connection = getConnection();
        Statement statement = connection.createStatement();
        ResultSet result = statement.executeQuery("SELECT * FROM estado");
        result.beforeFirst();
        while (result.next()) {
            Estado estado = new Estado();
            estado.setId_estado(result.getInt("id_estado"));
            estado.setNombre_estado(result.getString("nombre_estado"));
            estados.add(estado);
        }
    }

    public void buscarMunicipios() throws SQLException {
        Connection connection = getConnection();
        Statement statement = connection.createStatement();
        ResultSet result = statement.executeQuery("SELECT id_municipio, nombre_municipio FROM municipio WHERE Estado_id_estado = '" + id_estado + "'");
        result.beforeFirst();
        while (result.next()) {
            Municipio municipio = new Municipio();
            municipio.setId_municipio(result.getInt("id_municipio"));
            municipio.setNombre_municipio(result.getString("nombre_municipio"));
            municipios.add(municipio);
        }
    }

    public Connection getConnection() {
        try {
            strURL = "jdbc:mysql://localhost:3306/mydb";
            Class.forName("com.mysql.jdbc.Driver");
            return DriverManager.getConnection(strURL, "root", "root");
        } catch (SQLException ex) {
            return null;
        } catch (ClassNotFoundException ex) {
            return null;
        }
    }

    public List<Estado> getEstados() {
        return estados;
    }

    public void setEstados(List<Estado> estados) {
        this.estados = estados;
    }

    public List<Municipio> getMunicipios() {
        return municipios;
    }

    public void setMunicipios(List<Municipio> municipios) {
        this.municipios = municipios;
    }

    public int getId_estado() {
        return id_estado;
    }

    public void setId_estado(int id_estado) {
        this.id_estado = id_estado;
    }
}

I've been working on this for hours and still nothing, I'm really in a hurry here, so I'd appreciate if you give me some help here. Thx a lot for your attention :D

Answer

kolossus picture kolossus · Nov 12, 2012
  1. value="municipio" in <p:selectOneMenu id="Municipio" value="municipio"> means that the value in that dropdown will never change as you've effectively hardcoded the value on that field to always be municipio (and even that will fail conversion). The value attribute should be bound to a backing bean variable as in

      <p:selectOneMenu id="Municipio" value="#{beanInscripcion.municipio}" >  
        <f:selectItems value="#{beanInscripcion.municipios}"  
                       var="mun" itemLabel="#{mun.nombre_municipio}" itemValue="#{mun.nombre_municipio}" />  
    </p:selectOneMenu>
    

    and in your backing bean, have

       Municipio municipio;
      //getter and setter
    
  2. Remove the parameter event from <p:ajax update="Municipio" listener="#{beanInscripcion.buscarMunicipios(event)}" />. It should be

    <p:ajax update="Municipio"  listener="#{beanInscripcion.buscarMunicipios}" />
    
  3. Remove valueChangeListener="#{beanInscripcion.buscarMunicipios(event)}". It's unnecessary because you already have a <p:ajax/> event defined

  4. You will eventually run into problems submitting that form because you haven't created a JSF Converter for that Municipio custom type. It's mandatory if you're using anything other than String types in your select components. See a short intro to converters/converting here