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
I am using Primefaces and this is pretty simple. I have 2 seleceOneMenus, one for subjects (the parent one) and another one for Topics (the child one.).
<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>
Just notice, that when subject selectonemenu changes, then the topics menu change according to subject ID. I had create a simple function inside Topics Managed Bean (the managed bean for the child selectonemenu ) by editing the hibernate getList() function like as under:
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;
}
and things worked like a charm.... :)
It is just example. Try to reference for your program.
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"};
}
}
I know a solution for RichFaces, I'm pretty sure it will works for PrimeFaces as components are almost the same :
http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=ajax&sample=selectsUpdates&skin=blueSky
EDIT : Here is the translation applied to your code :
<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>
And for the 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;
}
}
Hope it will work since it is not tested!