본문 바로가기

[Thymeleaf] 타임리프와 스프링의 통합 4 - 멀티 체크박스

@xuv22025. 6. 30. 11:53

지난번 단일 체크박스를 응용하여 멀티 체크박스도 만들어보자.


컨트롤러 수정 - @ModelAttribute 사용

@ModelAttribute("regions")
public Map<String, String> regions() {
    Map<String, String> regions = new LinkedHashMap<>();
    regions.put("SEOUL", "서울");
    regions.put("BUSAN", "부산");
    regions.put("JEJU", "제주");
    return regions;
}

해당 코드는 등록, 상세, 수정 등에서도 등장해야하는 데이터들인데, 늘 모든 코드에서 중복해서 작성해야할까?

스프링에선 해당 귀찮음을 해결하기 위해 @ModelAttribute의 기능을 지원한다.

해당 에노테이션이 있는 컨트롤러가 호출될 때, 항상 모델에 자동으로 모델에 값이 담기게 된다.

즉 모델에 데이터가 담겨있기 때문에, 각 메서드에서는 @ModelAttribute를 파라미터로 받아서 편리하게 모델의 데이터를 사용할 수 있게 된다.

 

타임리프 코드 추가

<div>
    <div>등록 지역</div>
    <div th:each="region : ${regions}" class="form-check form-check-inline">
        <input type="checkbox" th:field="*{regions}" th:value="${region.key}" class="form-check-input">
        <label th:for="${#ids.prev('regions')}" th:text="${region.value}" class="form-check-label">서울</label>
    </div>
</div>

이렇게 되면 동적으로 id가 생성되어야 하는데, HTML 태그 속성에서 name은 같아도 되는데 id는 같으면 안된다. 그래서 타임리프는 체크박스를 each 반복안에서 1,2,3, 숫자를 뒤에 붙여준다.

레이블 입장에서는 최초에 id를 모르는데, 이때 #ids 를 사용하여 동적으로 생성되는 id를 사용할 수 있도록 해준다

이걸 보면 id가 checkbox에서 동적으로 생성된 regions1, regions2, regions3 에 맞추어 순서대로 사용된 것을 볼 수 있다.

추가적으로 이 기능도 _regions라는 히든 필드가 생성되는데 클라이언트가 서버에 아무런 데이터를 보내지 않는 것을 방지한다 (null 방지)

xuv2
@xuv2 :: xuvlog

폭싹 늙었수다

목차