Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

f:selectItem's key and value inverted when feeding from a map

In JSF's tag, if you feed it using a Map<Key, Value>

<h:selectOneMenu value="#{bean.integerProperty}">
  <f:selectItems value="#{bean.mapProperty}"/>
</h:selectOneMenu>

The resulting HTML will be the inverse of what one would expect

<select>
  <option selected="selected" value="MapValue1">MapKey1</option>
  <option value="MapValue2">MapKey2</option>
  <option value="MapValue3">MapKey3</option>
</select>

In the sense that the map's value will be set in the option's value attribute and the key will be set in its label.

I found this JIRA JIRA 1808 where the implications of having to write wrong maps are explained (uniqueness, mostly), but don't quite understand why correcting this would be

'disruptive and backwards incompatible'.

Does this come from previous versions of JSF? If so, does anybody know if there's a reason for it to be like this?

Just curious about if there's an explanation not to fix this.

like image 756
comandante N Avatar asked Mar 27 '12 16:03

comandante N


1 Answers

The initial reasoning is after all rather simple: dropdown labels have a greater precedence of to be unique than dropdown values. A dropdown with two same labels would be more a "wtf?" for the enduser than a dropdown with two same values. Map keys ensure uniqueness. I have indeed ever reported the technical unintuitiveness in the issue report which you linked yourself. However, it's a WONTFIX. If it would be changed in JSF 2.2, it wouldn't be backwards compatible anymore with JSF 2.0 / 2.1.

If your environment supports EL 2.2 (Tomcat 7, Glassfish 3, etc), you can easily swap it as follows:

<h:selectOneMenu value="#{bean.integerProperty}">
  <f:selectItems value="#{bean.mapProperty.entrySet()}" var="entry" 
     itemValue="#{entry.key}" itemLabel="#{entry.value}" />
</h:selectOneMenu>

See also:

  • Our <h:selectOneMenu> tag info page
like image 198
BalusC Avatar answered Oct 27 '22 14:10

BalusC