타임리프 - 요구사항 추가(체크박스, 라디오 버튼, 설렉트 박스)

slee2·2022년 2월 1일
0

타임리프를 사용해서 폼에서 체크박스, 라디오 버튼, 설렉트 박스를 편리하게 사용하는 방법을 알아본다.

  • 판매여부
    • 판매 오픈 여부
    • 체크 박스로 선택
  • 등록지역
    • 서울, 부산, 제주
    • 체크 박스로 다중 선택 가능
  • 상품 종류
    • 도서, 식품, 기타
    • 라디오 버튼으로 하나만 선택
  • 배송 방식
    • 빠른 배송
    • 일반 배송
    • 느린 배송
    • 설렉트 박스로 하나만 선택

상품 종류 (enum)

상품 종류는 ENUM을 사용했고, 설명을 위해 description필드를 추가했다.

배송방식

배송방식의 codeFAST같은 시스템에서 전달하는 값,
displayName빠른 배송같은 고객에게 보여주는 값

상품

체크박스

판매 여부의 체크를 통한 값 전달에 대해 알아보자. 먼저 타임리프 기능 없이 일반 순수 HTML을 통해 값을 전달한다.

컨트롤러에서 값을 받으면 컨트롤러에서 로그가 찍힐 것이다.

먼저 판매 오픈에 체크를 했을 경우,

폼 데이터에서 on이라고 입력되고 스프링은 이를 True로 넣어준다.

그렇다면, 체크를 안하면 어떻게 될까

폼 데이터에서는 값이 없게 되고 null이 들어가게 된다.

HTML checkbox의 특징이다. 체크가 안됐을 경우 값 자체를 보내지 않는다. 이 특징은 수정을 할때 문제가 발생할 수도 있다. 서버에서 값이 아예 들어오지 않는 것이 의도적으로 넣지 않은 것인지 알 수 없다.

여기서 스프링MVC는 트릭을 하나 사용하는데 히든 필드를 하나 만들어서 _open처럼 기존 체크 박스이름 앞에 _를 붙여서 전송하면 체크를 해제했다고 인식하게 할 수 있다.

_open=on
보기와 같이 체크가 해제되었을때 _open 필드는 무조건 값이 들어가고 그 조건으로 open값에 false를 넣는 방식이다.

만약에 체크박스에 체크가 오게 되면
open=on&_open=on
스프링 MVC는 open에 값이 있는 것을 확인하고 이때 _open은 무시한다.

하지만, 체크박스를 만들때마다 이를 일일이 만드는 것도 불편하기 때문에

이를 타임리프가 해결해준다.

체크박스 - 타임리프

th:field를 통해 값을 넣어준다.(*{open}도 가능) 그럼 실행할때 어떻게 나올까

id, name을 넣어줄 뿐만 아니라 hidden 태그도 자동으로 만들어 준다.

그러므로 MVC 트릭이 잘 작동하게 된다.

또, 저장후 완료된 모습을 보여주기 위해 체크박스에 값을 넣어주면

이런식으로 되는데, 원래라면 checked 속성은 값이 있기만 해도 체크가 되는 특징이 있어 if문을 통해 값이 있으면 속성 넣고 없으면 안넣는 로직을 따로 만들어야 하는데 th:field를 넣으면 이것도 알아서 처리를 해서 값이 있으면 속성을 넣고 없으면 속성 자체를 없애준다.

요약 : th:field는 킹왕짱이다.

멀티 체크박스

지역을 넣기 위해 모델에 다음 값들을 넣는다.(LinkedHashMap을 사용하면 순서대로 값이 들어가게 할 수 있다.) 그런데 여기서 이 값들을 아이템 추가할 때 뿐만 아니라, 아이템 세부사항, 아이템 수정에도 모두 넣어줘야한다.

그렇기 때문에 이런 공통사항을 한곳에 묶을 수 있는 기능이 있다.

이렇게 작성을 하면 이 컨트롤러 안에서 실행된 모든 메서드의 모델에 regoins에 반환값이 자동으로 들어가게 된다. 이 방법을 이용하면 일일이 모든 모델에 값을 넣지 않아도 된다.

다만, 성능 최적화에 고민을 해볼 필요는 있다. 모든 모델에 일일이 값을 넣기 때문이다.

여기서 th:field로 인해 id와 name이 자동으로 생성된다. name은 중복으로 생성되지만 id는 다르게 생성된다. 그렇다면 이 each문에서 label태그를 클릭해도 체크가 되게끔 inputid에 연결하고 싶은데 어떻게 해야 할까

th:for="${#ids.prev('regions')}"
타임리프의 기능중에 #ids라는게 있다. 이는 쉽게 말해 regoins 필드의 아이디를 자동으로 가져오겠다는 의미이다.

이런 식으로 아이디를 잘 가져올 수 있다.

또, 이 경우에도 _regoins가 히든값에 들어가기 때문에

이런식으로 빈 배열이 오게 된다. 히든값이 없다면 null로 들어오게 된다.

라디오 버튼

요걸 쓸거다

ENUM에서 values를 사용하면 ENUM의 모든 데이터를 배열로 만들어준다.

그런데 소스코드를 보면 실행했을때 hidden 태그가 없다. 체크박스의 경우에는 히든 태그를 넣지만, 라디오는 넣지 않는다.

그래서 출력은

이렇게 아무것도 선택하지 않을 경우 null 이 들어가게 된다. 라디오는 상품 상세나 상품 수정에 큰 영향을 주지 않기 때문에 특별한 트릭이 따로 없다. 또, 라디오의 경우 한 번 체크가 되면 취소가 안되기 때문에 이에 대한 트릭이 필요없는 것도 있다.

타임리프에서 ENUM 접근

<div th:each="type : ${T(hello.itemservice.domain.item.ItemType).values()}">

스프링EL 문법으로 직접 접근할 수도 있다.

그런데 이렇게 사용하면 ENUM의 패키지 위치가 변경되거나 할때 자바 컴파일러가 타임리프까지 컴파일 오류를 잡을 수 없으므로 추천하지는 않는다.

설렉트 박스

예제에서는 new로 일일이 생성해서 넣어줬지만, 실제로는 다른곳에서 static으로 데이터를 만들고 사용하는 것이 좋다.

option이라는 태그를 이용해 저렇게 선택할 수 있는지 처음알았다.

0개의 댓글