Thymeleaf(+ Spring MVC) におけるフォーム
各フォーム部品におけるThymeleafのタグの使い方。th:fieldが中心だが部品の特性によって差はあるのでメモ。
Table of Contents
この記事は最終更新から3年以上経過しています。
執筆時バージョン
Java | Java SE 8 |
概要
Spirng MVCとThymeleafでフォームを生成する場合は「th:field」を中心に考える。「th:field」を指定すればidやname属性などを生成や、戻る遷移時のvalue設定なども行ってくれる。
ファイル選択フォームについては次のページを参照。→こちら
サンプルについて
サーバー側では次のようにフォームやenumを設定する。
例で使用するフォーム
@Data
public class SimpleInputForm {
String name;
String[] favariteMovies;
String fisrtMovie;
String secondMovie;
}
例で使用するenum
@AllArgsConstructor
@Getter
public enum Movie {
スターウォーズ("star-wars", "スターウォーズ"),
ローマの休日("roman-holiday", "ローマの休日"),
トイストーリー("toy-story", "トイ・ストーリー");
private final String code;
private final String label;
}
enumはvalues()を使って渡す
model.addAttribute("movies", Movie.values());
フォームの生成
テキスト
th:fieldを指定すればid,name,valueの設定をしてくれる。
thymeleaf
<form method="post" action="#" th:action="@{./confirm}" th:object="${form}">
<input type="text" th:field="*{name}" />
</form>
生成されるhtml
<form method="post" action="./confirm">
<input type="text" class="form-control" id="name" name="name" value="" />
</form>
チェックボックス
Listやenumから生成する場合でもth:fieldを使える。th:valueを設定しておけば、その値と一致している場合にchecked="checked"が付与される。valueがonのhiddenフィールドも生成されるが、これはチェックを外したときに値を送らない対策。
labelとidの生成については、#idsユーティリティが便利。labelの位置が前か後ろかによって「prev」「next」を使い分ける。
thymeleaf
<form method="post" action="#" th:action="@{./confirm}" th:object="${form}">
<ul>
<li th:each="movie : ${movies}">
<input type="checkbox" th:field="*{favariteMovies}" th:value="${movie.code}" />
<label th:for="${#ids.prev('favariteMovies')}" th:text="${movie.label}">映画名</label>
</li>
</ul>
</form>
生成されるhtml
<form method="post" action="./confirm">
<ul>
<li>
<input type="checkbox" value="star-wars" id="favariteMovies1" name="favariteMovies" />
<input type="hidden" name="_favariteMovies" value="on" />
<label for="favariteMovies1">スターウォーズ</label>
</li>
<li>
<input type="checkbox" value="roman-holiday" id="favariteMovies2" name="favariteMovies" />
<input type="hidden" name="_favariteMovies" value="on" />
<label for="favariteMovies2">ローマの休日</label>
</li>
<li>
<input type="checkbox" value="toy-story" id="favariteMovies3" name="favariteMovies" />
<input type="hidden" name="_favariteMovies" value="on" />
<label for="favariteMovies3">トイ・ストーリー</label>
</li>
</ul>
</form>
ラジオ
考え方はチェックボックスと一緒。
thymeleaf
<form method="post" action="#" th:action="@{./confirm}" th:object="${form}">
<ul>
<li th:each="movie : ${movies}">
<input type="radio" th:field="*{fisrtMovie}" th:value="${movie.code}" />
<label th:for="${#ids.prev('fisrtMovie')}" th:text="${movie.label}">映画名</label>
</li>
</ul>
</form>
生成されるhtml
<form method="post" action="./confirm">
<ul>
<li>
<input type="radio" value="star-wars" id="fisrtMovie1" name="fisrtMovie" />
<label for="fisrtMovie1">スターウォーズ</label>
</li>
<li>
<input type="radio" value="roman-holiday" id="fisrtMovie2" name="fisrtMovie" />
<label for="fisrtMovie2">ローマの休日</label>
</li>
<li>
<input type="radio" value="toy-story" id="fisrtMovie3" name="fisrtMovie" />
<label for="fisrtMovie3">トイ・ストーリー</label>
</li>
</ul>
</form>
セレクト(ドロップダウン)
selectタグのth:fieldとoptionタグのth:valueが一致するとselectedを付与する。
thymeleaf
<form method="post" action="#" th:action="@{./confirm}" th:object="${form}">
<select th:field="*{secondMovie}">
<option th:each="movie : ${movies}" th:value="${movie.code}" th:text="${movie.label}">映画名</option>
</select>
</form>
生成されるhtml
<form method="post" action="./confirm">
<select id="secondMovie" name="secondMovie">
<option value="star-wars">スターウォーズ</option>
<option value="roman-holiday">ローマの休日</option>
<option value="toy-story">トイ・ストーリー</option>
</select>
</form>
Appendix A: 参考
Appendix B: 改訂履歴
-
v1.0, 2016-09-01: 初稿