-
Available since OmniFaces 3.0
The o:selectItemGroups
is an extension of UISelectItems
which allows you to iterate over a nested collection representing groups of select items. This is basically the UIComponent
counterpart of jakarta.faces.model.SelectItemGroup
. There is no equivalent (yet) in the standard Faces API. Currently the only way to represent SelectItemGroup
in UI is to manually create and populate them in a backing bean which can end up to be quite verbose.
Usage
Below example assumes a List<Category>
as value wherein Category
in turn has a List<Product>
.
<h:selectOneMenu value="#{bean.selectedProduct}" converter="omnifaces.SelectItemsConverter">
<f:selectItem itemValue="#{null}" />
<o:selectItemGroups value="#{bean.categories}" var="category" itemLabel="#{category.name}">
<f:selectItems value="#{category.products}" var="product" itemLabel="#{product.name}" />
</o:selectItemGroups>
</h:selectOneMenu>
Demo
Demo source code
<h:form>
<h2>Manually creating new SelectItemGroup()</h2>
<h:selectOneMenu value="#{selectItemGroupsBean.selectedProduct}" converter="omnifaces.SelectItemsConverter">
<f:selectItem itemValue="#{null}" itemLabel="Select ..." />
<f:selectItems value="#{selectItemGroupsBean.categorySelectItems}" />
<f:ajax render="selectedProduct" />
</h:selectOneMenu>
<p>Selected product: <strong><h:outputText id="selectedProduct" value="#{selectItemGroupsBean.selectedProduct.name}" /></strong></p>
</h:form>
<h:form>
<h2>Using <o:selectItemGroups></h2>
<h:selectOneMenu value="#{selectItemGroupsBean.selectedProduct}" converter="omnifaces.SelectItemsConverter">
<f:selectItem itemValue="#{null}" itemLabel="Select ..." />
<o:selectItemGroups value="#{selectItemGroupsBean.categories}" var="category" itemLabel="#{category.name}">
<f:selectItems value="#{category.products}" var="product" itemLabel="#{product.name}" />
</o:selectItemGroups>
<f:ajax render="selectedProduct" />
</h:selectOneMenu>
<p>Selected product: <strong><h:outputText id="selectedProduct" value="#{selectItemGroupsBean.selectedProduct.name}" /></strong></p>
</h:form>
package org.omnifaces.showcase.components;
import static java.util.stream.Collectors.toList;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import jakarta.annotation.PostConstruct;
import jakarta.faces.model.SelectItem;
import jakarta.faces.model.SelectItemGroup;
import jakarta.inject.Named;
import org.omnifaces.cdi.ViewScoped;
import org.omnifaces.showcase.model.Category;
import org.omnifaces.showcase.model.Product;
@Named
@ViewScoped
public class SelectItemGroupsBean implements Serializable {
private static final long serialVersionUID = 1L;
private Product selectedProduct;
private List<Category> categories;
private List<SelectItem> categorySelectItems;
@PostConstruct
public void init() {
categories = loadExampleCategories();
categorySelectItems = categories.stream().map(category -> {
SelectItemGroup group = new SelectItemGroup(category.getName());
group.setSelectItems(category.getProducts().stream()
.map(product -> new SelectItem(product, product.getName()))
.toArray(SelectItem[]::new));
return group;
}).collect(toList());
}
private List<Category> loadExampleCategories() {
List<Category> categories = new ArrayList<>();
categories.add(new Category("Animals", new Product("Cat"), new Product("Dog"), new Product("Parrot")));
categories.add(new Category("Cars", new Product("Alfa Romeo"), new Product("BMW"), new Product("Hyundai"), new Product("Toyota")));
return categories;
}
public Product getSelectedProduct() {
return selectedProduct;
}
public void setSelectedProduct(Product selectedProduct) {
this.selectedProduct = selectedProduct;
}
public List<Category> getCategories() {
return categories;
}
public List<SelectItem> getCategorySelectItems() {
return categorySelectItems;
}
}
package org.omnifaces.showcase.model;
import static java.util.Arrays.asList;
import java.util.List;
public class Category {
private String name;
private List<Product> products;
public Category() {
//
}
public Category(String name, Product... products) {
this.name = name;
this.products = asList(products);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
}
package org.omnifaces.showcase.model;
import org.omnifaces.showcase.validators.ProductGroup;
import org.omnifaces.showcase.validators.ValidProduct;
@ValidProduct(groups = ProductGroup.class)
public class Product {
private String name;
private int number1;
private int number2;
public Product() {
//
}
public Product(String name) {
this.name = name;
}
public Product(Product other) {
number1 = other.number1;
number2 = other.number2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber1() {
return number1;
}
public void setNumber1(int number1) {
this.number1 = number1;
}
public int getNumber2() {
return number2;
}
public void setNumber2(int number2) {
this.number2 = number2;
}
}
Documentation & Sources