JSF 2: grouping selects using SelectItemGroup + POJO

I tried working with grouped selections like this:

<h:selectOneMenu value="#{selectionLabBean.oneSelectMenuGroup}" id="SelectOneMenuGroup" > <f:selectItems value="#{selectionLabBean.heroGroupList}" /> </h:selectOneMenu> <p:message for="SelectOneMenuGroup" /> 

where heroGroupList looks something like this:

 SelectItem[] heroArr = new SelectItem[] { new SelectItem("Paladin"), ... }; heroListWithGrouping.add( new SelectItemGroup("Human", "A collection of human race Heroes", false, heroArr ) ); ..... 

And I just have to wonder if I can do this grouping with POJO instead of SelectItem objects?

If I could not achieve this, I think that I need to somehow convert the domain objects or the results of my query into SelectItem arrays in order to make it work.

Any ideas?

+7
source share
2 answers

This is really not possible if you want to use SelectItemGroup . You need to convert from the POJO collection to List<SelectItem> into a double for loop during bean (post).

 @PostConstruct public void init() { List<HeroRace> heroRaces = getItSomehowFromDatabase(); this.heroGroupList = new ArrayList<SelectItem>(); for (HeroRace heroRace : heroRaces) { SelectItemGroup group = new SelectItemGroup(heroRace.getName()); // Human, etc List<SelectItem> heroes = new ArrayList<SelectItem>(); for (Hero hero : heroRace.getHeroes()) { heroes.add(new SelectItem(hero.getName()); // Paladin, etc } group.setSelectItems(heroes.toArray(new SelectItem[heroes.size()])); this.heroGroupList.add(group); } } 

You can also use Hero as an element value.

 heroes.add(new SelectItem(hero, hero.getName()); // Paladin, etc 

so that you can bind #{selectionLabBean.oneSelectMenuGroup} to type Hero instead of String . But then you need to install Converter . This part has already answered Amorphis.

+9
source

Yes, you can return a list or POJO array instead of SelectItems. To do this, you will need a converter, but this is not very important. So, first the converter:

 @FacesConverter(forClass=Hero.class) public class HeroConverter implements Converter { @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { return new Hero(value); } @Override public String getAsString(FacesContext context, UIComponent component, Object value) { return ((Hero)value).getName(); } } 

Now, if you return the Hero es list to <f:selectItems> , you have the parameters in HTML, where the label is Hero.toString() , and the value is returned from HeroConverter.getAsString() .

One more thing. If you provide some value for this selection, JSF converts it to an object and checks (using the equals () method) if this object was in the list of objects to select. So, in the case above, you need to override equals() in Hero to check if the names match. Another solution is not to create a new instance in getAsObject , but to save the list of available Hero es and return this list to <f:selectionItems> and return the object from this list to getAsObject() .

+4
source

All Articles