2 분 소요


체크 박스 - 멀티

Controller

@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는 컨트롤러에 있는 별도의 메서드에 적용할 수 있다.
  • 컨트롤러를 요청할 때 regions에서 반환한 값이 자동으로 model에 담기게 된다.

addForm.html

<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>
  • th:for="${#ids.prev('regions')}"
    멀티 체크박스는 같은 이름으로 여러 체크박스를 만들 수 있다.
    생성된 HTML 태그 속성에서 name은 같아도 되지만, id는 모두 달라야 하기 때문에 each루프 안에서 반복해서 만들 때 임의로 1,2,3 숫자를 뒤에 붙여준다.
    (id="regions1"...)

타임리프는 ids.prev(...), ids.next(...)를 제공해서 동적으로 생성되는 id값을 사용할 수 있도록 한다.

생성 결과

<div class="form-check form-check-inline">
    <input type="checkbox" value="SEOUL" class="form-check-input" id="regions1" 
        name="regions">
    <input type="hidden" name="_regions" value="on"/>
    <label for="regions1" class="form-check-label">서울</label>
</div>

<!-- 이하 동일 -->

서울, 부산 선택 시

regions=SEOUL&_regions=on&regions=BUSAN&_regions=on&_regions=on

로그 : item.regions=[SEOUL, BUSAN]

지역 선택 X

_regions=on&_regions=on&_regions=on

로그: item.regions=[]

item.html

<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>
  • 등록에서 서울, 부산을 선택했다면 item.regions=[SEOUL, BUSAN]
  • Controller에서 Item을 넘겨주어 ${item.regions}에는 SEOUL, BUSAN이 들어있다.
  • th:field에 지정한 값과 th:value의 값을 비교해서 체크를 자동으로 처리해준다.


라디오 버튼

ItemType - Enum

public enum ItemType {

    BOOK("도서"), FOOD("식품"), ETC("기타");

    private final String description;

    ItemType(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

Controller

@ModelAttribute("itemTypes")
public ItemType[] itemTypes() {
    return ItemType.values();
}
  • ItemType.values()를 사용하면 해당 ENUM의 모든 정보를 배열로 반환한다.
    • [BOOK, FOOD, ETC]

addForm.html

<div th:each="type : ${itemTypes}" class="form-check form-check-inline">
    <input type="radio" th:field="*{itemType}" th:value="${type.name()}" 
        class="form-check-input">
    <label th:for="${#ids.prev('itemType')}" th:text="${type.description}" 
        class="form-check-label"> BOOK </label>
</div>
  • th:text="${type.description}": Enum의 정보 안에 설명 출력(도서 음식…)

실행 로그
item.itemType=FOOD: 값이 있을 때
item.itemType=null: 값이 없을 때

체크 박스는 체크를 해제하면 값이 null이 되기 때문에 히든 필드로 문제를 해결했지만, 라디오 버튼은 수정시에도 항상 하니를 선택(등록에서 선택을 안한 것은 예외)하도록 되어있으므로 체크 박스와 달리 별도의 히든 필드를 사용할 필요가 없다.

ENUM 직접 사용

타임리프에서 ENUM 직접 접근
<div th:each="type : ${T(hello.itemservice.domain.item.ItemType).values()}">
하지만 ENUM의 패키지 위치가 변경되면 컴파일러가 타임리프까지 컴파일 오류를 잡을 수 없으므로 추천X


셀렉트 박스

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;
}

DeliveryCode 자바 객체를 사용.

[참고]
@ModelAttribute가 있는 deliveryCodes()메서드는 컨트롤러가 호출 될 때 마다 사용되므로 deliveryCodes객체도 계속 생성된다. 이런 부분은 미리 생성해두고 재사용하는 것이 더 효율적이다.

addForm.html

<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>

생성된 HTML

<select class="form-select" id="deliveryCode" name="deliveryCode">
    <option value="">==배송 방식 선택==</option>
    <option value="FAST">빠른 배송</option>
    <option value="NORMAL">일반 배송</option>
    <option value="SLOW">느린 배송</option>
</select>


<출처 : 인프런 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술(김영한)>

댓글남기기