[play-framework] Selecting blank choice for Enum

50 views
Skip to first unread message

Dave Cheong

unread,
May 11, 2010, 10:02:18 AM5/11/10
to play-framework
Hi all,

I have a simple model Flight which has a property "origin" which is a
simple enum of type City.

@Entity
public class Flight extends Model {

@Required
@Enumerated(EnumType.STRING)
public City origin;

}

I would like to present the user with a blank choice which would
nullify this property.

So either

#{field 'flight.origin'}
#{select field.name, id:'origin', value:flight.origin}
#{option}-Choose-#{/option}
#{list cities, as:'city'}
#{option city}${city.label}#{/option}
#{/list}
#{/select}
#{/field}

or

#{field 'flight.origin'}
<select id="origin" name="${field.name}">
<option value="" ${flight.origin == null ? 'selected' : ''}>-
Choose-</option>
#{list cities, as:'city'}
<option value="${city}" ${flight.origin == city ? 'selected' :
''}>${city.label}</option>
#{/list}
</select>
#{/field}

However, in both cases, when editing an instance of Flight which has
this value populated initially, selecting the blank option doesn't get
bound.

I've traced the problem to Binder:

if (Enum.class.isAssignableFrom(clazz)) {
if (value == null || value.length == 0 ||
StringUtils.isEmpty(value[0])) {
return MISSING;
}
return Enum.valueOf(clazz, value[0]);
}

And then subsequently BeanWrapper:

Object value = Binder.bindInternal(name, prop.getType(),
prop.getGenericType(), params, newPrefix);
if (value != Binder.MISSING) {
prop.setValue(instance, value);
}

As the field value submitted is blank, the Binder reports it as
MISSING and the BeanWrapper skips it.

What is the recommended way of clearing an Enum other than creating an
explicit Enum value to represent blank or providing my own Binder/
Plugin implementation.

Any help provided is much appreciated.

Thanks,
dave

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.

Guillaume Bort

unread,
May 11, 2010, 2:31:54 PM5/11/10
to play-fr...@googlegroups.com
Why don't you define a value for BLANK in your enum? The cool thing
about enum is they are typed. If you set it to null it doesn't mean
anything.

Dave Cheong

unread,
May 11, 2010, 5:44:41 PM5/11/10
to play-framework
I could, but null is a valid case too.

Wouldn't BeanWrapper be better to loop through the params map instead
of all the properties of the bean? This way we could distinguish
between an empty string and the case of a property wasn't submitted
via the web form?

So <input name="origin" value=""/> or <option value=""/> would be
different from simply not posting "origin" in the web form?

The other thing about having a BLANK enum value is if we wanted to
omit printing BLANK in a table of search results, we'd have to check
for it explicitly, which is additional code vs simply printing $
{flight.origin} or ${flight.origin?.label}.

thanks,
dave
> > For more options, visit this group athttp://groups.google.com/group/play-framework?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To post to this group, send email to play-fr...@googlegroups.com.
> To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
> For more options, visit this group athttp://groups.google.com/group/play-framework?hl=en.

Dave Cheong

unread,
May 11, 2010, 6:59:55 PM5/11/10
to play-framework
Could the simplest solution to this problem be:

if (Enum.class.isAssignableFrom(clazz)) {
if (value == null) {
return null;
}
else if (value.length == 0 ||
StringUtils.isEmpty(value[0])) {
return MISSING;
}
return Enum.valueOf(clazz, value[0]);
}

Thoughts?

dave

Guillaume Bort

unread,
May 12, 2010, 5:43:12 AM5/12/10
to play-fr...@googlegroups.com
Yes it should be like that. What version are you using?

Dave Cheong

unread,
May 12, 2010, 8:35:26 AM5/12/10
to play-framework
Oops, got the logic round the wrong way:

            if (Enum.class.isAssignableFrom(clazz)) {
                if (value == null) {
                    return MISSING;
                }
                else if (value.length == 0 ||
StringUtils.isEmpty(value[0])) {
                    return null;
                }
                return Enum.valueOf(clazz, value[0]);
            }

I'm using 1.0.2.1.

dave

Guillaume Bort

unread,
May 12, 2010, 1:33:10 PM5/12/10
to play-fr...@googlegroups.com
Ok please report the bug, we will fix it in the 1.0.3

Dave Cheong

unread,
May 13, 2010, 8:42:50 AM5/13/10
to play-framework
Hi Guillaume,

I have opened a bug report for this:

https://bugs.launchpad.net/play/+bug/579945

dave
Reply all
Reply to author
Forward
0 new messages