JSF: selectManyCheckbox - state array always holds only one selected item - jsf

When multiple check boxes are checked only first item checked is provided in the array to the backing bean setter method. Other checked items are ignored.
For example: if 1, 2, 3 are checked, string array for setter will contain only 1. Or if 2 and 3 are checked, array will contain only 2.
HTML:
<h:selectManyCheckbox id="tableColumns"
value="#{contextBean.selectedStates}">
<f:selectItem itemValue="1" itemLabel="Number1 - 1" />
<f:selectItem itemValue="2" itemLabel="Number1 - 2" />
<f:selectItem itemValue="3" itemLabel="Number1 - 3" />
</h:selectManyCheckbox>
<a4j:commandButton value="Filter"
reRender="#{leftPanelId}, #{tab}"
action="#{contextBean.filter()}"/>
Backing Seam bean:
#Name (ContextBean.BEAN_NAME)
#Scope (ScopeType.SESSION)
#AutoCreate
public class ContextBean {
public static final String BEAN_NAME = "contextBean";
private String[] selectedStates;
public String[] getSelectedStates()
{
return selectedStates;
}
public void setSelectedStates(String[] selectedStates) //has always one item
{
this.selectedStates = selectedStates;
}
public void filter()
{
System.out.println(selectedStates); //holds only one item
}
}
Any help appreciated. What and where to look for?

Related

<f:selectItems is not returning value in <p:selectOneMenu>

I have a problem with getting value of f:selectItems but it is returning its label.
here is the code;
<p:selectOneMenu>.
<p:outputLabel value="Major Diseases"></p:outputLabel>
<p:selectOneMenu value="#{dataMigeration.mdId}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems var="t"
value="#{dataMigeration.majorDiseas}"
itemLabel="#{t.value.mdName}"
itemValue="#{t.value}"/>
<p:ajax listener="#{dataMigeration.getSubDiseasesByMojarDisease(dataMigeration.mdId)}"
event="change" update="dataMigration"/>
</p:selectOneMenu>
here is the dataMigeration class
#ManagedBean(name="dataMigeration")
#SessionScoped
public class DataMigeration{
String mdId;
private List<SelectItem> majorDiseas = new ArrayList<SelectItem>();
public List<SelectItem> getMajorDiseas() {
majorDiseas = new ArrayList<SelectItem>();
System.out.println("DataMigeration.getMajorDiseas():");
List<DiseaseCategory> majorDiseasesList = new ArrayList<DiseaseCategory>();
majorDiseasesList=DataManager.findAllRecords();
for (DiseaseCategory obj : majorDiseasesList) {
majorDiseas.add(new SelectItem(obj.getMdId(), obj.getMdName()));
}
return majorDiseas;
}
public void getSubDiseasesByMojarDisease(String mdId)
{
System.out.println("\n\n\n\n | value:"+mdId);
}
but I am getting mdId=itemLabel of f:selectedItem but I want to get itemValue of f:selectem. SomeWhere I have done before but I forgot now how to get ItemValue.
Your 'f:selectItems' statement is wrong. You can use the 'var' attribute to loop through a list of complex Java objects to dynamically create a list of SelectItem objects. (See http://www.mkyong.com/jsf2/jsf-2-dropdown-box-example/ for examples)
But in this case, you've already created your list of SelectItem objects in the backing bean, so just reference it like this instead:
<f:selectItems value="#{dataMigeration.majorDiseas}" />

Can't bind SelectItem list to <f:selectItem

I am using IceFaces components and I am trying to fill up a select with some values that correspond to a MangedBean property.
<h:form>
<ice:selectOneMenu size="1" style="width: 180px">
<f:selectItem value="#{stockManagedBean.listeCategoriesItem}"></f:selectItem>
</ice:selectOneMenu>
</h:form>
listeCategoriesItem is a property of StockManagedBean and is an ArrayList of SelectItem.
#ManagedBean
public class StockManagedBean {
CategorieDAO categorieDAO;
List<SelectItem> listeCategoriesItem;
public StockManagedBean() {
categorieDAO = new CategorieDAO();
listeCategoriesItem = new ArrayList<SelectItem>();
List<Categorie> listeCategories = categorieDAO.selectAllCat();
for(Categorie categorie: listeCategories) {
listeCategoriesItem.add(new SelectItem(categorie.getCatId(), categorie.getCatNom()));
}
}
public List<SelectItem> getListeCategoriesItem() {
return listeCategoriesItem;
}
public void setListeCategoriesItem(List<SelectItem> listeCategoriesItem) {
this.listeCategoriesItem = listeCategoriesItem;
}
}
I tested the values that come from my DAO and they are all correct. I also tested the values of the list in the getter and they are also correct, but when I load my html page, nothing is in the select list...
Use <f:selectItems> instead of <f:selectItem>. Note the s at the end of the former component.
<ice:selectOneMenu size="1" style="width: 180px">
<f:selectItems value="#{stockManagedBean.listeCategoriesItem}" />
</ice:selectOneMenu>
Also, it would be good to also have a field in your bean that will handle the value of the selected item in your selectOneMenu.
<ice:selectOneMenu size="1" style="width: 180px"
value="#{stockManagedBean.selectedCategory}">
<f:selectItems value="#{stockManagedBean.listeCategoriesItem}" />
</ice:selectOneMenu>
And in your managed bean:
#ManagedBean
public class StockManagedBean {
private String selectedCategory;
//rest of your code
//getters and setters...
}

Loading h:selectOneMenu depending of another h:selectOneMenu value

I have two h:selectOneMenu (1: Countries, 2: Cities). I need to load all cities from one selected country in the cities selectOneMenu using ajax. When I change the value of the countries selectOneMenu my cities selectOneMenu takes a null value from countryBean.selectedCountry.
<h:panelGrid columns="2">
<h:outputLabel for="countries" value="Countries: " />
<h:selectOneMenu converter="omnifaces.SelectItemsConverter"
id="countries" required="true" value="#{countryBean.selectedCountry}">
<f:selectItem itemLabel="Choose country" />
<f:selectItems value="#{countriesBB.findAllCountries()}"
var="country" itemLabel="#{country.name}" />
<f:ajax event="change" render="cities" />
</h:selectOneMenu>
<h:outputLabel for="cities"
value="Cities: " />
<h:selectOneMenu converter="omnifaces.SelectItemsConverter"
id="cities" required="true"
value="#{cityBean.selectedCity}">
<f:selectItem itemLabel="Choose city" />
<f:selectItems value="#{cityBean.findAllCitiesByCountry(countryBean.selectedCountry)}"
var="city" itemLabel="#{city.name}" />
</h:selectOneMenu>
</h:panelGrid>
This is the method that find the cities:
public List<city> findAllCitiesByCountry(Country country) {
List<City> cities = null;
try {
cities = citiesService.findAllCitiesByCountry(country);
} catch (Exception exception) {
logger.debug("Error finding cities.", exception);
}
return cities;
}
I am getting a NullPointerException because countryBean.selectedCountry is always null. What is the right way to do this?
One of the many rules which a JSF starter need to know:
Don't do business logic in a getter method.
Once you try to fix that by keeping your getter methods true getter methods (i.e. do not do anything else than just return property;) and performing the business logic in (post)constructor and/or action(listener) methods, then this particular problem shall disappear.
Here's a kickoff example:
<h:selectOneMenu value="#{bean.country}">
<f:selectItems value="#{bean.countries}" ... />
<f:ajax listener="#{bean.changeCountry}" render="cities" />
</h:selectOneMenu>
<h:selectOneMenu id="cities" value="#{bean.city}">
<f:selectItems value="#{bean.cities}" ... />
</h:selectOneMenu>
With something like this in a #ViewScoped bean:
private Country country; // +getter+setter
private City city; // +getter+setter
private List<Countries> countries; // +getter
private List<Cities> cities; // +getter
#EJB
private SomeService service;
#PostConstruct
public void init() {
countries = service.getCountries();
}
public void changeCountry() {
cities = service.getCities(country);
}

Cascading p:selectOneMenu fails with Validation Error: Value is not valid [duplicate]

This question already has answers here:
Validation Error: Value is not valid
(3 answers)
Closed 7 years ago.
I have two cascading p:selectOneMenu components. The first shows areas from a hashmap and the second shows cities for the selected area by ajax. But when submitting the form with the city selected, I get
Validation Error: Value is not valid
Here's the view
<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>
Here's the bean:
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>();
}
}
How is this caused and how can I solve it?
You will get this error when the submitted value of the dropdown is not contained in the list of available values. So this means that the list of available values has incompatibly changed during the HTTP request of the form submit as compared to the HTTP request of displaying the form. This in turn often means that the backing bean is request scoped and that the list of available values is not preinitialized in its (post)constructor.
Either putting the bean in the view scope, or adding code which properly preinitializes the list of available values based on request parameters, should fix your problem.
As BalusC said the value (identifier) of the selectItem has changed. This can happen if your bean is request scoped or if the objects have changed server side.
A common solution I use is to set the value of the selectItem to an id of the object it represents.
Lets assume City and Area have unique identifiers (id) and looks like this:
public class City //or Area
{
private Long id;
private String name;
//Rest of class
}
You can then introduce a converter for City and Area:
#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();
}
}
In your JSF page make use of the converter:
<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.
The first thing you need to do is to tell link the ajax to an event. So you probably want it to happen on the valueChange event so your ajax should be:
<p:ajax update="tmil2" event="valueChange" listener="#{BeanAreaAndCity.handleCityChange()}"></p:ajax>

