在JSF中创build多个依赖/级联selectOneMenu下拉列表

我正在尝试制作4个依赖菜单。

当用户从第一个菜单中select一个项目时,第二个菜单将显示依赖数据,当用户从第二个菜单中select项目时,第三个菜单将显示依赖数据等等。

用户只能看到第一个菜单上的项目,而其他项目将是空白的。 如果他在第一个菜单上select一个项目,第二个将显示数据,但是第三个和第四个将保持空白,等等。 用户最终必须从所有4个菜单中select条目。

<h:selectOneMenu id="first" value="#{nodes.selectState"}> <f:selectItems value="#{nodes.stateList}"/> <f:ajax render="second"> </h:selectOneMenu> <h:selectOneMenu id="second" value="#{nodes.selectCity"}> <f:selectItems value="#{nodes.cityList}"/> <f:ajax render="third"> </h:selectOneMenu> <h:selectOneMenu id="third" value="#{nodes.selectRegion"}> <f:selectItems value="#{nodes.regionList}"/> <f:ajax render="fourth"> </h:selectOneMenu> <h:selectOneMenu id="fourth" value="#{nodes.selectStation"}> <f:selectItems value="#{nodes.stationList}"/> </h:selectOneMenu> 

节点Java类

 private String selectState; //+setters, getters private String selectCity; //+setters, getters private String selectRegion; //+setters, getters private String selectStation; //+setters, getters private List<SelectItem> stateList; //+setters, getters private List<SelectItem> cityList; //+setters, getters private List<SelectItem> regionList; //+setters, getters private List<SelectItem> stationList; //+setters, getters public getStateList(){ stateList= new ArrayList<SelectItem>(); stateList.add(new SelectItem("A")); } public getCityList(){ CityList= new ArrayList<SelectItem>(); if(selectState.equals("A")){ CityList.add(new SelectItem("B")); } } public getRegionList(){ RegionList= new ArrayList<SelectItem>(); if(selectCity.equals("B")){ RegionList.add(new SelectItem("C")); } } public getStationList(){ StationList= new ArrayList<SelectItem>(); if(selectRegion.equals("C")){ StationList.add(new SelectItem("D")); } } 

它只在前2个菜单中工作,而另外2个菜单则为空值

将bean放在视图范围内,并在getter方法中摆脱任何业务逻辑。

必须将bean放在视图范围内,以便logging所有以前的select和新的可用项目,否则,如果rendered属性取决于仅在先前请求中设置的条件,或者JSF需要validation所选内容项目与可用项目列表进行比较。

getter方法不应该包含任何业务逻辑,因为它们也将在aovalidation阶段被调用。 您应该使用<f:ajax listener>根据更改执行业务逻辑。 您应该在侦听器方法中也明确地清除所select的子选项的值。 您可以使用<f:ajax render>来更新子下拉列表的内容。

因此,所以:

 <h:selectOneMenu id="state" value="#{nodes.selectedState}"> <f:selectItem itemValue="#{null}" itemLabel="-- select --" /> <f:selectItems value="#{nodes.availableStates}" /> <f:ajax listener="#{nodes.changeState}" render="city region station" /> </h:selectOneMenu> <h:selectOneMenu id="city" value="#{nodes.selectedCity}"> <f:selectItem itemValue="#{null}" itemLabel="-- select --" /> <f:selectItems value="#{nodes.availableCities}" /> <f:ajax listener="#{nodes.changeCity}" render="region station" /> </h:selectOneMenu> <h:selectOneMenu id="region" value="#{nodes.selectedRegion}"> <f:selectItem itemValue="#{null}" itemLabel="-- select --" /> <f:selectItems value="#{nodes.availableRegions}" /> <f:ajax listener="#{nodes.changeRegion}" render="station" /> </h:selectOneMenu> <h:selectOneMenu id="station" value="#{nodes.selectedStation}"> <f:selectItem itemValue="#{null}" itemLabel="-- select --" /> <f:selectItems value="#{nodes.availableStations}" /> </h:selectOneMenu> 

 @ManagedBean @ViewScoped public class Nodes { private String selectedState; // getter+setter private String selectedCity; // getter+setter private String selectedRegion; // getter+setter private String selectedStation; // getter+setter private List<SelectItem> availableStates; // getter (no setter necessary!) private List<SelectItem> availableCities; // getter (no setter necessary!) private List<SelectItem> availableRegions; // getter (no setter necessary!) private List<SelectItem> availableStations; // getter (no setter necessary!) @EJB private SomeService someService; @PostConstruct public void init() { availableStates = someService.listStates(); } public void changeState(AjaxBehaviorEvent event) { availableCities = someService.listCities(selectedState); selectedCity = selectedRegion = selectedStation = null; availableRegions = availableStations = null; } public void changeCity(AjaxBehaviorEvent event) { availableRegions = someService.listRegions(selectedCity); selectedRegion = selectedStation = null; availableStations = null; } public void changeRegion(AjaxBehaviorEvent event) { availableStations = someService.listStations(selectedRegion); selectedStation = null; } // Generate necessary getters+setters here. You should not change them. } 

也可以看看:

  • 如何select合适的bean范围?
  • 向JSF中的selectOneMenu添加“nothing selected”选项的最佳方法
  • 如何从数据库中填充h:selectOneMenu的选项?
  • 何时使用valueChangeListener或f:ajax监听器?
  • 为什么JSF多次调用getters

您的代码中存在拼写错误。 对于第三个菜单,您已将id名称设为“first”而不是“third”。 可能是因为这个问题。

试试这个,它可以帮助你

通过使用“select城市”,“select区域”,“select站点”来避免空指针exception。

  public getStateList(){ stateList= new ArrayList<SelectItem>(); stateList.add(new SelectItem("A")); } public getCityList(){ CityList= new ArrayList<SelectItem>(); if(selectState.equals("A")) { CityList.add(new SelectItem("B")); } else { CityList.add(new SelectItem("--Select City--")); selectCity = "--Select City--"; } public getRegionList(){ RegionList= new ArrayList<SelectItem>(); if(selectCity.equals("B")) { RegionList.add(new SelectItem("C")); } else { RegionList.add(new SelectItem("--Select Region--")); selectRegion = "--Select Region--"; } } public getStationList(){ StationList= new ArrayList<SelectItem>(); if(selectRegion.equals("C")) { StationList.add(new SelectItem("D")); } else { StationList.add(new SelectItem("Select Station")); selectStation = "--Select Station--"; } } 

你正面临这个问题,因为你有两次id="first" 。 解决这个问题,它应该工作。