级联p:selectOneMenu失败,验证错误:值无效

时间:2012-10-15 08:36:41

标签: jsf primefaces hashmap selectonemenu

我有两个级联p:selectOneMenu组件。第一个显示散列图中的区域,第二个显示ajax选定区域的城市。但是当提交选定城市的表格时,我会得到

  

验证错误:值无效

这是视图

<p:selectOneMenu id="area" value="#{bean.area}">
    <f:selectItem itemLabel="Select Area" itemValue="" />
    <f:selectItems value="#{bean.areas}" />
    <p:ajax update="city" listener="#{bean.handleAreaChange()}" />
</p:selectOneMenu>
<p:selectOneMenu id="city" value="#{bean.city}">
    <f:selectItem itemLabel="Select City" itemValue="" />
    <f:selectItems value="#{bean.cities}" />
</p:selectOneMenu>  

这是豆子:

private String area;
private String city;
private Map<String, String> areas = new HashMap<String, String>();
private Map<String, String> cities = new HashMap<String, String>();
private Map<String, Map<String, String>> allCities = new HashMap<String, Map<String,String>>();

public void handleAreaChange() {
    if (area != null && !area.isEmpty()) {
        cities = allCities.get(area);
    } else {
        cities = new HashMap<String, String>();
    }
}

这是如何引起的?如何解决?

3 个答案:

答案 0 :(得分:1)

当提交的下拉列表值未包含在可用值列表中时,您将收到此错误。因此,这意味着在表单提交的HTTP请求期间,与显示表单的HTTP请求相比,可用值列表已不相容地更改。这反过来通常意味着支持bean是请求范围的,并且可用值列表未在其(post)构造函数中预先初始化。

将bean放在视图范围中,添加代码,根据请求参数正确预先初始化可用值列表,应解决您的问题。

答案 1 :(得分:1)

正如BalusC所说,selectItem的值(标识符)已经改变。如果您的bean是请求作用域或者对象已更改服务器端,则会发生这种情况。

我使用的一个常见解决方案是将selectItem的值设置为它所代表的对象的id。

假设CityArea具有唯一标识符(id),如下所示:

public class City //or Area
{
    private Long id;
    private String name;

    //Rest of class
}

然后,您可以为CityArea

引入转换器
@FacesConverter("cityConverter")
public class CityConverter implements javax.faces.convert.Converter
{
    @Override
    public Object getAsObject(FacesContext ctx, UIComponent cmp, String str)
    {
        //Convert id to Object (City) and return it
    }

    @Override String getAsString(FacesContext ctx, UIComponent, Object obj)
    {
        //Return the id that represents the Object (City) here
        return ((City)obj).getId().toString();
    }
}

在您的JSF页面中使用转换器:

<p:selectOneMenu id="area" value="#{bean.area}" converter="areaConverter">
    <f:selectItem itemLabel="Select Area" itemValue="" />
    <f:selectItems value="#{bean.areas}" />
    <p:ajax update="city" listener="#{bean.handleAreaChange()}" />
</p:selectOneMenu>
<p:selectOneMenu id="city" value="#{bean.city}" converter="cityConverter">
    <f:selectItem itemLabel="Select City" itemValue="" />
    <f:selectItems value="#{bean.cities}" />
</p:selectOneMenu>

More about how to implement a FacesConverter on this site

答案 2 :(得分:0)

您需要做的第一件事就是将ajax链接到事件。所以你可能希望它发生在valueChange事件上,所以你的ajax应该是:

<p:ajax update="tmil2" event="valueChange" listener="#{BeanAreaAndCity.handleCityChange()}"></p:ajax>