코드 그라데이션
Thymeleaf 통합 (4) 체크 박스 - 멀티 본문
체크 박스 - 멀티
체크 박스를 멀티로 사용해서, 하나 이상을 체크할 수 있도록.
등록 지역
- 서울, 부산, 제주
- 체크 박스로 다중 선택할 수 있다.
등록 폼 수정
@GetMapping("/add")
public String addForm(Model model) {
model.addAttribute("item", new Item());
Map<String, String> regions = new LinkedHashMap<>(); // HashMap 쓰면 순서가 보장x
regions.put("SEOUL", "서울");
regions.put("BUSAN", "부산");
regions.put("JEJU", "제주");
model.addAttribute("regions", regions);
return "form/addForm";
}
Map<String, String> regions = new LinkedHashMap<>(); // HashMap 쓰면 순서가 보장x
regions.put("SEOUL", "서울");
regions.put("BUSAN", "부산");
regions.put("JEJU", "제주");
model.addAttribute("regions", regions);
그런데, 생각해보면 이것은 등록 폼에만 넣는 게 아니라 상품 상세, 수정 폼에도 들어가고 해야 한다.
그럼 코드를 따로 빼는 게 맞죠.
/**
* 이렇게 하면 이 컨트롤러를 호출할 때는
* 항상 얘가 ModelAttribute 에 자동으로 addAttribute 되어가지고
* Model에 무조건 담긴다.
* 그래서 일일이 메서드에 추가했던 코드를 다시 다 지울 수 있게 된다.
* @return
*/
@ModelAttribute("regions")
public Map<String, String> regions() {
Map<String, String> regions = new LinkedHashMap<>();
regions.put("SEOUL", "서울");
regions.put("BUSAN", "부산");
regions.put("JEJU", "제주");
return regions;
}
예를 들어, editForm이 호출이 되면, 위의 얘의 내용이 자동으로 모델에 담기게 된다는 뜻.
@ModelAttribute의 특별한 사용법
addForm.html - 추가
single checkbox 아래 영역에 추가
<!-- multi checkbox -->
<div>
<!-- "등록 지역" 섹션을 표시하는 div -->
<div>등록 지역</div>
<!-- Thymeleaf 반복문으로 지역 목록을 처리하며, 각 지역에 대한 체크박스를 생성 -->
<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>
부연설명
<div th:each="region : ${regions}" class="form-check form-check-inline">
- 이 요소는 Thymeleaf의 반복 지시문인 th:each를 사용하여 반복된다.
- ${regions}는 Thymeleaf 컨텍스트에서 제공되는 컬렉션 또는 리스트를 나타내며, region은 각 요소를 대표하는 변수.
- 이 요소에는 "form-check" 및 "form-check-inline" 클래스가 지정되어 있다.
- 이러한 클래스는 일반적으로 CSS 스타일링을 적용하는 데 사용된다.
<input type="checkbox" th:field="*{regions}" th:value="${region.key}" class="form-check-input">
- 이 부분은 체크박스를 생성하는 부분입니다. th:field 속성은 Thymeleaf의 폼 바인딩을 사용하며, *{regions}는 해당 체크박스의 값을 연결할 모델 속성을 나타낸다.
- th:value는 각 체크박스의 값으로 ${region.key}를 사용하고 있으며, 이 값은 반복문에서 현재 요소의 키를 나타낸다.
- class="form-check-input"는 체크박스에 CSS 클래스를 지정한다.
<label th:for="${#ids.prev('regions')}" th:text="${region.value}" class="form-check-label">서울</label>
- 이 부분은 체크박스 옆에 레이블을 생성한다.
- th:for 속성은 레이블을 체크박스와 연결하고, ${#ids.prev('regions')}는 이전 폼 컨트롤의 ID를 참조.
- th:text는 레이블의 텍스트로 ${region.value}를 사용하고 있으며, 이 값은 반복문에서 현재 요소의 값을 나타낸다.
- class="form-check-label"는 레이블에 CSS 클래스를 지정한다
실행하면
새로 생김
페이지 소스 보기 해보면
반복문을 사용해서 돌리는데,
그 돌리는 것은 아까 처음에 추가했던
@ModelAttribute("regions")
public Map<String, String> regions() {
Map<String, String> regions = new LinkedHashMap<>();
regions.put("SEOUL", "서울");
regions.put("BUSAN", "부산");
regions.put("JEJU", "제주");
return regions;
}
요게 한다.
설명
each로 체크박스가 반복 생성된 결과 - id 뒤에 숫자가 추가
로그 출력
FormItemController.addItem() 에 코드 추가
log.info("item.regions={}", item.getRegions());
편의를 위해 application.properties의 옵션을 끄고 돌리겠다.
regions를 List로 지정했으므로 값 두개가 잘 들어온다.
이번엔 지역 선택 하지 않고 등록해보면
빈 배열이 들어옴을 확인할 수 있음.
로그: item.regions=[]
item.html에도 추가
<!-- multi checkbox -->
<div>
<div>등록 지역</div>
<div th:each="region : ${regions}" class="form-check form-check-inline">
<input type="checkbox" th:field="${item.regions}" th:value="${region.key}" class="form-check-input" disabled>
<label th:for="${#ids.prev('regions')}"
th:text="${region.value}" class="form-check-label">서울</label>
</div>
</div>
item에는 th:object가 없다!!!
타임리프의 체크 확인
즉
th:field="${item.regions}" th:value="${region.key}" 이렇게 있으면
item.regions 에는 처음에 내가 선택한 두 개(서울, 부산) 이 들어가 있다.
value에는 값이 하나씩 만들어지니까 th:value 에는 값이 서울, 부산, 제주 가 들어가 있다.
첫 번째는 region.key 얘가 서울인데 서울 값이 item.regions에 있나 비교해보고, 있으니까 checked 에 값을 넣어주고,
두 번째는 region.key 얘가 부산인데 부산 값이 item.regions에 있나 비교해보고, 있으니까 checked 에 값을 넣어주고,
세 번째는 region.key 얘가 제주인데 제주 값이 item.regions에 있나 비교해보고, 없으니까 넣지 않는다는 것.
editForm.html - 추가
<!-- multi checkbox -->
<div>
<div>등록 지역</div>
<div th:each="region : ${regions}" class="form-check form-check-inline">
<input type="checkbox" th:field="${item.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>
'Spring > Thymeleaf' 카테고리의 다른 글
Thymeleaf 통합 (6) Select Box (1) | 2023.12.07 |
---|---|
Thymeleaf 통합 (5) 라디오 버튼 (2) | 2023.12.06 |
Thymeleaf 통합 (3) 체크 박스 - 단일 (2) (1) | 2023.12.03 |
Thymeleaf 통합 (2) 체크 박스 - 단일(1) (0) | 2023.12.02 |
요구사항 (또) 추가 (0) | 2023.11.30 |