Massimo Caliman
by Massimo Caliman
1 min read

Categories

  • Java

Tags

  • code
  • en
  • java
  • jsf

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.