타임리프와 스프링

바그다드·2023년 5월 6일
0

-지난 포스팅에서 타임리프의 주요 기능들에 대해서 알아봤다. 이번에는 타임리프와 스프링을 통합해서 사용하는 것에서 오는 편리한 기능을 알아보자

1. form 처리

  • 먼저 컨트롤러에서 객체를 넘겨주자
    @GetMapping("/{itemId}/edit")
    public String editForm(@PathVariable Long itemId, Model model) {
        Item item = itemRepository.findById(itemId);
        model.addAttribute("item", item);
        return "form/editForm";
    }
  • 이제 넘어온 객체를 이용하여 폼을 편하게 구성해보자
<form action="item.html" th:action th:object="${item}" method="post">
        <div>
            <label for="id">상품 ID</label>
            <input type="text" class="form-control" th:field="*{id}" readonly>
        </div>
        <div>
            <label for="itemName">상품명</label>
            <input type="text" class="form-control" th:field="*{itemName}">
        </div>
        <div>
            <label for="price">가격</label>
            <input type="text" class="form-control" th:field="*{price}">
        </div>
        <div>
            <label for="quantity">수량</label>
            <input type="text" class="form-control" th:field="*{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='@{/form/items/{itemId}(itemId=${item.id})}'|"
                        type="button">취소</button>
            </div>
        </div>

    </form>

th:object

  • th:object를 이용하여 사용할 객체를 지정한다
  • 이후에 *{}표현식을 이용하여 th:object에서 지정한 객체에 접근할 수 있다.

th:field

  • th:field="${property}"를 이용하면 id, name을 property로 설정하고, value속성은 property에 저장되어 있는 값이 들어간다.
    즉, th:field를 사용하면 id, name, value를 따로 선언하지 않아도 타임리프가 생성해준다.

2. 체크박스

  • 체크 박스의 경우 체크를 하고 값을 넘기면 on이라는 값이 넘어가고, 스프링에서는 이 값을 boolean형 데이터로 바꿔 넘겨준다.
    그런데 문제는 체크박스가 체크되어 있지 않는 경우에는 false가 넘어오는 것이 아니라 아예 파라미터 자체가 넘어오질 않는다.
    이로 인해 서버측에서는 이에 대한 처리를 하기 곤란한 상황이 발생할 수 있다.
    <!-- 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>
  • 이런 경우에 hidden타입을 하나 추가하고, 체크박스의 name에 ''를 앞에 붙여 name을 설정해주면 스프링에서 이 값을 처리해준다.
    체크 박스가 선택되어 있다면 true를, 체크되어 있지 않다면 false를 반환한다.
    - 위의 경우에는 open에
    를 붙여 _open이라고 설정하였다.
  • 하지만 일일이 히든 필드를 추가해주는 것도 불편하다ㅜㅜ
        <!-- single checkbox -->
        <div>판매 여부</div>
        <div>
            <div class="form-check">
                <input type="checkbox" th:field="*{open}" class="form-check-input">
                <label for="open" class="form-check-label">판매 오픈</label>
            </div>
        </div>
  • 앞서 사용했던 th:field를 사용하면 id,name,value를 생성하는 것에 더해서 체크 박스일 경우 위에서 name에 '_'를 추가한 hidden타입의 태그를 생성했던 것처럼 자동으로 hidden타입의 태그를 추가해준다.
  • th:field는 체크 박스의 경우 값이 true인 경우 체크를 자동으로 처리해준다.
    - 그렇지 않다면 개발자가 직접 checked라는 속성을 넣어줘야 한다.

3. 멀티

<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:field를 사용할 경우 id값이 중복되면 안되기 때문에 region1, region2 이런식으로 id가 자동으로 부여되는데 label태그의 경우 체크박스의 id를 알아야 한다. 이럴 때 사용하는 기능이 ${#ids.prev('')}나 ids.next('')를 이용해 동적으로 생성되는 id값을 사용할 수 있도록 해준다.
profile
꾸준히 하자!

0개의 댓글