dev@javaserverfaces.java.net

h:selectOneMenu selection and f:selectItem with null itemValue

From: Mark Collette <mark.collette_at_icesoft.com>
Date: Wed, 06 Feb 2008 15:03:13 -0700

A user filed a bug report with ICEfaces about the behaviour of our
ice:selectOneMenu component, and when I went to investigate it versus
stock JSF behaviour, I found that the unexpected behaviour was actually
with stock JSF 1.2. So, I'm hoping that I can get some guidance here.

Basically, if you want to use h:selectOneMenu to select from a list of
Long values, but also want to accomodate selecting null, there's a
problem. You can not make an f:selectItem with itemValue="#{null}"
because it will then use the itemLabel as the itemValue, so you'll be
trying to match h:selectOneMenu's value value to "Not specified" instead
of null. So then if you use itemValue="" it has inconsistent behaviour.
If you select it, then the bean will actually get null, in both the
property setter and the ValueChangeEvent, as desired. But when it
renders, it will not make the "Not specified" option be selected.
Nothing will be selected. Well, the browser will select by default the
first thing in the menu, which will be "1" in this case.

My questions are, what is the desired behaviour, selecting "Not
specified", or nothing at all? Is this a bug in Mojarra, or is this what
the spec desires?

Here's the example code:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
<body>
<h:form>
    <h:selectOneMenu value="#{bean.count}"
valueChangeListener="#{bean.valueChangeListener}">
        <f:selectItem itemValue="1"/>
        <f:selectItem itemValue="2"/>
        <f:selectItem itemValue="3"/>
        <f:selectItem itemValue="4"/>
        <f:selectItem itemValue="5"/>
        <f:selectItem itemValue="" itemLabel="Not specified"/>
    </h:selectOneMenu>
    <h:commandButton value="Submit"/>
</h:form>
</body>
</html>

public class Bean {
    private Long count = null;
    public Long getCount() { return count; }
    public void setCount(Long c) { count = c; }

    public void valueChangeListener(ValueChangeEvent event) {
        System.out.println("valueChangeListener() newValue: " +
event.getNewValue());
    }
}


Mark Collette
http://mark-icefaces-reflections.blogspot.com/