§Handling form submission
§Defining a form
The play.data
package contains several helpers to handle HTTP form data submission and validation. The easiest way to handle a form submission is to define a play.data.Form
that wraps an existing class:
public class User {
public String email;
public String password;
}
Form<User> userForm = form(User.class);
Note: The underlying binding is done using Spring data binder.
This form can generate a User
result value from HashMap<String,String>
data:
Map<String,String> anyData = new HashMap();
anyData.put("email", "[email protected]");
anyData.put("password", "secret");
User user = userForm.bind(anyData).get();
If you have a request available in the scope, you can bind directly from the request content:
User user = userForm.bindFromRequest().get();
§Defining constraints
You can define additional constraints that will be checked during the binding phase using JSR-303 (Bean Validation) annotations:
public class User {
@Required
public String email;
public String password;
}
Tip: The
play.data.validation.Constraints
class contains several built-in validation annotations.
You can also define an ad-hoc validation by adding a validate
method to your top object:
public class User {
@Required
public String email;
public String password;
public String validate() {
if(authenticate(email,password) == null) {
return "Invalid email or password";
}
return null;
}
}
Since 2.0.2 the validate
-method can return the following types: String
, List<ValidationError>
or Map<String,List<ValidationError>>
§Handling binding failure
Of course if you can define constraints, then you need to be able to handle the binding errors.
if(userForm.hasErrors()) {
return badRequest(form.render(userForm));
} else {
User user = userForm.get();
return ok("Got user " + user);
}
§Filling a form with initial default values
Sometimes you’ll want to fill a form with existing values, typically for editing:
userForm = userForm.fill(new User("[email protected]", "secret"))
Tip:
Form
objects are immutable - calls to methods likebind()
andfill()
will return a new object filled with the new data.
§Handling a form that is not related to a Model
You can use a DynamicForm
if you need to retrieve data from an html form that is not related to a Model
:
public static Result hello(){
DynamicForm requestData = form().bindFromRequest();
String firstname = requestData.get("firstname");
String lastname = requestData.get("lastname");
return ok("Hello " + firstname + " " + lastname);
}
§Register a custom DataBinder
In case you want to define a mapping from a custom object to a form field string and vice versa you need to register a new Formatter for this object.
For an object like JodaTime’s LocalTime
it could look like this:
Formatters.register(LocalTime.class, new SimpleFormatter<LocalTime>() {
private Pattern timePattern = Pattern.compile(
"([012]?\\\\d)(?:[\\\\s:\\\\._\\\\-]+([0-5]\\\\d))?"
);
@Override
public LocalTime parse(String input, Locale l) throws ParseException {
Matcher m = timePattern.matcher(input);
if (!m.find()) throw new ParseException("No valid Input",0);
int hour = Integer.valueOf(m.group(1));
int min = m.group(2) == null ? 0 : Integer.valueOf(m.group(2));
return new LocalTime(hour, min);
}
@Override
public String print(LocalTime localTime, Locale l) {
return localTime.toString("HH:mm");
}
});