타임리프는 스프링 없이도 동작하지만 스프링과 통합을 위한 다양한 기능을 편리하게 제공한다
SpringEL 문법 통합
스프링 빈 호출 지원
th:object, th:field => 편리한 폼 관리를 위한 추가 속성
폼 컴포넌트 기능
입력 폼 처리
th:object
form 태그에서 th:object를 통해 form에서 어떤 객체를 사용하는 지 설정할 수 있다. (서버에서 이 객체를 생성해서 넘겨주어야 한다)
<form action="item.html" th:action th:object="${item}" method="post">
th:object="${item}으로 설정하면 form 태그 안에서 *{itemName}을 사용하면 타임리프가 알아서 ${item.ItemName}으로 해석해준다
th:field
th:field를 사용하면 타임리프가 렌더링 할 때 field의 이름을 사용하여 알아서 id, name, value값을 설정해준다
<input type="text" th:field="*{itemName}" class="form-control"placeholder="이름을 입력하세요">
위의 내용을 다음과 같이 렌더링 해준다
<input type="text" class="form-control" placeholder="이름을 입력하세요" id="itemName" name="itemName" value="">
object의 itemName의 값이 따로 설정되어있지 않으면 value값이 비어있는 상태가 되고, 값이 설정되어 있으면 그 값이 추가된다.
단일 체크 박스
체크박스를 이용하여 체크를 했는지 하지 않았는지를 확인하는 경우이다.
체크박스가 체크된 경우 on으로 넘어오지만(타임리프가 true값으로 저장함) 체크되지 않은 경우 값이 아예 전달되지 않기 때문에 문제가 일어날 수 있다.
(true로 설정된 값을 수정 시에 체크를 풀었는데 null이 전달되어 true로 유지되는 경우)
이 때 다음과 같은 히든 필드를 사용할 수 있다
<div class="form-check">
<input type="checkbox" id="open" name="open" class="form-check-input">
<input type="hidden" name="_open" value="on"/> <!-- 히든 필드 추가 -->
<label for="open" class="form-check-label">판매 오픈</label>
</div>
(lable태그는 판매오픈이라는 글자를 눌러도 체크박스가 작동되게 하는 용도이다)
위 코드를 추가해주면
open=on&_open=on => open=true
_open=on => open=false
로 서버에 전달되기 때문에 값을 확실히 알 수 있다.
th:field
타임리프를 사용하면 위의 hidden값을 개발자가 추가하지 않아도 알아서 추가해준다.
<div class="form-check">
<input type="checkbox" id="open" th:field="*{open}" class="form-checkinput">
<label for="open" class="form-check-label">판매 오픈</label>
</div>
위와 같이 checkbox에 th:field 사용시 id, name, value 뿐 아니라 hidden 필드도 자동으로 생성해준다
다중 체크박스
체크박스를 만들시에 lable에서 id를 사용해서 구역을 설정한다
하지만 th:each를 이용해 여러개의 박스 생성시 id가 자동으로 다르게 생성되기 때문에 다른 방법으로 lable을 생성해야한다
<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>
#ids.prev('regions') 사용시 th:field에서 자동으로 생성된 id가 적용된다
#ids.next를 사용하면 다음에 생성될 id로 적용된다.
실행시 다음과 같이 작동된다
<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>
<input type="checkbox" value="BUSAN" class="form-check-input" id="regions2" name="regions">
<input type="hidden" name="_regions" value="on"/>
<label for="regions2" class="form-check-label">부산</label>
추가로 타임리프는 th:field에 지정한 값과 th:value의 값을 비교해서 체크를 자동으로 처리해준다
예를들어 th:field값인 item.resion에 seoul과 busan이 있고, th:value값인 resion.key값에 seoul, busan, jeju 가 있으면 이 두 값을 비교해 seoul과 busan에만 체크를 하고 jeju에는 checked속성을 넣지 않는다
라디오 버튼
라디오 버튼은 체크박스처럼 선택하지만 하나만 선택할 수 있다
<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>
위 코드는 itemTypes 처음부터 끝까지 반복되며 실행된다
item.itemType을 필드로 가지고 id는 itemType1, itemType2, .. 로 자동생성된다 label의 for 속성도 id와 동일하게 생성된다
value값은 type.name()인데 type은 지금 실행중인 itemTypes의 name이다 (name() 은 enum타입의 변수)
th:text로 출력되는 선택지 이름은 itemTypes의 description부분이다
위의 반복문을 사용할 때 타임리프로 enum에 직접 접근도 가능하다
<div th:each="type : ${T(hello.itemservice.domain.item.ItemType).values()}">
셀렉트 박스
<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>
th:each를 통해 deliveryCodes의 갯수만큼 반복
th:value는 deliveryCode의 code, th:text는 deliveryCode의 displayName
참고한 강의
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/
스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의
웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있
www.inflearn.com
'Spring Boot > thymeleaf' 카테고리의 다른 글
타임리프(thymeleaf) 템플릿조각 / 템플릿 레이아웃 (0) | 2023.10.31 |
---|---|
타임리프 기본 표현식 (1) | 2023.10.27 |