普通にFormクラスを利用してのやり方と、やってみたらできたことをメモ。
ちなみにJavaでの開発です。
#version
2.5.10
まずはフォームクラスを作成。
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を設定します。
次にコントローラー作成。
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: 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: 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メソッドで下記
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でのエラーの呼び出し
@if(form.error("nameError") != null){
@form.errors().get("nameError").get(0).message()
}
こんな感じで表示させることができました。
フィールドコンストラクタも是非使いこなしてみたいところです。
###追記
上記のバリデーションの追加は下記で簡単にできた。
public Result submit() {
Form<userForm> userForm = form.bindFromRequest();
if("aaa".equals(equserForm.get().name) {
userForm.reject("nameError", "この名前は使えません");
return badrequest(form.render(userForm));
}
}
呼び出し
@if(form.error("nameError") != null){
@form.error("nameError").message()
}
こっちの方が圧倒的に楽。
Formはよく見てみるとちゃんと色々用意されてました。