LoginSignup
13
8

More than 5 years have passed since last update.

PlayFrameworkのformでいろいろ試してみた。

Last updated at Posted at 2017-11-24

普通にFormクラスを利用してのやり方と、やってみたらできたことをメモ。
ちなみにJavaでの開発です。

version

2.5.10


まずはフォームクラスを作成。

UserForm.java
public class UserForm{

    @Required(message="名前を入力してください")
    public String name;

    @Required(message="メールアドレスを入力してください")
    public String email;

    @Required(message="電話番号を入力してください")
    @Pattern(regexp = "^(070|080|090)-\\d{4}-\\d{4}$",message="電話番号の形式で入力してください")
    public String telephone;
}

入力されるフィールドとValidationを設定します。

次にコントローラー作成。

FormController.java
package controllers

import com.google.inject.Inject;
import UserForm;
import play.data.Form;
import play.data.FormFactory;
import play.mvc.Controller;
import play.mvc.Result;

public class FormController extends Controller{
    //フォームフィールドを用意
    private Form<UserForm> form;

    //コンストラクタでフォームを生成
    @Inject
    public UserController(FormFactory formFactory) {
        this.form = formFactory.form(UserForm.class);
    }

    //フォームを表示するメソッド
    public Result showForm() {
        return ok(form.render(form));
    }

    //submitで呼ばれるメソッド
    public Result submit() {
        Form<UserForm> userForm = form.bindFromRequest();
        //エラー時にフォームに戻す
        if(userForm.hasErrors()){
            return badRequest(form.render(userForm));
        }

        UserForm user = userForm.get();
        return result.render(user);
    }
}

フォーム表示の際はコンストラクタでフォームを作ってviewに渡してあげます。

次にroutesも設定しましょう。

#フォーム表示
GET    /           controllers.FormController.showForm

#submit
POST   /submit     controllers.FormController.submit

続いてviewの作成。helper内では制限があると思っていましたが普通にもできた!

form.scala.html
@(form: Form[UserForm])
@main(){
    @form.helper(@routes.FormController.submit){

        @(helper.inputText(form("name")))

        @(helper.inputText(form("email")))

        <!-- あとは省略 -->
    }
}

上記な感じでフォームができますが、このhelperの記述だとレンダリングされて出てくるformの形が決まっていてちょっと使いづらいなーと。
ちなみに上記でレンダリングされてくるのはこんなん。

<dl class="" id="input_field>
    <dt><lavel for="input">name</label></dt>
    <dd>
        <input type="text" id="name" name="name" value="">
    </dd>
    <!-- エラー検出時はこれが出ます
    <dd class="error">This field is required!</dd>
    <dd class="error">Another error</dd> -->
    <!-- 入力制限に応じて出ます
    <dd class="info">Required</dd>
    <dd class="info">Another constraint</dd> -->
</dl>

<dl class="" id="input_field>
    <dt><lavel for="input">email</label></dt>
    <dd>
        <input type="text" id="email" name="email" value="">
    </dd>
    <!-- <dd>省略 -->
</dl>

フィールドコンストラクタの自作でいじれるみたいですが、Scalaは全然触ったことないこともあり、別の方法でもっと自由にフォーム画面作りたいなーと思って、helperの中で普通に書いてみたらできました。

form.scala.html
@(form: Form[UserForm])
@main(){
    @form.helper(@routes.FormController.submit){

        @if(form.error("name") != null){
            @form.error("name").message()
        }
        名前:<input type="text" name="name">
        <br>
        @if(form.error("email") != null){
            @form.error("email").message()
        }
        Email:<input type="email" name="email">
        <!-- あとは省略 -->
    }
}

上記でもちゃんと動きました。
ただし、helperでの自動生成にたよらず自分で作成するのでエラーメッセージの表示なんかも自分で記述しなければなりません。


フォームクラスのアノテーションだけではなく、自分でValidationを作成することもできました。

Controllerのsubmitメソッドで下記

FormController.java
    public Result submit() {
        Form<UserForm> userForm = form.bindFromRequest();
        //nameの入力値が「aaa」の時にエラーを出す
        if("aaa".equals(equserForm.get().name)){
            ValidationError error = 
                new ValidationError("error", "この名前は使えません。", new ArrayList<>());
            List<ValidationError> errors = new ArrayList<>();
            errors.add(error);
            registerForm.errors().put("nameError", errors);
            return badRequest(form.render(userForm));
        }
    }

ValidationErrorオブジェクトを作成してFormにつめる感じです。

viewでのエラーの呼び出し

form.scala.html
@if(form.error("nameError") != null){
    @form.errors().get("nameError").get(0).message()
}

こんな感じで表示させることができました。

フィールドコンストラクタも是非使いこなしてみたいところです。


追記

上記のバリデーションの追加は下記で簡単にできた。

FormController.java
    public Result submit() {
        Form<userForm> userForm = form.bindFromRequest();
        if("aaa".equals(equserForm.get().name) {
            userForm.reject("nameError", "この名前は使えません");
            return badrequest(form.render(userForm));
        }
    }

呼び出し

form.scala.html
    @if(form.error("nameError") != null){
        @form.error("nameError").message()
    }

こっちの方が圧倒的に楽。
Formはよく見てみるとちゃんと色々用意されてました。

13
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
8