在JSF中制作多个从属/级联的selectOneMenu下拉列表 [英] Make multiple dependent / cascading selectOneMenu dropdown lists in JSF

查看:151
本文介绍了在JSF中制作多个从属/级联的selectOneMenu下拉列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作4个从属菜单.

I am trying to make 4 dependent menus.

当用户从第一个菜单中选择一项时,第二个菜单将显示相关数据,而当用户从第二个菜单中选择一项时,第三个菜单将显示相关数据,依此类推.

When the user chooses an item from the first menu, the second menu will show dependent data and when the user chooses item from the second one , the third one will show dependent data and so on.

用户将仅在第一个菜单上看到项目,其他项目将为空白.如果他在第一个菜单上选择一个项目,则第二个菜单将显示数据,但第三个和第四个菜单将保持空白,依此类推.用户最终必须从所有4个菜单中选择条目.

The user will see items on the first menu only and the other ones will be blank. If he chooses an item on the first menu the second one will show data but the third and the fourth will remain blank, and so on. The user must eventually choose entries from all the 4 menus.

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

它仅在前两个菜单中起作用,其他两个菜单获得空值

it's only working at the first 2 menus the other 2 menus get null values

推荐答案

将bean放入视图范围,并摆脱getter方法中的任何业务逻辑.

Put the bean in the view scope and get rid of any business logic in getter methods.

必须将bean放在视图作用域中,以便记住所有以前的选择和新的可用项,否则如果例如rendered属性取决于仅在先前请求中设置的条件,或者取决于JSF是否需要根据可用项目列表来验证所选项目.

The bean must be placed in the view scope so that all previous selections and new available items are remembered, otherwise things will fail if e.g. rendered attribute depends on a condition which was only set in a previous request, or if JSF needs to validate the selected item against list of available items.

getter方法不应包含任何业务逻辑,因为它们也将在a.o期间被调用.验证阶段.您应该使用<f:ajax listener>来基于更改执行业务逻辑.您还应该在侦听器方法中明确清除子下拉列表的选定值.您可以使用<f:ajax render>更新子下拉列表的内容.

The getter methods should not contain any business logic as they will also be invoked during a.o. validations phase. You should use <f:ajax listener> to perform business logic based on a change. You should in the listener method also explicitly clear out selected values of child dropdowns. You can use <f:ajax render> to update the contents of child dropdowns.

因此,

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

另请参见:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