Help us understand the problem. What is going on with this article?

Play Framework 2.6(Scala)でFormの処理を作ってみた

More than 1 year has passed since last update.

概要

ScalaのPlay Frameworkで手始めにForm処理を一つ作ってみようとしたら、ネットにあるサンプルソースから仕様が意外に変わっていたので、2.6時点での作成方法を情報整理をしてみました。

前提

ログイン画面をイメージしてFormの処理を作ってみました。気づいた点やはまった点を、ソースを交えて記載しています。

サンプルソース

【routesファイル】

GET     /      controllers.LoginController.loginInit
GET     /login controllers.LoginController.loginInit
POST    /login controllers.LoginController.loginSubmit

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file controllers.Assets.versioned(path="/public", file: Asset)

【models】

models.scala
package models

case class LoginUser(
    userid:String, 
    userpw:String); 

【controllers】

LoginController.scala
package controllers

import javax.inject._
import play.api._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import models._
import play.api.data.validation.Valid
import play.api.data.validation.Constraint
import play.api.data.validation.Invalid
import play.api.i18n.I18nSupport

@Singleton
class LoginController @Inject()(cc: ControllerComponents) extends AbstractController(cc) with I18nSupport {

  // ログインフォーム
  // 空白チェックにオリジナルメッセージを設定してみる
  val loginUserForm = Form( mapping("userid" -> text.verifying("ユーザIDを入力してください" , {!_.isEmpty()}) , 
                                    "userpw" -> text.verifying("パスワードを入力してください" , {!_.isEmpty()})
                                    )
                                    (LoginUser.apply)(LoginUser.unapply) 
                           )

  // ログイン画面の初期表示
  def loginInit() = Action { implicit request =>
     Ok( views.html.login(loginUserForm) )
  }

  // ログイン画面のSubmit
  def loginSubmit() = Action { implicit request: Request[AnyContent] =>
     loginUserForm.bindFromRequest.fold(
         // 入力チェックNG
         errors => {           
           BadRequest( views.html.login(errors) )
         },
         // 入力チェックOK
         success => {
           val loginUser = loginUserForm.bindFromRequest.get
           Ok( views.html.loginSuccess() )
         }        
     )
  }

}

Controllerの作成にあたってまず留意すべきことは、こちらのstackoverflowの記事より、2.6からクラスの継承に必要なものが変わった点です。
あと、これは別に2.6だからということではないのですが、空白チェックにあえてverifyingを使って試しにオリジナルのメッセージを設定してみました。また、入力チェックの詳細についてはPlayframework 2.0(Scala)でサンプルアプリケーション作成-3.メッセージの国際化(i18n)対応が参考になります。

【view】

login.scala.html
@(loginUserForm : Form[LoginUser])(implicit request: RequestHeader, messagesProvider: MessagesProvider)
@import helper._
@main("サンプル"){
    <font size=5>■ログイン画面</font><br/>
    @helper.form( action = helper.CSRF(routes.LoginController.loginSubmit) ){
        <fieldset>
          @helper.inputText(loginUserForm("userid") , '_label -> "ログインID")
          @helper.inputPassword(loginUserForm("userpw") , '_label -> "パスワード")
        </fieldset>
        <input type="submit" value="ログイン">
    }
}
loginSuccess.scala.html
@import helper._
@main("サンプル"){
    <font size=5>■ログイン成功</font>
}

まず、冒頭のimplicit parameterです。こちらのstackoverflowの記事によると、これがないと2.6ではコンパイルエラーになるそうです。
また、2.6では初期設定ではCSRFの設定がONになっているので、こちらのstackoverflowの記事によると、actionでCSRFのメソッドを使う必要があるとのこと。
また、2.6というわけではないですが、フィールドコンストラクタがviewのヘルパーの引数に設定できるので、フォームテンプレートヘルパーの利用を参考に試しに設定してみました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away