Monday, 30 June 2014

Problem with JSF h:selectOneMenu and dates

While implementing pages in JSF you will often encounter silly problems which may take hours to solve. The longest it takes to find solution, the stupidest problem usually is. This is one of such situations.

What I tried to accomplish was to put a list of dates into h:selectOneMenu (or h:selectOneListbox) tag as an options. Date selection should be submitted on change. The initial code looked like this:

dateFormats.toShort() is just a simple utility method which turns date into a string having format: "dd/MM/yyyy". The code above sort of worked i.e. it rendered ok and dates were formatted nicely. The only problem was that when I selected a date the value was not submitted. To be precise: date options were not submitted, null option was. Though there were no errors or warnings in logs it was pretty obvious that there is something wrong with date options.

After a few hours of playing around I’ve found a solution:

It looks like the only way to make h:selectOneMenu work with dates is to transform date options into strings (itemValue="#{dateFormats.toShort(date)}") and then transform selected option back to date (<f:convertdatetime pattern="dd/MM/yyyy">). Please note that the pattern used by date converter MUST be the same as format of the value in itemValue attribute (in our case it’s "dd/MM/yyyy").

The general lesson which comes with this story is the following: if you use h:selectOneMenu with options which are not one of primitive data types (or can be easily transformed to ones like Long, Integer etc.) you have to use converters!