체크박스 - single
문제점
체크박스(single) - html
<div>판매 체크</div> <div> <div class="check"> <input type="checkbox" id="open" name="open" class="check-input"> <label for="open" class="check-label">판매</label> </div> </div>
체크박스(single) - controller
@PostMapping("/add") public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes) { log.info("item.open={}", item.getOpen()); Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId", savedItem.getId()); redirectAttributes.addAttribute("status", true); return "redirect:/form/items/{itemId}"; }
📋 결론
HTML 체크박스는 선택이 안되면 값을 보내지 않는다.
기존에 체크된 값을 해제하고 보내도 값이 넘어가지 않는다.
즉, 서버는 값이 오지 않는 것으로 판단 할 수도 있는 문제점 발생💻 해결
스프링 MVC는 히든 필드를 생성하여 "_" 를 붙여 전송하면 체크해제의 인식을 할 수 있다.
<input type="checkbox" id="open" name="open" class="check-input"> <input type="hidden" name="_open" value="on"/> <!-- 히든 필드 추가 -->
📌 판단
open=true && _open=true : 체크
open= && _open=true : 체크 해제
매번 히든 필드를 추가하면 번거로운 일이 생긴다. 타임리프가 해결해준다.
체크박스 - 타임리프: 판매
<div>판매</div> <div> <div class="check"> <input type="checkbox" id="open" th:field="*{open}" class="check"> <label for="open" class="check">판매</label> </div> </div>
🤖 실행 후 소스를 확인하면 히든 생성 확인 가능
<input type="hidden" name="_open" value="on"/>
타임리프 표현식
변수 : ${...}
선택 변수: *{...}
체크박스 - multi
@ModelAttribute?
HTTP body 내용과 HTTP 파라미터 값을 getter, setter, 생성자 통해 주입을 위해 사용
컨트롤러의 반환값 등이 자동으로 model에 담기게 된다.체크박스(multi) - controller
@ModelAttribute("cities") public Map<String, String> city() { Map<String, String> city = new LinkedHashMap<>(); city.put("SEOUL", "서울"); city.put("BUSAN", "부산"); city.put("JEJU", "제주"); return city; }
체크박스(multi) - html
<div> <div>등록 지역</div> <div th:each="city : ${city}" class="form-check form-check-inline"> <input type="checkbox" th:field="*{cities}" th:value="${city.key}" class="form-check-input"> <label th:for="${#ids.prev('cities')}" th:text="${city.value}" class="form-check-label">서울</label> </div> </div>
📌 주의
th:for="${#ids.prev('cities)}"
반복해서 HTML 태그를 생성할때 name 값은 같아도 되나 id는 모두 달라야 함.
라디오 버튼
라디오버튼 - controller
@ModelAttribute("itemTypes") public ItemType[] itemTypes() { return ItemType.values(); } /* * ItemType(ENUM) : [BOOK, FOOD, ETC] */
라디오버튼 - html
<div> <div>상품 종류</div> <div th:each="type : ${itemTypes}" class="form-check form-check-inline"> <input type="radio" th:field="${item.itemType}" th:value="${type.name()}" class="form-check-input" disabled> <label th:for="${#ids.prev('itemType')}" th:text="${type.description}" class="form-check-label"> BOOK </label> </div> </div>
th:object에 item 을 선언하였다면 th:field에 ${item.itemType} 대신 *{itemType} 으로 작성 가능
셀렉트 박스
셀렉트 박스 - controller
@ModelAttribute("deliveryCodes") public List<DeliveryCode> deliveryCodes() { List<DeliveryCode> deliveryCodes = new ArrayList<>(); deliveryCodes.add(new DeliveryCode("FAST", "빠른 배송")); deliveryCodes.add(new DeliveryCode("NORMAL", "일반 배송")); deliveryCodes.add(new DeliveryCode("SLOW", "느린 배송")); return deliveryCodes; }
셀렉트 박스 - html
<!-- SELECT --> <div> <div>배송 방식</div> <select th:field="*{deliveryCode}" class="form-select"> <option value="">==배송 방식 선택==</option> <option th:each="deliveryCode : ${deliveryCodes}" th:value="$ {deliveryCode.code}" th:text="${deliveryCode.displayName}">FAST</option> </select> </div>