쌓고 쌓다

다중 체크 박스 사용하기 본문

프로그래밍/thymeleaf

다중 체크 박스 사용하기

승민아 2023. 8. 20. 17:30

목표 기능

 

@Data
public class Item {
    private List<String> regions; //등록 지역
}

아이템 클래스의 등록 지역(ex. 부산, 서울)을 가지는 필드가 있다.

 

이 필드를 다중 체크 박스를 통해 값을 넣어보자.

 

@ModelAttribute("regions")
public Map<String, String> regions() {
    Map<String, String> regions = new LinkedHashMap<>(); // HashMap은 순서가 보장안되나 LinkedHashMap은 보장됨
    regions.put("SEOUL", "서울");
    regions.put("BUSAN", "부산");
    regions.put("JEJU", "제주");
    return regions;
}

컨트롤러에 @ModelAttribute를 메서드에 사용하여

어떤 메서드를 호출하더라도 Model에 regions를 담게 한다.

서버에 보관하는 값은 "SEOUL"이지만 사용자에게 보여질 값은 "서울"로하기 위해 작성했다.

 

등록 폼

<form action="item.html" th:action th:object="${item}" method="post">
    <div th:each="region : ${regions}">
        <input type="checkbox" th:field="*{regions}" th:value="${region.key}">
        <label th:for="${#ids.prev('regions')}" th:text="${region.value}"></label>
    </div>
</form>

현재 ${regions}에 든 값은 Map<String, String>이다.

이 값을 each로 region에 담아 하나씩 꺼내면 <Key,Value> 형태로 꺼내져 region.key, region.value를 사용할 수 있다.

(EX. <SEOUL, "서울">)

 

th:field??? id, name 속성을 자동으로 생성해준다고 알고있다.

name 속성의 값은 같아도 문제 없지만. ID는 달라야한다.

다행히 타임리프의 each는 반복해서 만들때 1, 2, 3을 뒤에 붙여준다.

 

name 속성이 regions로 같기에

Item 클래스의 List<String> regions에 매핑되어 리스트로 모두 들어간다.

 

상세보기 폼

Item 상세보기에서도 동일하게 regions 필드를 불러올 수 있다.

<div th:each="region : ${regions}">
    <input type="checkbox" th:field="${item.regions}" th:value="${region.key}" disabled>
    <label th:for="${#ids.prev('regions')}" th:text="${region.value}"></label>
</div>

상품 상세보기는 form 태그를 안쓰기에 *{}를 사용하지 않음을 주의하자.

 

타임리프는 th:field와 th:value의 값을 비교하여 checked 옵션 또한 넣어준다.

Comments