공부함

타임리프 스프링 통합, 폼 본문

스프링/스프링mvc2

타임리프 스프링 통합, 폼

찌땀 2023. 10. 10. 15:40

https://www.inflearn.com/course/lecture?courseSlug=%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2&unitId=83273&tab=curriculum 

 

학습 페이지

 

www.inflearn.com

 

타임리프는 스프링 없이도 동작하지만, 스프링 통합을 위한 다양한 기능을 제공한다. 

- 스프링 EL 문법 통합

- 스프링 빈 호출 지원 

- 편리한 폼 관리를 위한 추가 속성 지원 

- 폼 컴포넌트 기능 

- 메세지, 국제화 기능의 편리한 통합 

- 검증, 오류 처리 통합 

- 변환 서비스 ConversionService 통합 

 


입력 폼 처리 

렌더링 전 
<input type="text" th:field="*{itemName}/>
렌더링 후 
<input type="text" id="itemName" name="itemName" th:value="*{itemName}" />

th:object : 커맨드 객체 지정  

*{ .. } : 선택 변수 식, th:object에서 지정한 객체에 접근 

th:field : html 태그의 id, name,value 속성 값 자동 처리 

 

<form action="item.html" th:action th:object="${item}" method="post">
    <div>
        <label for="itemName">상품명</label>
        <input type="text" id="itemName" th:field="*{itemName}" class="formcontrol" placeholder="이름을 입력하세요">
    </div>
    <div>
        <label for="price">가격</label>
        <input type="text" id="price" th:field="*{price}" class="form-control" placeholder="가격을 입력하세요">
    </div>
    <div>
        <label for="quantity">수량</label>
        <input type="text" id="quantity" th:field="*{quantity}" class="formcontrol" placeholder="수량을 입력하세요">
    </div>
</form>

form에서 사용할 객체를 th:object 속성으로 등록한다. 

등록한 객체를 대상으로 *{ .. } 선택 변수 식을 사용할 수 있다. 

th:field 는 위에서 말했듯이 id, field, value 속성값을 자동으로 만들어준다.

id, field 속성값은 th:field 에서 지정한 변수 이름과 같으며, value 속성값은 th:field에서 지정한 변수의 값을 사용한다. 

 

단일 체크박스

@PostMapping("/add")
public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes) {
    Item savedItem = itemRepository.save(item);
    redirectAttributes.addAttribute("itemId", savedItem.getId());
    redirectAttributes.addAttribute("status", true);
    return "redirect:/form/items/{itemId}";
}

post form으로 (쿼리 스트링 형태로) 데이터가 넘어오면 그에 맞는 Item 객체가 @ModelAttribute에 의해 생성된다.

<!-- single checkbox -->
<div>판매 여부</div>
<div>
    <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>
</div>

_open은 체크 해제를 인식하기 위한 히든 필드이다. 

체크박스를 선택할 경우 open=on & _open = on이 된다.  _open은 무시되고 item.open = true가 된다. 

체크박스를 해제할 경우 _open만 있고 item.open = false가 된다. 

 

위 방식은 MVC에서 제공하는 기능이다. 

하지만 이렇게 매번 히든 필드를 추가하기는 번거롭다. 

타임리프를 사용하면 더 간단하게 할 수 있다. 

 

<div>판매 여부</div>
<div>
    <div class="form-check">
        <input type="checkbox" id="open" th:field="*{open}" class="form-checkinput">
        <label for="open" class="form-check-label">판매 오픈</label>
    </div>
</div>

th:field = "${item.open}"으로 설정해주면 된다. 

또는 th:object ="${item}"으로 변수를 선언하고  th:field = "*{open}" 선택 변수 식을 사용할 수도 있다.

 

멀티 체크 박스

@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를 활용해 이러한 메서드를 컨트롤러 내에 선언해 주면 해당 컨트롤러의 메서드가 호출될 때는 항상 model의 regions가 담기게 된다. 

중복을 해소하는데 유용하다. 

 

<div>
    <div>등록 지역</div>
    <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>

th:each 태그를 사용해서 반복문으로 멀티 체크박스를 렌더링한다. 

주의 : th:field="*{regions}" 는 Item 객체의 regions이다. 

<label>은 <input> 의 id를 알아야 한다. 그런데 위 예시에서는 th:field를 활용해서 id가 만들어지기 때문이 미리 알 수 가 없다. 이럴 때 th:for="${#ids.prev('regions')}"로 동적으로 생성되는 id 값을 만들 수 있다. 

 

멀티 체크박스에서도 아무것도 선택하지 않으면 _regions=on&_regions=on&_regions=on과 같이 값이 넘어간다. 

 

라디오 버튼 

여러 선택지 중 하나 선택할 때 사용한다. 

<!-- radio button -->
<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>

체크박스랑 거의 똑같다..

 

셀렉트 박스 

마찬가지로 여러 선택지 중 하나 선택 

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

 

'스프링 > 스프링mvc2' 카테고리의 다른 글

메세지, 국제화  (0) 2023.10.11
타임리프  (0) 2023.10.09