How to set default value of h:selectOneRadio button

I am unable to set the default value of h:selectOneRadio as i need radio button to be pre selected
<h:selectOneRadio id="myRadio" value="#{Externalbean.addressFlag}" >
<f:selectItem itemValue="1" itemLabel="Yes"/>
<f:selectItem itemValue="0" itemLabel="No"/>
</h:selectOneRadio>
and my backing bean is
private String addressFlag="0";
public String getAddressFlag() {
return addressFlag;
}
public void setAddressFlag(String addressFlag) {
this.addressFlag = addressFlag;
}
but no luck
You need to set the default value in the init method of your backing bean:
#ManagedBean
public class YourBackingBean implements Serializable {
private String addressFlag;
#PostConstruct
public void init() {
addressFlag = "0";
}
public String getAddressFlag() {
return addressFlag;
}
public void setAddressFlag(String addressFlag) {
this.addressFlag = addressFlag;
}
}
I did a little test, it works just fine as expected, but I also observed that when you leave out the <h:form> tag, the behaviour of radio buttons is unpredictable and dependent on the webbrowser. The JSF-generated HTML output looks correct, but the webbrowser would in the view only select the button which was actually selected by the user in the previous request on the same page. If the cache is empty, none of the buttons is selected. At least, that was the case in FF.
So, it look like that you have forgotten to put a <h:form> around it.
Only use that <h:selectOneRadio required="true"> :
<h:selectOneRadio required="true" id="myRadio" value="#{Externalbean.addressFlag}" >
<f:selectItem itemValue="1" itemLabel="Yes"/>
<f:selectItem itemValue="0" itemLabel="No"/>
</h:selectOneRadio>
Did you try to set the addressFlag as an Integer?
private Integer addressFlag = 0;
public Integer getAddressFlag() {
return addressFlag;
}
public void setAddressFlag(Integer addressFlag) {
this.addressFlag = addressFlag;
}

Resources