做多因/级联selectOneMenu用于在下拉列表JSF(Make multiple depend

2019-09-01 23:18发布

我试图让4个依赖的菜单。

当用户选择从所述第一菜单中的项,所述第二菜单将显示相关的数据,并且当用户从第二个选择项目,第三个将显示相关的数据等。

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

<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个菜单得到空值

Answer 1:

把豆在视图范围和getter方法摆脱任何业务逻辑的。

bean必须被放置在视图范围内,使所有先前的选择和新的可用项目会被记住,否则事情会如果如未能rendered属性取决于其仅在先前请求中设定的条件,或者如果JSF需要验证所选针对现有项目的列表项。

getter方法不应该包含任何业务逻辑,因为他们也将在AO验证阶段进行调用。 您应该使用<f:ajax listener>执行基于变化的业务逻辑。 你应该在监听器方法也明确地清除掉孩子的下拉列表中选择值。 您可以使用<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.
}

也可以看看:

  • 如何选择合适的豆范围是什么?
  • 在JSF添加一个“什么也没有选择”选项将selectOneMenu用于最佳方式
  • 如何填充h的选择:从数据库selectOneMenu用于?
  • 当使用valueChangeListener或f:ajax的听众?
  • 为什么JSF调用干将多次


Answer 2:

有一个在你的代码一个错字错误。 对于第三个菜单,你给了ID名称为“第一”,而不是“第三”。 可能是它这个问题的,因为。



Answer 3:

试试这个,它可以帮助你

通过使用 - 选择City--, - 选择Region--, - 选择站 - 避免空指针异常。

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


Answer 4:

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



文章来源: Make multiple dependent / cascading selectOneMenu dropdown lists in JSF