Spring Boot Thymeleaf Viewの一部を動的に変える


目的

セレクトボックスで選択した内容に応じてそれに紐付くリストを動的に(画面の再読み込みなしに部分的に)変更する

環境

Spring Boot
Thymleaf
Kotlin

完成形イメージ

選択した講座に合わせて、開催時間が変わる例

方法

Thymleafのfragmentを利用して、一部のDOMだけレンダリングさせる。
また、セレクトボックスを押した際のリクエストについては、ajaxを用いる

処理の流れ
  1. ViewでselectBoxの値変更
  2. ajaxでpost
  3. Controllerで変更したい部分だけのDOMを返す
  4. フロント側でControllerからもらったDOMと該当箇所を差し替え(ajaxのレスポンス受け取る部分)

詳細

testview.html
<!-- 部分的にレンダリングしたい部分 -->
<div th:fragment="test-fragment"> 
  <label for="target">ご希望の時間帯 他の時間帯はお問い合わせ欄に記載ください</label>
  <select id="target" th:field="*{course_id}" th:onchange="updateCourseDateList(this.value)">
    <option th:each="courseDate : ${courseDates}"
            th:value="${courseDate.id}"
            th:text="${courseDate.holding_date}"></option>
  </select>
</div>
.
.
.

<script type="text/javascript">
  function updateCourseDateList(selectedId) {
    url = '/updateCourseDate/' + selectedId;
    var targetElement = document.getElementById("target");

    $.ajax({
      method: 'POST',
      data: {},
      url: url
    }).then(
            function(data) {
              targetElement.outerHTML = data;
            },
            function() {
              alert("error");
            });
  }
</script>
testController
   @PostMapping("updateCourseDate/{selectedId}")
   fun updateCourseDateList(model: Model, @PathVariable(value= "selectedId") selectedId: Int): String {
        model.addAttribute("course_id",xxxx)
        model.addAttribute("courseDates", xxxxx)
        return "testview :: test-fragment"
// return 時に 部分的にレンダリングしたい部分のtest-fragmentを指定する
    }