Thymeleafのth:checkedの使い方!チェックボックスON/OFFを動的に制御する方法
生徒
「Thymeleafでチェックボックスを使いたいのですが、Javaのデータによってチェックを入れるにはどうすればいいですか?」
先生
「Thymeleafではth:checkedという属性を使うと、Javaで設定した条件によってチェックボックスにチェックを入れることができますよ。」
生徒
「そのth:checked属性はどんなときに使われますか?」
先生
「例えば、プロフィール設定で「メールを受け取る」チェックを設定する場合や、フォームの更新画面で元々の設定に基づいてチェック状態を維持する際に便利ですね。」
1. th:checkedとは?
th:checkedは、ThymeleafでチェックボックスのON/OFFを「その場で評価した条件」に合わせて切り替えるための属性です。通常のHTMLではcheckedを直接書くと常に固定でONになりますが、th:checkedなら${...}に書いた式(モデルに入れたブール値や比較結果)がtrueのときだけチェックが入ります。言い換えると、テンプレート側の一行で「表示時に正しい状態へ自動反映」できます。
たとえば「お知らせメールを受け取る」のように、ユーザー設定や既存データを初期表示へそのまま映したい場面で便利です。プログラミング未経験でも、「trueなら入る、falseなら外れる」という素直な挙動と覚えておくと扱いやすく、フォームの見た目と実際の値がズレにくくなります。
※ 実務では${...}の中にコントローラーで用意した値を入れます。ここでは雰囲気をつかむため、固定の式を使っています。
<!-- true なのでチェックONで表示される -->
<input type="checkbox" th:checked="${true}"> 受け取る
<!-- 比較式:年齢が18以上ならチェックON -->
<input type="checkbox" th:checked="${18 >= 18}"> 成人向けの案内を表示
上の例では、最初の行は常にON、二つ目は比較がtrueになるためONで表示されます。実際は${receiveNewsletter}のようにモデルの値を差し替えるだけで、同じ書き方で動的にON/OFFを切り替えられます。
2. th:checkedの基本的な使い方
ここでは「コントローラーで用意した値」をテンプレートのチェックボックスに反映する最短手順を確認します。流れはシンプルで、(1) Javaでブール値をModelに入れる → (2) HTMLでth:checkedにその値(または式)を書く、の2ステップだけです。
// Controller: 値をModelへ入れる基本形
@Controller
public class UserSettingsController {
@GetMapping("/settings")
public String userSettings(Model model) {
boolean receiveNewsletter = true; // 初期表示でONにしたい例
model.addAttribute("receiveNewsletter", receiveNewsletter);
// ついでに別パターン(オフにしたい例)
boolean showTips = false;
model.addAttribute("showTips", showTips);
return "userSettings"; // userSettings.html を表示
}
}
次に、テンプレート側でth:checkedを使います。${...}にtrue/falseが入れば、その結果に応じてON/OFFが自動で切り替わります。
<!-- userSettings.html:モデルの値をそのまま使う例 -->
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="receive" th:checked="${receiveNewsletter}">
<label class="form-check-label" for="receive">メールを受け取る</label>
</div>
<!-- false なので初期表示はOFFになる例 -->
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="tips" th:checked="${showTips}">
<label class="form-check-label" for="tips">ヒントを表示する</label>
</div>
<!-- 簡単な式もOK(trueならON):比較や否定もそのまま書ける -->
<div class="form-check">
<input class="form-check-input" type="checkbox" id="example" th:checked="${!showTips}">
<label class="form-check-label" for="example">サンプル:否定でONにする</label>
</div>
ポイントは「th:checkedは${...}の結果がtrueならチェックON」という一点です。未経験の方は、まずブール値(真偽値)をModelに入れてみて、${値}/${!値}と書き分けるところから始めると、画面の状態を直感的にコントロールできます。
3. th:checkedを使った実用例:ユーザープロフィール設定
さらに、複数の設定項目にth:checkedを活用する例を紹介します。以下のコードでは、ユーザーの「プッシュ通知」や「メール通知」の設定を管理するフォームを作成します。コントローラーから複数の設定をModelに渡し、それぞれのチェックボックスに動的に反映させます。
@Controller
public class NotificationController {
@GetMapping("/notificationSettings")
public String notificationSettings(Model model) {
model.addAttribute("pushNotification", true);
model.addAttribute("emailNotification", false);
return "notificationSettings";
}
}
対応するHTMLコードは以下のようになります。
<form action="/saveNotificationSettings" method="post">
<div>
<label>プッシュ通知</label>
<input type="checkbox" th:checked="${pushNotification}">
</div>
<div>
<label>メール通知</label>
<input type="checkbox" th:checked="${emailNotification}">
</div>
<button type="submit">設定を保存</button>
</form>
このコードでは、pushNotificationがtrueでチェックが入り、emailNotificationがfalseなのでチェックは外れた状態で表示されます。こうすることで、ユーザーの既存の設定内容に基づいたチェックボックスが表示され、ユーザーが設定を確認した上で変更・保存できるようになります。
4. th:checkedの注意点とポイント
th:checkedを使う際の注意点として、データの取り扱いに気をつける必要があります。特に、Java側でチェック状態がnullや不定の状態の場合、予期しない表示になることがあります。そのため、Modelに渡す前にtrueまたはfalseとして値を確定させるか、デフォルト値を設定しておくと良いでしょう。
また、複数のチェックボックスを使用する場合、それぞれのth:checked属性の値が適切に設定されているか確認しましょう。データが正しく反映されることで、ユーザーの意図に沿ったフォームが提供できます。
5. th:checkedとth:fieldの違いと使い分け(Springフォームと双方向バインド)
th:checkedは「表示時のON/OFFを動的に制御」するための属性、th:fieldは「@ModelAttributeにバインドされたプロパティと自動連携」するための属性です。Spring Boot + Thymeleafでは、ブール値のチェックボックスにth:fieldを使うと、初期表示のチェック状態も送信値の取り扱いも安全に行えます(SEO観点の主要キーワード:Thymeleaf th:checked 使い方/チェックボックス ON/OFF 動的制御)。
// DTO(フォームオブジェクト)
public class UserSettings {
private boolean receiveNewsletter;
// getter/setter
}
// Controller
@Controller
@RequestMapping("/settings")
public class SettingsController {
@GetMapping
public String show(@ModelAttribute("userSettings") UserSettings form) {
// 初期値(デフォルトONなど)
form.setReceiveNewsletter(true);
return "settings";
}
@PostMapping
public String submit(@ModelAttribute("userSettings") UserSettings form) {
// form.getReceiveNewsletter() にON/OFFが格納される
return "redirect:/settings?done";
}
}
<!-- settings.html -->
<form th:action="@{/settings}" th:object="${userSettings}" method="post" class="vstack gap-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="receiveNewsletter" th:field="*{receiveNewsletter}">
<label class="form-check-label" for="receiveNewsletter">メールを受け取る</label>
</div>
<button class="btn btn-primary" type="submit">保存する</button>
</form>
ポイント:th:field="*{receiveNewsletter}"を使うと、表示時はプロパティ値に応じて自動でチェックON/OFF、送信時はOFFでも安全にfalseがサーバへ渡るように補助入力(hidden)が自動生成されます。
6. 複数チェックボックス(List/Enum)をth:checked/th:fieldで動的制御
「興味のあるトピック」など複数選択は、List<String>やSet<Enum>にバインドして、テンプレート側でth:eachとth:fieldを併用するのが定番です。既存データに基づきチェック状態を自動維持でき、更新画面でもON/OFFを動的に制御できます。
// Enum 例
public enum Topic { NEWS, SALES, EVENTS }
// DTO
public class PrefForm {
private Set<Topic> topics = new LinkedHashSet<>();
// getter/setter
}
// Controller(初期選択を付与)
@Controller
@RequestMapping("/prefs")
public class PrefController {
@GetMapping
public String show(@ModelAttribute("prefForm") PrefForm form) {
form.getTopics().add(Topic.NEWS); // 既存値としてNEWSにチェック
return "prefs";
}
}
<!-- prefs.html -->
<form th:action="@{/prefs}" th:object="${prefForm}" method="post" class="vstack gap-2">
<div th:each="t : ${T(com.example.Topic).values()}" class="form-check">
<input class="form-check-input" type="checkbox" th:field="*{topics}" th:value="${t}" th:id="${'topic-' + t}">
<label class="form-check-label" th:for="${'topic-' + t}" th:text="${t}">NEWS</label>
</div>
<button class="btn btn-success mt-2" type="submit">保存</button>
</form>
既存のリスト/セットを直接使わず個別条件で制御したいときは、#lists.contains(selected, value)や#bools.isTrue(...)を使ったth:checkedも有効です。
<!-- th:checkedを用いた個別制御の例 -->
<input type="checkbox"
th:each="opt : ${allTags}"
th:value="${opt}"
th:checked="${#lists.contains(selectedTags, opt)}"> <span th:text="${opt}">タグ</span>
7. 初期値・バリデーション・アクセシビリティの実践ポイント
- 初期値はサーバ側で決める:
Modelまたはフォームオブジェクトに既定値(ON/OFF)を設定してから表示すると、初期表示のブレが起きにくく、SEO観点でも安定したコンテンツを提供できます。 - OFF時の未送信対策:
th:field付きチェックボックスは、OFFでもfalseが送信されるよう自動補助されます。th:checkedのみで制御する場合は、必要に応じてhiddenを自前で追加します。 - バリデーション連携:必須扱いにする場合はサーバ側で検証し、エラーを
th:errors等で表示します。
<div class="form-check">
<input class="form-check-input" type="checkbox" th:field="*{agreeTerms}" id="agreeTerms" required>
<label class="form-check-label" for="agreeTerms">利用規約に同意する</label>
</div>
<div class="text-danger small" th:if="${#fields.hasErrors('agreeTerms')}" th:errors="*{agreeTerms}">
同意が必要です
</div>
- アクセシビリティ:
labelのforと入力のidを対応させ、タップ領域を広げる(.form-check等)とユーザビリティが向上します。 - 条件付き無効化:他項目の値に応じた無効化は
th:attrでdisabledを切り替え可能。例:th:attr="disabled=${!canEdit}"
まとめ
今回は、Thymeleafのth:checked属性を使って、チェックボックスの動的な制御方法について学びました。この機能は、チェックボックスの状態をJava側のデータに基づいて自動的に制御できる便利な方法です。特に、ユーザー設定画面やプロフィール編集画面など、ユーザーが事前に選択した内容を保持しながら編集できるフォームを作る際に役立ちます。
例えば、メール配信の設定や通知のオン・オフなど、チェックボックスを活用するシーンではth:checkedを使用することで、データの管理が簡単になります。JavaのコントローラーからModelに設定値を渡し、それをThymeleafのテンプレートで利用することで、動的にチェックボックスを制御できるため、ユーザーにとっても使いやすいインターフェースを提供できます。
また、th:checkedを使用する際のポイントとして、事前にJavaでデフォルト値を設定しておくことが重要です。これにより、チェックボックスの初期状態を意図通りに設定でき、ユーザーに誤解を与えないUIが実現できます。さらに、Modelに値が設定されていない場合は、nullチェックを行うかデフォルトのfalseを設定することも推奨されます。
以下のように、th:checkedを利用したチェックボックスの実用的なサンプルコードを再確認しておきましょう。
@Controller
public class ProfileController {
@GetMapping("/profile")
public String profileSettings(Model model) {
// デフォルト値として false を設定
model.addAttribute("receiveNewsletter", true);
model.addAttribute("enableNotifications", false);
return "profile";
}
}
<form action="/saveProfileSettings" method="post">
<div>
<label>ニュースレターを受け取る</label>
<input type="checkbox" th:checked="${receiveNewsletter}" name="receiveNewsletter">
</div>
<div>
<label>通知を有効にする</label>
<input type="checkbox" th:checked="${enableNotifications}" name="enableNotifications">
</div>
<button type="submit">保存</button>
</form>
このように、th:checkedを使うことで、ユーザーにとってわかりやすいインターフェースを実現できるだけでなく、バックエンドのロジックもシンプルに保つことができます。これからのThymeleafプロジェクトで、ぜひこのth:checkedを活用してみてください。
生徒
「Thymeleafのth:checkedの使い方がよく分かりました!フォームのチェックボックスを動的に制御するのにとても便利ですね。」
先生
「そうですね、th:checkedを使えば、ユーザーが以前選択した内容を保持することができるので、再入力の手間が省けて親切なUIが作れます。」
生徒
「JavaのコントローラーからModelに値を渡してチェックボックスに反映するという流れもシンプルで覚えやすいです。」
先生
「これからの開発では、チェックボックスだけでなく、他のフォーム要素にもThymeleafの動的な属性設定を活用してみましょう。例えばth:selectedでドロップダウンリストの選択状態を制御したり、th:disabledで入力制御もできますよ。」
生徒
「他の属性設定も試してみたいです!ありがとうございました!」