How to specify complex form validations in Play 2?

playframework, playframework-2.0, scala

Solution

You can nest the `mappings`/`tuples` in your form definition and add `verifying` rules on mapping, sub-mapping, tuple and sub-tuple. Then in your templates you can retrieve the errors using `form.errors("fieldname")` for a specific field or a group a fields.

For example :

val signinForm: Form[Account] = Form(
    mapping(
        "name" -> text(minLength=6, maxLength=50),
        "email" -> email,
        "password" -> tuple(
            "main" -> text(minLength=8, maxLength=16),
            "confirm" -> text
        ).verifying(
            // Add an additional constraint: both passwords must match
            "Passwords don't match", password => password._1 == password._2
        )
    )(Account.apply)(Account.unapply)
)

If you have two different passwords, you can retrieve the error in your template using `form.errors("password")`

In this example, you will have to write your own `Account.apply` and `Account.unapply` to handle `(String, String, (String, String))`

Problem

I understand how to add simple form validations in Play 2 such as `nonEmptyText`, but how would I implement more complex validations such as "at least one of the fields must be defined"? Presently I throw an exception in my model object if it gets initialized with all `None`s, but this generates a nasty error message. I would prefer to get a friendly error message on the form page.

Original source