2012-10-15 39 views
1

我有兩個級聯的p:selectOneMenu組件。第一個顯示哈希映射的區域,第二個顯示ajax選定區域的城市。但是,提交與城市選擇的形式時,我得到級聯p:selectOneMenu失敗,驗證錯誤:值無效

Validation Error: Value is not valid

這裏的景色

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

這是怎麼造成的,我怎麼能解決這個問題?

回答

0

你需要做的第一件事是告訴鏈接ajax事件。所以,你可能希望它在valueChange事件發生,所以你的Ajax應該是:

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

這是默認事件。所以這不會改變任何OP。 – BalusC

+0

我總是明確說明事件。我甚至沒有意識到它會默認valueChange(儘管這很有道理,我猜)。看起來我今天也學到了一些東西。這是這個論壇的美麗。 – SteveS

1

時可用值列表中沒有包含在下拉列表中提交的值,您將收到此錯誤。因此,這意味着可用值列表在提交表單的HTTP請求期間與顯示錶單的HTTP請求相比,發生了不兼容的變化。這反過來常常意味着後臺bean是請求作用域,並且可用值的列表未在其(後)構造函數中進行預初始化。

要麼把豆在視圖範圍內,添加代碼正確preinitializes基於請求參數可用值的列表中,應該解決您的問題。

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

+0

+1用於擴展BalusC的答案與例子。 –