“form:
xxxxxx: Validation Error: Value"
BalusC comments: “the list behind <f:selectItems
value /> does not
contain the submitted value during processing of the form submit request as per
the Object#equals() contract.” He says this
may be caused because of problems in the equals() method.
PrimeFaces online showcase example does not have this
problem. They probebly solved it in the
coming versions.
For the time being I developed an other solution. I changed the types od selects from hashMap
to SelectItem lists as seen below:
asrSelect3.xhtml
-----------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD
XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
xmlns:p="http://primefaces.org/ui">
<h:head><title>PrimeFaces ARS Test</title>
</h:head>
<h:body>
<div align="center">
<h1 class="ui-widget-header
ui-corner-all" align="center">PrimeFaces ARS Test</h1>
<br/>
<p:fieldset legend="Multiple
Selects">
<h:form id="form">
<p:messages id="msgs"
showDetail="true" />
<p:panel header="Double
Combo" style="margin-bottom:10px;">
<h:panelGrid columns="2"
cellpadding="5">
Continent:
<h:selectOneMenu id="continent"
value="#{arsBean3.continent}">
<f:selectItems value="#{arsBean3.continents}"/>
<f:ajax render="countries"
listener="#{arsBean3.handleContinentChange2}"
/>
</h:selectOneMenu>
<br/>Country:
<h:selectOneMenu value="#{arsBean3.country}"
id="countries">
<f:selectItems value="#{arsBean3.countries}"/>
</h:selectOneMenu>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit"
update="msgs" actionListener="#{arsBean3.displayLocation}"
id="btnSubmit"/>
</p:panel>
</h:form>
</p:fieldset>
<br/>
</div>
</h:body></html>
arsBean3.java
-------------------
package ars.primefaces.ajax;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import
javax.faces.application.FacesMessage;
import
javax.faces.context.FacesContext;
import
javax.faces.event.AjaxBehaviorEvent;
import
javax.faces.model.SelectItem;
import
javax.faces.bean.ManagedBean;
import
javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class ArsBean3 implements
Serializable {
private
String continent;
private
String country;
private
List<SelectItem> continents = new ArrayList<SelectItem>();
private
Map<String,List<SelectItem>> countryDetailsData =
new HashMap<String, List<SelectItem>>();
private
List<SelectItem> countries = new ArrayList<SelectItem>();
public
ArsBean3() {
continents.add(new
SelectItem("Europe"));
continents.add(new
SelectItem("Asia"));
continents.add(new
SelectItem("America"));
List<SelectItem>
countryDetailsEurope = new ArrayList<SelectItem>();
countryDetailsEurope.add(new
SelectItem("Germany"));
countryDetailsEurope.add(new
SelectItem("Britain"));
countryDetailsEurope.add(new
SelectItem("France"));
List<SelectItem>
countryDetailsAmerica = new ArrayList<SelectItem>();
countryDetailsAmerica.add(new
SelectItem("US"));
countryDetailsAmerica.add(new
SelectItem("Canada"));
countryDetailsAmerica.add(new
SelectItem("Mexico"));
List<SelectItem>
countryDetailsAsia = new ArrayList<SelectItem>();
countryDetailsAsia.add(new
SelectItem("Turkey"));
countryDetailsAsia.add(new
SelectItem("Russia"));
countryDetailsAsia.add(new
SelectItem("China"));
countryDetailsData.put("Europe",
countryDetailsEurope);
countryDetailsData.put("America",
countryDetailsAmerica);
countryDetailsData.put("Asia",
countryDetailsAsia);
}
public
String getContinent() {
return
continent;
}
public
void setContinent(String continent) {
this.continent
= continent;
}
public
String getCountry() {
return
country;
}
public
void setCountry(String country) {
this.country
= country;
}
public
List<SelectItem> getContinents() {
return
continents;
}
public
void setContinents(List<SelectItem> continents) {
this.continents
= continents;
}
public
Map<String, List<SelectItem>> getCountryDetails() {
return
countryDetailsData;
}
public
void setCountryDetails(Map<String, List<SelectItem>>
countryDetailsData) {
this.countryDetailsData
= countryDetailsData;
}
public
List<SelectItem> getCountries() {
return
countries;
}
public
void setCountries(List<SelectItem> countries) {
this.countries
= countries;
}
public
void handleContinentChange2(AjaxBehaviorEvent evt) {
if(continent
!=null && !continent.equals(""))
countries
= countryDetailsData.get(continent);
else
countries
= new ArrayList<SelectItem>();
country=countries.iterator().next().getLabel();
System.out.println(country);
System.out.println(countries);
}
public void displayLocation() {
FacesMessage msg = new
FacesMessage("Selected", "Continent:" + continent + ",
Country: " + country);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
It worked. Then I carried the same variable types and
used Primefacesmultiselect and ajax call.
This also worked correctly.
arsSelect4.xhtml
-----------------------
<!DOCTYPE html
PUBLIC "-//W3C//DTD
XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
xmlns:p="http://primefaces.org/ui">
<h:head><title>PrimeFaces ARS Test</title>
</h:head>
<h:body>
<div align="center">
<h1 class="ui-widget-header
ui-corner-all" align="center">PrimeFaces ARS Test</h1>
<br/>
<p:fieldset legend="Multiple
Selects">
<h:form id="form">
<!--
p:growl id="msgs" showDetail="true"/-->
<p:messages id="msgs"
showDetail="true"/>
<p:panel header="Double
Combo" style="margin-bottom:10px;">
<h:panelGrid columns="2"
cellpadding="5">
<p:selectOneMenu id="continent"
value="#{arsBean4.continent}">
<f:selectItem itemLabel="Select
Continent" itemValue=""
/>
<f:selectItems value="#{arsBean4.continents}"
/>
<p:ajax update="form:countries"
listener="#{arsBean4.handleContinentChange}" />
</p:selectOneMenu>
<p:selectOneMenu id="countries"
value="#{arsBean4.country}">
<f:selectItem itemLabel="Select
Country" itemValue=""
/>
<f:selectItems value="#{arsBean4.countries}"
/>
</p:selectOneMenu>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit"
update="msgs" actionListener="#{arsBean4.displayLocation}"
id="btnSubmit"/>
</p:panel>
</h:form>
</p:fieldset>
<br/>
</div>
</h:body></html>
arsBean4.java
-------------------
package ars.primefaces.ajax;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import
javax.faces.application.FacesMessage;
import
javax.faces.context.FacesContext;
import
javax.faces.event.AjaxBehaviorEvent;
import
javax.faces.model.SelectItem;
import
javax.faces.bean.ManagedBean;
import
javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class ArsBean4 implements
Serializable {
private
String continent;
private
String country;
private
List<SelectItem> continents = new ArrayList<SelectItem>();
private
Map<String,List<SelectItem>> countryDetailsData =
new HashMap<String, List<SelectItem>>();
private
List<SelectItem> countries = new ArrayList<SelectItem>();
public
ArsBean4() {
continents.add(new
SelectItem("Europe"));
continents.add(new
SelectItem("Asia"));
continents.add(new
SelectItem("America"));
List<SelectItem>
countryDetailsEurope = new ArrayList<SelectItem>();
countryDetailsEurope.add(new
SelectItem("Germany"));
countryDetailsEurope.add(new
SelectItem("Britain"));
countryDetailsEurope.add(new
SelectItem("France"));
List<SelectItem>
countryDetailsAmerica = new ArrayList<SelectItem>();
countryDetailsAmerica.add(new
SelectItem("US"));
countryDetailsAmerica.add(new
SelectItem("Canada"));
countryDetailsAmerica.add(new
SelectItem("Mexico"));
List<SelectItem>
countryDetailsAsia = new ArrayList<SelectItem>();
countryDetailsAsia.add(new
SelectItem("Turkey"));
countryDetailsAsia.add(new
SelectItem("Russia"));
countryDetailsAsia.add(new
SelectItem("China"));
countryDetailsData.put("Europe",
countryDetailsEurope);
countryDetailsData.put("America",
countryDetailsAmerica);
countryDetailsData.put("Asia",
countryDetailsAsia);
}
public
String getContinent() {
return
continent;
}
public
void setContinent(String continent) {
this.continent
= continent;
}
public
String getCountry() {
return
country;
}
public
void setCountry(String country) {
this.country
= country;
}
public
List<SelectItem> getContinents() {
return
continents;
}
public
void setContinents(List<SelectItem> continents) {
this.continents
= continents;
}
public
Map<String, List<SelectItem>> getCountryDetails() {
return
countryDetailsData;
}
public
void setCountryDetails(Map<String, List<SelectItem>>
countryDetailsData) {
this.countryDetailsData
= countryDetailsData;
}
public
List<SelectItem> getCountries() {
return
countries;
}
public
void setCountries(List<SelectItem> countries) {
this.countries
= countries;
}
public
void handleContinentChange() {
if(continent
!=null && !continent.equals(""))
countries
= countryDetailsData.get(continent);
else
countries
= new ArrayList<SelectItem>();
country=countries.iterator().next().getLabel();
System.out.println(country);
System.out.println(countries);
}
public void displayLocation() {
FacesMessage msg = new
FacesMessage("Selected", "Continent:" + continent + ",
Country: " + country);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
My solution to a temporary problem
in the primefaces showcase multiselect and AJAX usage is to change the variable
types used for the selectitems. It
certainly solves the problem as seen above.
Kind regards.
Ali R+ SARAL