-
Available since OmniFaces 1.3
The omnifaces.SelectItemsIndexConverter
is a variant of the SelectItemsConverter
which automatically converts based on the position (index) of the selected item in the list instead of the Object.toString()
of the selected item.
Usage
This converter is available by converter ID omnifaces.SelectItemsIndexConverter
. Just specify it in the converter
attribute of the selection component holding <f:selectItems>
.
<h:selectOneMenu value="#{bean.selectedItem}" converter="omnifaces.SelectItemsIndexConverter">
<f:selectItems value="#{bean.availableItems}" />
</h:selectOneMenu>
Since OmniFaces 4.5 it's also available by <o:selectItemsIndexConverter>
tag.
<h:selectOneMenu value="#{bean.selectedItem}">
<f:selectItems value="#{bean.availableItems}" />
<o:selectItemsIndexConverter />
</h:selectOneMenu>
Pros and cons as compared to SelectItemsConverter
This converter has the following advantages over SelectItemsConverter
:
- No need to rely on
Object.toString()
method of the object. - No need to extend the
SelectItemsConverter
whenObject.toString()
method of the object cannot be used. - No need to expose the object's unique key in its
Object.toString()
,if that's a problem.
This converter has the following disadvantage over SelectItemsConverter
:
- The "Validation Error: value is not valid" will never occur anymore for the case that the available select items has incompatibly changed during the postback due to a developer's mistake. The developer should make absolutely sure that exactly the same list is preserved on postback (e.g. by making it a property of a view scoped or broader scoped bean).
Demo
Demo source code
<h:form>
<p>
<b>Last selected item:</b> <h:outputText id="selected_item" value="#{selectItemsBean.selectedEntity.value}" />
</p>
<h:panelGrid columns="2">
<h:outputLabel for="iterator" value="Items with iterator: " />
<h:selectOneMenu id="iterator" value="#{selectItemsBean.selectedEntity}" converter="omnifaces.SelectItemsIndexConverter">
<f:selectItem itemValue="#{null}" itemLabel="Choose item" noSelectionOption="true" />
<f:selectItems value="#{selectItemsBean.exampleEntities}" var="entity" itemLabel="#{entity.value}" itemValue="#{entity}" />
<f:ajax render="selected_item" />
</h:selectOneMenu>
<h:outputLabel for="iterator_def_value" value="Items with iterator (default value): " />
<h:selectOneMenu id="iterator_def_value" value="#{selectItemsBean.selectedEntity}" converter="omnifaces.SelectItemsIndexConverter">
<f:selectItem itemLabel="Choose item" noSelectionOption="true" />
<f:selectItems value="#{selectItemsBean.exampleEntities}" var="entity" itemLabel="#{entity.value}" />
<f:ajax render="selected_item" />
</h:selectOneMenu>
<h:outputLabel for="selectitems" value="Items with SelectItem list: " />
<h:selectOneMenu id="selectitems" value="#{selectItemsBean.selectedEntity}" converter="omnifaces.SelectItemsIndexConverter">
<f:selectItem itemLabel="Choose item" noSelectionOption="true" />
<f:selectItems value="#{selectItemsBean.selectItems}" />
<f:ajax render="selected_item" />
</h:selectOneMenu>
<h:outputLabel for="selectitems_array" value="Items with SelectItem array: " />
<h:selectOneMenu id="selectitems_array" value="#{selectItemsBean.selectedEntity}" converter="omnifaces.SelectItemsIndexConverter">
<f:selectItem itemLabel="Choose item" noSelectionOption="true" />
<f:selectItems value="#{selectItemsBean.selectItemArray}" />
<f:ajax render="selected_item" />
</h:selectOneMenu>
</h:panelGrid>
</h:form>
package org.omnifaces.showcase.converters;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import jakarta.annotation.PostConstruct;
import jakarta.faces.model.SelectItem;
import jakarta.inject.Named;
import org.omnifaces.cdi.ViewScoped;
import org.omnifaces.showcase.model.ExampleEntity;
import org.omnifaces.util.selectitems.SelectItemsBuilder;
@Named
@ViewScoped
public class SelectItemsBean implements Serializable {
private static final long serialVersionUID = 1L;
// 3 different forms of the defining data to which SelectItems can bind.
private List<ExampleEntity> exampleEntities;
private List<SelectItem> selectItems;
private SelectItem[] selectItemArray;
private ExampleEntity selectedEntity;
@PostConstruct
public void init() {
exampleEntities = new ArrayList<>();
exampleEntities.add(new ExampleEntity(1L, "Amsterdam"));
exampleEntities.add(new ExampleEntity(2L, "Frankfurt"));
exampleEntities.add(new ExampleEntity(3L, "London"));
selectItems = new SelectItemsBuilder()
.add(new ExampleEntity(4L, "New York"), "New York")
.add(new ExampleEntity(5L, "Miami"), "Miami")
.add(new ExampleEntity(6L, "Los Angeles"), "Los Angeles")
.buildList();
selectItemArray = new SelectItemsBuilder()
.add(new ExampleEntity(7L, "Willemstad"), "Willemstad")
.add(new ExampleEntity(8L, "Oranjestad"), "Oranjestad")
.add(new ExampleEntity(9L, "Kralendijk"), "Kralendijk")
.build();
}
public List<ExampleEntity> getExampleEntities() {
return exampleEntities;
}
public List<SelectItem> getSelectItems() {
return selectItems;
}
public SelectItem[] getSelectItemArray() {
return selectItemArray;
}
public ExampleEntity getSelectedEntity() {
return selectedEntity;
}
public void setSelectedEntity(ExampleEntity selectedEntity) {
this.selectedEntity = selectedEntity;
}
}
package org.omnifaces.showcase.model;
import java.io.Serializable;
public class ExampleEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String value;
public ExampleEntity() {
//
}
public ExampleEntity(Long id, String value) {
this.id = id;
this.value = value;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public boolean equals(Object other) {
return (other instanceof ExampleEntity) && (id != null)
? id.equals(((ExampleEntity) other).id)
: (other == this);
}
@Override
public int hashCode() {
return (id != null)
? (this.getClass().hashCode() + id.hashCode())
: super.hashCode();
}
@Override
public String toString() {
return String.format("ExampleEntity[%d, %s]", id, value);
}
}
Documentation & Sources