Play Form Scala CI Maven Central

The Rails framework encourages RESTful design of your applications, which means you'll be making a lot of "PATCH", "PUT", and "DELETE" requests (besides "GET" and "POST"). However, most browsers don't support methods other than "GET" and "POST" when it comes to submitting forms.

Rails works around this issue by emulating other methods over POST with a hidden input named "_method", which is set to reflect the desired method:

form_with(url: search_path, method: "patch")

Output:

<form accept-charset="UTF-8" action="/search" data-remote="true" method="post">
  <input name="_method" type="hidden" value="patch" />
  <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
   ...
</form>

When parsing POSTed data, Rails will take into account the special _method parameter and act as if the HTTP method was the one specified inside it ("PATCH" in this example).

Ruby on Rails

Play doesn't offer this feature, but this module does.

Getting Started

To get started you add play-form as a dependency in SBT:

libraryDependencies += "com.github.plippe" %% "play-form" % "2.8.x"

After that you need to configure the request handler inside your application.conf:

play.http.requestHandler = "com.github.plippe.play.form.RequestHandler"

Usage

Use @com.github.plippe.play.form.form instead of @helper.form like the bellow example from Play's documentation.

-@helper.form(action = routes.Application.userPost()) {
+@com.github.plippe.play.form.form(action = routes.Application.userPost()) {
  @helper.inputText(userForm("name"))
  @helper.inputText(userForm("age"))
}

Versioning

Play Form supports several different versions of Play.

Play Form version Play version
2.8.x 2.8.x
2.7.x 2.7.x
2.6.x 2.6.x

Import

To remove the need to write the full package name, you can import the form in your build.sbt:

TwirlKeys.templateImports += "com.github.plippe.play.form.form"

This would simplify the views.

-@helper.form(action = routes.Application.userPost()) {
+@form(action = routes.Application.userPost()) {
  @helper.inputText(userForm("name"))
  @helper.inputText(userForm("age"))
}

Cross Site Request Forgery (CSRF)

By default, Play will require a CSRF check when all of the following are true:

  • The request method is not GET, HEAD or OPTIONS.
  • The request has one or more Cookie or Authorization headers.
  • The CORS filter is not configured to trust the request’s origin.

Play's documentation

If you encounter Unauthorized errors, your request most likely fails the CSRF check. Play's documentation offers a few solutions. I choose the @helper.CSRF.formField in the example project.