[2.0.1] Form helpers for @ManyToOne-annotated id columns don't show errors

320 views
Skip to first unread message

doctea

unread,
Jun 1, 2012, 6:39:10 AM6/1/12
to play-framework
Hi,

In my form template I have something like:
@select(field = filledForm("client.id"), options =
Client.as_opts, ...)

and in the model I have the 'client' field defined thus:
@ManyToOne
@Required
@Formats.NonEmpty
public Client client;


This mostly works (shows the correctly selected item in the list,
allows you to change it etc) but the form field doesn't show the
errors for the field. A Required error is stored in the Form's errors
list, but as it is stored under the key 'client' and not 'client.id'
the DefaultFieldConstructor does not display it as an error in the
form.

Anyone got a workaround or a fix for this? Happy to have a go at it
myself but I've spent a couple of days scratching my head over this
and haven't really gotten anywhere yet so could do with some pointers,
thanks!

Kevin Bosman

unread,
Jun 3, 2012, 9:04:05 AM6/3/12
to play-fr...@googlegroups.com
> Anyone got a workaround or a fix for this?  Happy to have a go at it
> myself but I've spent a couple of days scratching my head over this
> and haven't really gotten anywhere yet so could do with some pointers,
> thanks!

If you create a formatter (see play.data.format.Formatters) for your lookup model type (in your case, for your "Client" model), you can refer to the field name directly in your select helper, instead of referencing it by its id. This bypasses the need to solve the apparent problem.

example:

public class Client extends DoctuaAuditingModel {

static {
play.data.format.Formatters.register(Client.class, new ClientFormatter());
}

public static class ClientFormatter extends SimpleFormatter<Client> {

@Override
public Client parse(String text, Locale locale) {
if (text == null || text.trim().length() == 0)
return null;
return Client.find.byId(Long.parseLong(text.trim()));
}

@Override
public String print(Client value, Locale locale) {
return (value == null || value.id == null ? "" : value.toString());
}
}

@Id
public Long id;

...

}

Then in your select helper you'd simply reference it like this:
@select(filledForm("client"), options = ...)

Kevin Bosman

unread,
Jun 3, 2012, 12:47:52 PM6/3/12
to play-fr...@googlegroups.com
> public String print(Client value, Locale locale) {
return (value == null || value.id == null ? "" : value.toString());
> }

My apologies, the print() function above needs to convert the id value back to a string, so in the absence of an overriding Client.toString() method, it should probably more generically read as follows:

public String print(Client value, Locale locale) {
return (value == null || value.id == null ? "" : value.id.toString());
}

doctea

unread,
Jun 6, 2012, 11:51:07 AM6/6/12
to play-framework
Thank you. This seems to work perfectly!
> return (value == null || value.id == null ? "" : value*.id*.toString());
>
>
>
>
>
>
>
> }
Reply all
Reply to author
Forward
0 new messages