JSF selectOneMenu and Converters

Published: Saturday, 13 November 2010
jsf

How to make a single select dropdown with selectOneMenu, using converted objects.

Create your converter class.

Make it accessible via the managed bean. I did this by adding a getter to my stock managed bean. Alternatively you could register your converter so it will work globally.

public class StockBean {
   ...
    public ExchangeConverter getExchangeConverter() {
        return exchangeConverter;
    }
   ...
}

My StockBean is already registered under #{stockBean}. This means we can refer to the ExchangeConverter using #{stockBean.exchangeConverter}. The ExchangeConverter converts a String displayed by or sent to the browser to an Exchange. In this project an Exchange is a stock exchange, such as NYSE.

public class Exchange {
    private String code;

    public Exchange(String code) {
        this.code = code;
    }
    public String getCode() {
        return code;
    }
}

Next, add the Exchange the user will pick into the managed bean.

public class StockBean {
    // user selected fields
    private Exchange exchange;

    public void setExchange(Exchange exchange) {
        this.exchange = exchange;
    }

    public Exchange getExchange() {
        return exchange;
    }
    ...
}

Now we need to generate the values the user can choose. The following method returns a List of javax.faces.model.SelectItem. These will be used in the dropdown or select box.

public class StockBean {
...
    public List<SelectItem> getExchanges() {
        List<SelectItem> selectItems = new ArrayList<SelectItem>();
        List<Exchange> exchanges = exchangeService.getExchanges();
        for (Exchange exchange : exchanges) {
            SelectItem item = new SelectItem(exchange, exchange.getCode());
            selectItems.add(item);
        }
       return selectItems;

    }

When creating the SelectItems, make sure you set the value as your special type, not a String. In this case give the SelectItem the Exchange for the value.

Now we can add it to the form.

<h:selectOneMenu value="#{stockBean.exchange}" converter="#{stockBean.exchangeConverter}" >
  <f:selectItems value="#{stockBean.exchanges}"/>
</h:selectOneMenu>

Troubleshooting

Check the converter is being passed the correct class for getAsString. If not, check the SelectItem's value is the correct class.