This is a study note for Play Forms.

1 Overview

Play binds a POST request with a Form object, creates a case class instance and call custom validations. The related imports are

1
2
3
import play.api.data._
import play.api.data.Forms._
import play.api.data.validation.Constraints._

Using forms involves the following steps.

2 Defining a Form

First define a case class which contains the elements of the form. Then define a Form object with the Forms.mapping method. The method takes the names and constraints of the form, and two functions: apply and unapply of the case class. The mapping supports up to 22 fields.

Alternatively, you can use Forms.tuple or Forms.single to define tuples or a single value.

A form mapping can define nest balues by using Forms.mapping inside an existing mapping. For repeated values, using Forms.list or Forms.seq.

1.2 Defining Constraints

Play has the following out of the box constraints:

  • text: scala.String with optional minLength and maxLength
  • nonEmptyText: non-empty text
  • number: scala.Int with optonal min, max and strict
  • longNumber: scala.Long with optonal min, max and strict
  • bigDecimal: takes precision and scale
  • date, sqlDate: maps to java.util.Date, java.sql.Date, optionally takes pattern and timeZone
  • email: scala.String, using an email regular expression
  • boolean, checked: maps to scala.Boolean
  • optional: maps to scala.Option
  • seq and list: for collection of items

Use play.api.data.validation.Constraint to define ad-hoc constraints. Or define constraints on the case class with the verfiying method.

3 Validating a Form in an Action

The Form.bindFromRequest.fold() method takes two functions: one for binding failure and one for binding success. It is common to use BadRequest for the error case and use Redirect for the success case.

An alternative way is to use parse.form body parser to handle the form request.

4 Displaying Forms

To display a form, passing a form parameter to the view template. In the view template, use @helper.form(action= routes.path.method()){...} to define a view. The views.html.helper package defines many input helpers including form, inputText, inputPassword, inputDate, inputFile, inputRadioGroup, select, textarea, checkbox, and input.

The form helpers take MessageProvider as an implicit parameter to provide error messages for a language defined in the request.

To display repeated values, using @helper.repeat or @helper.repeatWithIndex.

Use Forms.optonal to diesplay option value.

Use Form.fill() or Forms.default() to fill initial value.

For static value, use Forms.ignored().

5 Custom Binder for Form Mapping

Each form mapping uses an implicit Formatter[T] binder object that converts th string to/from the target data type.

6 Protecting CSRF

Since Play 2.6, the CSRF filter is applied automatically. To disable it for a specific route, add + nocsrf to a route.

All actions that need to access the CSRF token uses an implicit request. In view template, the CSRF.formField requires an implicit RequestHeader parameter or an implicit MessagesRequestHeader.

Uses @CSRF.formField to a form in view template.