Play Framework 2.1のちょっとした新機能
実はPlay Framework 2.0.xのFormでは同じフィールド名で複数値を受け取ることができない。
<input type="checkbox" name="name" value="value1"> <input type="checkbox" name="name" value="value2"> <input type="checkbox" name="name" value="value3">
例えば、上のようなフォームがあったとして、全てにチェックを入れても一つしか値は格納されない(多分name=value3しか入らない。もしかしたらvalue1かも)。
正確に書くと、request.body.asFormUrlEncodedの時点ではMap[String, Seq[String]]としてちゃんと格納されているのでこれを直接参照すれば"(name -> Seq(value1, value2, value3))"が得られるのだが、form.bindFromRequest()した瞬間に内部的にMap[String, String]に変換され、(name -> value3)となってしまう…。
POSTパラメータ | name=value1&name=value2&name=value3 |
---|---|
request.body.asFormUrlEncoded | Map(name -> Seq(value1, value2, value3)) |
bindFromRequestした際の内部的なデータ | Map(name -> value3) |
一応、以下のようにフィールド名に"[番号]"をつけてあげれば複数の値を取得することができる。
<input type="checkbox" name="name[0]" value="value1"> <input type="checkbox" name="name[1]" value="value2"> <input type="checkbox" name="name[2]" value="value3">
コントローラ側の例
case class AddForm(val name: List[String]) val addForm = Form( mapping( "name" -> list(text) )(AddForm.apply)(AddForm.unapply) )
チェックボックスならこれで解決だが、複数選択可能なセレクトボックス(multiple要素をつけたselect)だとお手上げ。(どう転んでもnameは1つしか指定できないので)
しかし、Play Framework 2.1はこれが改善されており、末尾が"[]"で終わるフィールド名は自動的にname[0], name[1]に変換されるようになった!
POSTパラメータ | name=value1&name=value2&name=value3 |
---|---|
request.body.asFormUrlEncoded | Map(name -> Seq(value1, value2, value3)) |
bindFromRequestした際の内部的なデータ | Map(name[0] -> value1, name[1] -> value2, name[2] ->value3) |
↑こんな感じに保存されてる
これで、mappingのlistが使い物になる!やったー (2.0.xでもやってほしい…)