BackEnd/Thymeleaf

[Thymeleaf] 입력 폼 처리

샤아이인 2022. 1. 30.

인프런 김영한님의 Spring강의에서 공부한것을 올리며, Thymeleaf의 경우 unit 단위로 공부후 각각 정리하는 글을 작성하겠습니다.

 

입력 폼 처리

타임리프가 제공하는 입력 폼 기능을 적용하면, 기존 프로젝트의 폼 코드를 효율적으로 개선할수가 있다.

 

우선 수정할 기존 코드를 확인해 봅시다. 삼품을 수정하는 수정 Form에 해당합니다.

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <link th:href="@{/css/bootstrap.min.css}"
            href="../css/bootstrap.min.css" rel="stylesheet">
    <style>
        .container {
            max-width: 560px;
        }
    </style>
</head>
<body>

<div class="container">

    <div class="py-5 text-center">
        <h2>상품 수정 폼</h2>
    </div>

    <form action="item.html" th:action method="post">
        <div>
            <label for="id">상품 ID</label>
            <input type="text" id="id" name="id" class="form-control" value="1" th:value="${item.id}" readonly>
        </div>
        <div>
            <label for="itemName">상품명</label>
            <input type="text" id="itemName" name="itemName" class="form-control" value="상품A" th:value="${item.itemName}">
        </div>
        <div>
            <label for="price">가격</label>
            <input type="text" id="price" name="price" class="form-control" value="10000" th:value="${item.price}">
        </div>
        <div>
            <label for="quantity">수량</label>
            <input type="text" id="quantity" name="quantity" class="form-control" value="10" th:value="${item.quantity}">
        </div>

        <hr class="my-4">

        <div class="row">
            <div class="col">
                <button class="w-100 btn btn-primary btn-lg" type="submit">저장</button>
            </div>
            <div class="col">
                <button class="w-100 btn btn-secondary btn-lg"
                        onclick="location.href='item.html'"
                        th:onclick="|location.href='@{/basic/items/{itemId}(itemId=${item.id})}'|"
                        type="button">취소</button>
            </div>
        </div>

    </form>

</div> <!-- /container -->
</body>
</html>
 

이중 대표적으로 상품 ID 를 살펴봅시다. 나머지도 같은 원리로 변경됩니다.

<div>
    <label for="id">상품 ID</label>
    <input type="text" id="id" name="id" class="form-control" value="1" th:value="${item.id}" readonly>
</div>
 

기존의 코드에는 id, name이 같은 값으로 중복되고 있으며, value도 직접 타이핑 하여 지정해주고 있습니다.

이러한 과정을 한번에 처리하는 방법을 타임리프는 제공하고 있죠!

 

우선 컨트롤러를 살펴봅시다.

@GetMapping("/{itemId}/edit")
public String editForm(@PathVariable Long itemId, Model model) {
    Item item = itemRepository.findById(itemId);
    model.addAttribute("item", item);
    return "form/editForm";
}
 

컨트롤러에서는 model을 사용하고 있습니다.

model에 item을 추가하여 뷰로 넘기고 있죠!

 

이는 밑에서 사용할 th:object를 위해 먼저 해당 오브젝트 정보를 넘겨주어야 하기 때문입니다.

수정 폼이기 때문에 데이터가 담긴 오브젝트를 만들어서 뷰에 전달하는 것 이죠!

 

이번에는 바뀐 뷰를 통해 확인합시다.

우선 <form> 부분에 th:object="${item}"이 추가되었습니다. th:object는 커맨드 객체를 저장하는 부분이 됩니다.

th:object 를 적용하려면 먼저 컨트롤러에서 해당 오브젝트 정보를 넘겨주어야 합니다. 따라서 model에 데이터를 담아서 넘기는 것 입니다.

<form action="item.html" th:action th:object="${item}" method="post">
        <div>
            <label for="id">상품 ID</label>
            <input type="text" id="id" th:field="*{id}" class="form-control" readonly>
        </div>
        <div>
            <label for="itemName">상품명</label>
            <input type="text" id="itemName" th:field="*{itemName}" class="form-control">
        </div>
        <div>
            <label for="price">가격</label>
            <input type="text" id="price" th:field="*{price}" class="form-control">
        </div>
        <div>
            <label for="quantity">수량</label>
            <input type="text" id="quantity" th:field="*{quantity}" class="form-control">
        </div>

        생략....
</form>

 

이후 각각의 <input> 태그를 보면 th:field="*{id}"로 변경되어 있습니다.

*{...} : 선택 변수 식이라고 하며, th:object 에서 선택한 객체에 접근한다.

*{id} 는 선택 변수 식을 사용했는데, ${item.id}와 같습니다. 앞서 th:object 로 item을 선택했기 때문에 선택 변수 식을 적용할 수 있다.

 

th:field 를 사용하면 HTML 태그의 id, name, value 속성을 자동으로 처리해 준다. 다음과 같이 말이다!

 

- 렌더링 전

<input type="text" th:field="*{itemName}" />
 

- 렌더링 후

<input type="text" id="itemName" name="itemName" th:value="*{itemName}" />
 

이렇게 자동으로 추가해주기 때문에 개발자가 오타낼 확률이 적어진다.

예를 들어 기존의 코드는 itemNameee 과 같이 오타가 날수도 있는데, 타임리프를 활용하여 폼을 작성하면 이런부분도 방지가 된다.

 

th:object , th:field 덕분에 폼을 개발할 때 약간의 편리함을 얻었다. 쉽고 단순해서 크게 어려움은 없다.

사실 이것의 진짜 위력은 뒤에 설명할 검증(Validation)에서 나타나게 된다. 이에 대한 내용은 나중에 작성하도록 하겠다.

'BackEnd > Thymeleaf' 카테고리의 다른 글

[Thymeleaf] 체크 박스 - 멀티  (0) 2022.01.30
[Thymeleaf] 체크 박스  (0) 2022.01.30
[Thymeleaf] 레이아웃  (0) 2022.01.30
[Thymeleaf] 템플릿 조각  (0) 2022.01.29
[Thymeleaf] 자바스크립트 인라인  (0) 2022.01.28

댓글