schmmd
schmmd

Reputation: 19448

How to specify complex form validations in Play 2?

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 Nones, but this generates a nasty error message. I would prefer to get a friendly error message on the form page.

Upvotes: 10

Views: 2674

Answers (3)

Chris Dail
Chris Dail

Reputation: 26029

I have improved upon @kheraud's accepted answer. You can take the tuple and transform it back to a single string. This allows you to use the default apply/unapply functions.

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
        ).transform(
            { case (main, confirm) => main },
            (main: String) => ("", "")
        )
    )(Account.apply)(Account.unapply)
)

Upvotes: 7

kheraud
kheraud

Reputation: 5288

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))

Upvotes: 9

Alpay
Alpay

Reputation: 1368

In Play! Framework, you can show friendly error messages by the use of flash variable. You just need to write something like;

flash.error("Oops. An error occurred");

to your controller. Where this error message will reside on the html page should be set with for example;

<h1>${flash.error}</h1>

Play! Framework will put the error message where it finds this ${flash.error} thing.

Upvotes: 0

Related Questions