스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - (12) 타임리프 스프링 통합과 폼 - 라디오 버튼, 셀렉트 박스
인프런 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술편을 학습하고 정리한 내용 입니다.
라디오 버튼
라디오 버튼은 여러 선택지 중에 하나를 선택할 때 사용할 수 있다.
자바 ENUM을 활용해서 개발해 보자.
- 상품 종류
- 도서, 식품, 기타
- 라디오 버튼으로 하나만 선택할 수 있다.
FormItemController - 추가
1
2
3
4
@ModelAttribute("itemTypes")
public ItemType[] itemTypes() {
return ItemType.values();
}
ItemType을 등록 폼, 조회, 수정 폼에서 모두 사용하므로 @ModelAttribute을 사용해서 모든 컨트롤러에서 사용할 수 있도록 등록.
ItemType.values()를 사용하면 해당 ENUM의 모든 정보를 배열로 반환. ex) [BOOK, FOOD, ETC]
상품 등록 폼에 기능을 추가해 보자.
등록 - addForm.html
1
2
3
4
5
6
7
8
9
10
11
12
<!-- radio button -->
<div>
<div>상품 종류</div>
<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>
</div>

다음과 같이 라디오 버튼이 만들어 졌다.

타입도 잘 넘어간다. 만약 선택을 안하고 넘기면 null이 넘어간다.

체크 박스는 수정 시 체크를 해제하면 아무 값도 넘어가지 않기 때문에, 별도의 히든 필드로 이런 문제를 해결했다.
라디오 버튼은 이미 선택이 되어 있다면, 수정 시에도 항상 하나를 선택하게 되어 있으므로 체크 박스와 달리 별도의 히든 필드를 사용할 필요가 없다.
상품 상세, 수정에도 라디오 버튼을 넣자.
상세 - item.html
1
2
3
4
5
6
7
8
9
10
11
<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>
주의: item.html에는 th:object를 사용하지 않았기 때문에 th:field부분에 ${item.itemType}으로 적어주어야 한다.
disabled를 사용해서 상품 상세에서는 라디오 버튼이 선택되지 않도록 했다.

수정 - editForm.html
1
2
3
4
5
6
7
8
9
10
11
12
<!-- radio button -->
<div>
<div>상품 종류</div>
<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>
</div>

타임리프에서 ENUM 직접 사용하기
컨트롤러단에서 model에 ENUM을 안넘기고 바로 타임리프에서 자바 객체에 직접 접근할 수 있다.
타임리프에서 ENUM 직접 접근
1
<div th:each="type : ${T(hello.itemservice.domain.item.ItemType).values()}">
${T(hello.itemservice.domain.item.ItemType).values()} 스프링 EL 문법으로 ENUM을 직접 사용할 수 있다.
ENUM에 values()를 호출하면 해당 ENUM의 모든 정보가 배열로 반환 된다.
그런데 이렇게 사용하면 ENUM의 패키지 위치가 변경되거나 할 때 자바 컴파일러가 타임리프까지 컴파일 오류를 잡을 수 없으므로 추천하지는 않는다.
셀렉트 박스
셀렉트 박스는 여러 선택지 중에 하나를 선택할 때 사용할 수 있다.
- 배송 방식
- 빠른 배송
- 일반 배송
- 느린 배송
- 하나만 선택 가능

FormItemController
1
2
3
4
5
6
7
8
@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라는 자바 객체를 사용하는 방법으로 진행.
DeliveryCode를 등록 폼, 조회, 수정 폼에서 모두 사용하므로 @ModelAttribute의 특별한 사용법을 적용하자.
참고
@ModelAttribute가 있는deliveryCodes()메서드는 컨트롤러가 호출 될 때 마다사용되므로deliveryCodes객체도 계속 생성된다. 이런 부분은 미리 생성해두고 재사용하는 것이 더 효율적이다.
등록 - addForm.html
1
2
3
4
5
6
7
8
9
10
<!-- 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>
<hr class="my-4">
먼저 맨 위에 배송 방식 선택 껍데기를 만들고, 그 밑에 each로 여러 선택지를 만든다.

이제 상세와 수정에 추가하면 끝난다.
상세 - item.html
1
2
3
4
5
6
7
8
9
10
<!-- SELECT -->
<div>
<div>배송 방식</div>
<select th:field="${item.deliveryCode}" class="form-select" disabled>
<option value="">==배송 방식 선택==</option>
<option th:each="deliveryCode : ${deliveryCodes}" th:value="${deliveryCode.code}"
th:text="${deliveryCode.displayName}">FAST</option>
</select>
</div>
<hr class="my-4">

수정 - editForm.html
1
2
3
4
5
6
7
8
9
10
<!-- 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>
<hr class="my-4">

댓글남기기