I can't see the point of your requirement of reseting the country list when selecting an state. The proper behaviour here is, in my opinion, allowing the end user to choose an State inside each country. That's done by loading the related states for each country and rendering the dependent h/p:selectOneMenu
.
I don't encourage you to use two different beans for that, just go with @ViewScoped
. Also accessing transient JSF managed beans from the view the way you do (#{infoBean.infoDataHolder}
) does not make sense in JSF, just access to a bean directly.
Here you've got my workaround:
@ManagedBean
@ViewScoped
public class InfoDataHolder {
private List<String> availableCountries = Arrays.asList("USA",
"Switzerland");
private List<String> availableStates = new ArrayList<String>();
private String selectedCountry;
private String selectedState;
public void countrySelected() {
if ("USA".equals(selectedCountry)) {
availableStates = Arrays.asList("Arizona", "California");
} else if ("Switzerland".equals(selectedCountry)) {
availableStates = Arrays.asList("Zurich", "Bern");
} else {
availableStates = new ArrayList<String>();
}
}
public List<String> getAvailableCountries() {
return availableCountries;
}
public List<String> getAvailableStates() {
return availableStates;
}
public String getSelectedCountry() {
return selectedCountry;
}
public String getSelectedState() {
return selectedState;
}
public void setSelectedCountry(String selectedCountry) {
this.selectedCountry = selectedCountry;
}
public void setSelectedState(String selectedState) {
this.selectedState = selectedState;
}
}
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head />
<h:body>
<h:form>
<h:selectOneMenu value="#{infoDataHolder.selectedCountry}">
<f:selectItem noSelectionOption="true" itemLabel="Choose a Country" />
<f:selectItems var="country"
value="#{infoDataHolder.availableCountries}" itemValue="#{country}" />
<f:ajax listener="#{infoDataHolder.countrySelected}"
render="state_selection" />
</h:selectOneMenu>
<h:selectOneMenu value="#{infoDataHolder.selectedState}"
id="state_selection">
<f:selectItem noSelectionOption="true" itemLabel="Choose an State" />
<f:selectItems value="#{infoDataHolder.availableStates}" var="state"
itemValue="#{state}" />
</h:selectOneMenu>
</h:form>
</h:body>
</html>
See also: