はじめに
Spring BootとThymeleafでWebアプリケーションを開発する際、「データベースの値をセレクトボックスに表示したい」という場面は頻繁にありますよね。
例えば、DBに以下のようなfoodsテーブルがあるとします。
id: 1, name: りんご
id: 2, name: みかん
id: 3, name: ぶどう
この記事では、このような動的なセレクトボックスを、コードが冗長にならず、かつ再利用しやすく「きれいに」実装する基本的な流れを紹介します。
主な手順
・Java側: DBから取得したリストを、セレクトボックスに最適なMap形式に変換する
・Thymeleaf側: Mapの値をth:eachで展開し、セレクトボックスを描画する
1. DBから値を取り出すクラスを作成
これはもう各々DomaやJPAなんかを使われていると思います。
お好きなライブラリで主キーと表示させたい名前をLinkedHashMapに突っ込んでください。
public Map<String,String> getFoodList(List<FoodEntity> foodEntityList){
Map<String,String> foodMap = new LinkedHashMap<String,String>();
foodMap.put(""," ")
foodMap.putAllfoodEntityList(クラス名.getFoodList(foodEntityList))
return foodMap;
}
public Map<String,String> getFoodList(List<FoodEntity> foodEntityList){
Map<String,String> returnMap = new LinkedHashMap<String,String>();
for (int i=0;i < foodEntityList.size();i++){
foodEntity entity = foodEntityList.get(i);
returnMap.put(entity.getId,entity.getName)
}
return returnMap;
}
こんな感じに引数に与えることで絞り込みも可能にしています。
thymeleafからここへSpELで呼び出します。
2. javaからthymeleafへ送る
ここで送るものはFormとSelectBoxSetクラスです。
Formですが、このFormに入れたEntityListを引数(検索条件)に、SelectBoxの中身を構築しますので、Serviceクラスで好きなように絞り込んでください。
ここでは全検索した結果を入れます
String foodCode;
List<FoodEntity> foodEntityList;
Form form = new form();
form.setFoodEntityList = foodRepository.findAll;
準備もできたので、モデルに詰めていきます
model.addAttribute("SelectBoxSet",SelectBox);
model.addAttribute("form",form);
3. thymeleafで実装
ここからセレクトボックスにして表示させていきます。
結論から書くとこんな感じです。それぞれ解説していきます
<select th:field="*{foodCode}">
<option th:each="item : ${selectBox.getFoodList(form.foodEntityList)}"
th:value="${item.key}"
th:text="${item.value}"
th:selected="${item.key} == *{foodCode}"/>
</select>
<select th:field="*{foodCode}">
見慣れている方も多いですね、selectBoxの定義とformとの紐づけです。
<option th:each="item : ${selectBox.getFoodList(form.foodEntityList)}
ここが肝です。SpELでjavaのメソッドを呼び出してます。
今回はselectBoxSetのgetFoodListメソッドをformのfoodEntityListを引数として呼び出し、これをitemという名前をつけてth:eachで要素の数だけループしています。
th:value="${item.key}"
th:text="${item.value}"
th:selected="${item.key} == *{foodCode}"
裏側の値をkey(今回はfoodCode)と設定しています。
表側の値はvalue(今回はfoodName)と設定しています。
このitemのキーがフォームのfoodCodeと同じだったら、この選択肢を「選択済み」の状態にします。
まとめ
以上が、Spring Boot/Thymeleafで動的なセレクトボックスをきれいに実装する流れです。
・Java側: LinkedHashMapを使って「キーと値のペア」と「順序」を保持したデータを用意する。
・Thymeleaf側: th:eachでMapをループさせ、entry.keyとentry.valueを使ってを生成する。
このパターンを使えば、コードの見通しが良く、再利用性の高い実装ができます。