【问题标题】:How to update a selectonemenu depending on other one selected value?如何根据其他一个选定值更新选择菜单?
【发布时间】:2012-10-31 14:09:59
【问题描述】:

我在尝试制作我的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

【问题讨论】:

    标签: java jsf primefaces selectonemenu dynamic-content


    【解决方案1】:

    我正在使用 Primefaces,这非常简单。我有 2 个 seleceOneMenus,一个用于主题(父级),另一个用于主题(子级)。

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

    请注意,当主题 selectonemenu 更改时,主题菜单会根据主题 ID 更改。我通过编辑 hibernate getList() 函数,在 Topics Managed Bean(子 selectonemenu 的托管 bean)中创建了一个简单的函数,如下所示:

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

    事情就像一个魅力...... :)

    【讨论】:

      【解决方案2】:
      1. &lt;p:selectOneMenu id="Municipio" value="municipio"&gt; 中的value="municipio" 意味着该下拉列表中的值将永远不会改变,因为您已经有效地将该字段上的值硬编码为始终为municipio(即使这样也会导致转换失败)。 value 属性应绑定到支持 bean 变量,如

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

        在你的支持 bean 中,有

           Municipio municipio;
          //getter and setter
        
      2. &lt;p:ajax update="Municipio" listener="#{beanInscripcion.buscarMunicipios(event)}" /&gt; 中删除参数event。应该是

        <p:ajax update="Municipio"  listener="#{beanInscripcion.buscarMunicipios}" />
        
      3. 删除valueChangeListener="#{beanInscripcion.buscarMunicipios(event)}"。这是不必要的,因为您已经定义了 &lt;p:ajax/&gt; 事件

      4. 您最终会在提交该表单时遇到问题,因为您还没有为 Municipio 自定义类型创建 JSF 转换器。如果您在选择的组件中使用 String 类型以外的任何类型,则这是强制性的。查看转换器/转换的简短介绍here

      【讨论】:

        【解决方案3】:

        我知道 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>
        

        对于豆子:

        @ManagedBean(name = "beanInscripcion") @RequestScoped 公共类 BeanInscripcion 实现 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
        • 渲染的 PrimeFaces 等价物是更新,执行的等价物是进程。实际上 RichFaces 遵循更多的 JSF 标准,即 f:ajax。
        • 请为您的 OP 解决方案添加更多解释。你刚刚给了他一个链接
        【解决方案4】:

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

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

        【讨论】:

        • 我正在尝试使用我自己的代码修改来尝试您的示例,但我不太确定要使用哪个范围,您会推荐我哪一个?
        • 大声笑,我遇到了一个新问题,我坚持你的例子并试图实现我的但由于某种原因第二个 消失而不是显示新内容
        猜你喜欢
        • 2013-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多