Thymeleafでチェックボックスを使ったときに少しハマったポイントをまとめてみました!
一般的にはth:field
にプロパティを指定して出力させることが多いと思います。
th:object
でBeanを指定していれば自動でバインドされるので、単純に出力するだけであれば一番手っ取り早くて簡単にチェック状態を保持することもできます。
th:fieldを使う場合
th:object
で指定しているBeanの中で定義されているプロパティを指定し、チェックボックスとして出力することができます。
一番大きなポイントとしてはチェックボックスを出力するのと同時に、パラメータ名の先頭にアンダースコアが付いた形でhiddenを出力することです。
hiddenで出力されているパラメータがチェックボックスを選択していない状態でも送信されることで、Spring側がfalseとしてハンドリングするようになっています。
(ちなみにJSPでSpringのタグライブラリを使用した際も同様なので、Spring Frameworkの仕様が影響しているような気がします)
実際に型別で2パターンほど出力してみるとこんな感じになります。
■booleanのプロパティを使って出力する場合
<input type="checkbox" th:field="*{checkBoo}">
※実際に出力されるHTML
<input type="checkbox" id="checkBoo1" name="checkBoo" value="true">
<input type="hidden" name="_checkBoo" value="on">
■Stringのプロパティを使って出力する場合
<input type="checkbox" th:field="*{checkStr}" th:value="on" >
※実際に出力されるHTML
<input type="checkbox" value="on" id="checkStr1" name="checkStr">
<input type="hidden" name="_checkStr" value="on">
新規で開発を行う場合はこのような一般のお作法通りに記述することで問題なく動作できるかと思います。
しかし、別のフレームワークからマイグレーションする際などは元の仕様が異なることもあり、hiddenが出力されてfalseとして扱われると困ることがありそうです。
自動でhiddenが出力されないようにするには?
結論としてはth:field
の使用を避けるのが一番です。
単純にname属性を使うようにしてもチェックボックスとしての役割は果たすことができます。
ただ、hiddenが出力されなくなったかわりにth:field
が自動で行っていたチェック状態を判定ができなくなってしまいます。
(th:object
に指定したBeanのプロパティをバインドしなくなるため)
多少冗長にはなりますが、別の方法で判定してチェック状態を保持することは可能です。
■booleanのプロパティを使って出力する場合
<form th:action="@{/check}" th:object="${form}" method="POST">
<input type="checkbox" name="checkBoo" th:checked="${form.checkBoo}">
</form>
※実際に出力されるHTML
<form action="/context-path/check" method="POST">
<input type="checkbox" name="checkBoo" checked="checked">
</form>
■Stringのプロパティを使って出力する場合
<form th:action="@{/check}" th:object="${form}" method="POST">
<input type="checkbox" name="checkStr" th:value="on" th:checked="${form.checkStr eq 'on'}">
</form>
※実際に出力されるHTML
<form action="/context-path/check" method="POST">
<input type="checkbox" name="checkStr" value="on" checked="checked">
</form>
上記の例だと、型がbooleanの場合はtrueではないとき・Stringの場合はvalue属性に指定した値ではないときは、当然checked属性が出力されないように判定してくれます。
必要に応じてこういった書き方も使っていくのが良いと思います。
まとめ
書き方によってはチェックボックスを選択してない状態でも値がPOSTされることになるので、内部の実装によっては影響があります。
自分自身が遭遇したパターンとしては、hiddenで送られたパラメータがStringの型変換(Converter)カスタマイズ実装に影響を及ぼしていたことがありました。
Webアプリケーションを作っていく上では一部の話ですが、知っておくと得する内容だと思います。
Thymeleafの豆知識として参考になれば幸いです。
参考