Making direct mappings between a Map and a dropdown box with Java Server Faces 2.3 is simple and immediate.
Given the sample Session Bean below:
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
@SessionScoped
@Named
public class ThatBean implements Serializable {
//stuff...
private static final Map<String, Object> thatMap;
//stuff...
private String thatId;
//stuff...
static {
thatMap = new LinkedHashMap<>();
thatMap.put("TheDesc1", "TheKey1");
thatMap.put("TheDesc2", "TheKey2");
}
//stuff...
public Map<String, Object> getThatMap() {
return this.thatMap;
}
//stuff...
public String getThatId() {
return thatId;
}
//stuff...
public void setThatId(String thatId) {
this.thatId = thatId;
}
}
The code in the JSF XHTML file is reduced to just a few lines:
<h:selectOneMenu value="#{thatBean.thatId}">
<f:selectItems value="#{thatBean.thatMap}" />
</h:selectOneMenu>
The mapping is automatic with key and value of the option tag of the select tag.
However, the automation can significantly influence the way we populate our Map.
For finer control we can use the following form:
<h:selectOneMenu value="#{thatBean.thatId}">
<f:selectItems
value="#{thatBean.thatMap.entrySet()}"
var="entry"
itemValue="#{entry.key}"
itemLabel="#{entry.value}" />
</h:selectOneMenu>
In the simplest cases, if we don’t need a Map and can hard-code the values:
<h:selectOneMenu value="#{thatBean.thatId}">
<f:selectItem itemValue="Key1" itemLabel="Label1" />
<f:selectItem itemValue="Key2" itemLabel="Label2" />
</h:selectOneMenu>
Below is the full text of the example page:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Dropdown box examples</title>
</h:head>
<h:body>
Dropdown box examples
<h:form>
Select 1
<h:selectOneMenu value="#{thatBean .thatId}">
<f:selectItems value="#{thatBean.thatMap}" />
</h:selectOneMenu>
Select 2
<h:selectOneMenu value="#{thatBean.thatId}">
<f:selectItems
value="#{thatBean.thatMap.entrySet()}"
var="entry"
itemValue="#{entry.key}"
itemLabel="#{entry.value}" />
</h:selectOneMenu>
Select 3
<h:selectOneMenu value="#{thatBean.thatId}">
<f:selectItem itemValue="Key1" itemLabel="Label1" />
<f:selectItem itemValue="Key2" itemLabel="Label2" />
</h:selectOneMenu>
</h:form>
</h:body>
</html>
One clarification, the @SessionScoped and @Named annotations replace the old and deprecated ones,
which we can obviously continue to use for the moment.
