如何根据另一个选择菜单的选定值更新选择菜单?

6

我一直在尝试让我的selectOneMenu内容根据另一个选择的值而改变。第一个的内容来自我的数据库中的一个表格,它工作得很好,但是第二个应该来自另一个表格,但我无法使它工作。这是我的index.html,我只是想证明这是如何工作的:


        <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>

这是我Bean的一个部分,我需要获取第二个菜单的内容:


@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;
    }
}

我已经花了几个小时在这上面,但还是没有任何进展。我现在真的很着急,希望您能给我一些帮助。非常感谢您的关注 :D

4个回答

6
  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


6

我正在使用Primefaces,这很简单。我有两个selectOneMenus,一个是主题(父级),另一个是话题(子级)。

<h:selectOneMenu id="subject" value="#{QuestionsMB.selectedSubjectId}" var="selectedSubject">  
                <f:selectItem itemLabel="Select Subject" noSelectionOption="true" />
                <f:selectItems value="#{SubjectsMB.subjectsList}" var="selectedSubject" itemValue="#{selectedSubject.id}" itemLabel="#{selectedSubject.subjectName}" />
                <p:ajax update="topic" />
            </h:selectOneMenu>


            <h:selectOneMenu id="topic" value="#{QuestionsMB.selectedTopicId}" var="selectedTopic">  
                <f:selectItem itemLabel="Select Topic" noSelectionOption="true" />
                <f:selectItems value="#{TopicsMB.getTopicsListBySubjectId(QuestionsMB.selectedSubjectId)}" var="selectedTopic" itemValue="#{selectedTopic.id}" itemLabel="#{selectedTopic.topicName}" />
            </h:selectOneMenu>

请注意,当主题选择菜单发生变化时,主题菜单会根据主题ID进行更改。我已经在主题管理bean中创建了一个简单的函数(子选择菜单的管理bean),通过编辑hibernate getList()函数来实现:

public List<Topics> getTopicsListBySubjectId(String subjectID) 
    {
        Topics topic = new Topics();
        List<Topics> TopicsList = new ArrayList<Topics>();

        if(subjectID.length() != 0)
        {
            topic.setSubjectId(Integer.parseInt(subjectID));
            TopicsList = getTopicsService().getTopicsBySubjectId(topic);
        }
        else
        {   
            TopicsList.addAll(getTopicsService().getTopics());
        }
        return TopicsList;
    }

并且事情进展得非常顺利.... :)

0

我知道一种适用于RichFaces的解决方案,我非常确信它对PrimeFaces也同样适用,因为这两个组件几乎相同:

http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=ajax&sample=selectsUpdates&skin=blueSky

编辑:以下是应用于您的代码的翻译:

<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="second" process="@this" listener="#{beanInscripcion.buscarMunicipios(event)}" />
</p:selectOneMenu>
<p:separator />
<p:outputPanel id="second">
    <h:outputLabel rendered="#{not empty beanInscripcion.id_estado}" value="Municipio" styleClass="requiredLbl"/>
    <p:selectOneMenu rendered="#{not empty beanInscripcion.id_estado}" id="Municipio" value="municipio">  
        <f:selectItems value="#{beanInscripcion.municipios}" var="mun" itemLabel="#{mun.nombre_municipio}" itemValue="#{mun.nombre_municipio}" />  
    </p:selectOneMenu>
</p:outputPanel>

关于这个Bean:

@ManagedBean(name = "beanInscripcion") @RequestScoped 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;
}

}

希望它能正常工作,因为它还没有经过测试!


好的,我刚试了一下,但是不起作用,因为我的primefaces元素中没有相同的属性,我的<p:ajax>标签没有“render”属性或“execute”属性,所以我不能使用这个,但我真的很感激你的帮助,总比没有好:P - AlexLezama
PrimeFaces中的等效渲染是update,执行的等效是process。实际上,RichFaces遵循更多的JSF标准,即f:ajax。 - Alexandre Lavoie
请为原帖补充更多解释,不要只给他一个链接。 - kolossus

0

这只是一个例子。尝试参考您的程序。

example.xhtml

        <p:selectOneMenu value="#{SelectOneMenuBean.selectedValue}" 
                         style="width:195px;" required="true" id="countryMenu">
            <p:ajax update="cityMenu"/>
            <f:selectItems value="#{SelectOneMenuBean.countries}"/>
        </p:selectOneMenu>
        <p:selectOneMenu style="width:195px;" required="true" id="cityMenu">
            <f:selectItems value="#{SelectOneMenuBean.cities}"/>
        </p:selectOneMenu>

SelectOneMenuBean.java

@ManagedBean(name="SelectOneMenuBean")
public class SelectOneMenuBean {
    private String selectedValue;

    public String getSelectedValue() {
        return selectedValue;
    }

    public void setSelectedValue(String selectedValue) {
        this.selectedValue = selectedValue;
    }

    public String[] getCountries() {
        return new String[] {"AAA", "BBB", "CCC", "DDD"};
    }

    public String[] getCities() {
        if(selectedValue != null && selectedValue.equals("AAA")) {
            return new String[] {"City_1 of AAA", "City_2 of AAA", "City_3 of AAA"};
        } else if(selectedValue != null && selectedValue.equals("BBB")) {
            return new String[] {"City_1 of BBB", "City_2 of BBB", "City_3 of BBB"};
        } else if(selectedValue != null && selectedValue.equals("CCC")) {
            return new String[] {"City_1 of CCC", "City_2 of CCC", "City_3 of CCC"};
        } else if(selectedValue != null && selectedValue.equals("CCC")) {
            return new String[] {"City_1 of CCC", "City_2 of CCC", "City_3 of CCC"};
        } 
        return new String[] {"No City"};
    }
}

我正在尝试使用您的示例进行自己的代码修改,但我不太确定应该使用哪个范围,您会推荐我使用哪个? - AlexLezama
哈哈,我遇到了一个新问题,我按你的例子尝试实现到我的项目中,但是由于某些原因第二个<selectOneMenu>消失了,而没有显示新内容。 - AlexLezama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接