-
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