[thymeleaf] 단일 체크박스

Kade Jeon·2024년 3월 2일
0

Thymeleaf

목록 보기
20/22

checkbox의 한계

html input 타입 중 checkbox는 태생적으로 가지는 한계가 있다. 그것은 바로 체크가 되지 않았을 때 값이 아예 넘어오지 않는다는 것. 개발자는 체크시에는 true로 미체크시에는 false로 값을 받는다면 좋겠지만 checkbox는 그렇게 호락호락한 친구가 아니다.

checkbox는 선택이 되었을 때, on이라는 값이 전송되고 이를 true로 컨버팅하여 알려준다.
하지만, 선택이 되지 않았을 때는 아예 name이 전송되지 않는다.

Spring이 checkbox를 처리하는 방법

스프링MVC는 이와 같은 경우에 히든 타입의 태그를 넣어서 처리를 도와주고 있다. 이때 이름은 체크박스의 이름에 언더바(_)를 넣어준다.

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

이렇게 처리하면 두 가지 케이스가 발생하게 된다.
1. open_open 이 함께 전송된 경우
→ 이때는 open으로 넘어오는 on 값을 이용한다.
2. _open 만 전송된 경우
→ open에 값이 없는 것으로 판단하여 false로 처리해준다.

궁금증

  1. hidden 필드를 넘겨줄 때, _open만 전송된 경우 value가 on이 아닌 어떤 값이 넘어가든 상관없지 않을까?
    → 테스트 결과 value를 어떤 값으로 바꿔도 문제가 되지 않았다.
  2. 그럼 아예 value를 지워버리면 어떻게 될까? 값이 전송되지 않아서 _open도 전송되지 않을까?
    → 테스트 결과 value를 지워도 _open은 전송되기 때문에 문제 없이 작동했다.

따라서 이 방식은 _open의 값(value)는 전혀 상관없고, 전송이 될 때 open과 _open이 같이 전송되느냐 아니냐만 고려하는 것으로 확인했다. 이 결과를 활용한다면 단순히 히든 태그만 넣어주는 것으로도 문제없이 사용할 수 있어보인다.

<div class="form-check">
	<input type="checkbox" id="open" name="open" class="form-check-input" />
	<input type="hidden" name="_open" /> <!--히든 필드 추가 -->
	<label for="open" class="form-check-label">판매오픈</label>
</div>

타임리프가 checkbox를 처리하는 방법

타임리프에서는 스프링MVC가 처리하는 방법을 이용해서 자동으로 처리를 도와준다. 다만, 이를 활용하려면 th:field 를 이용한다.
폼 태그 때와 동일하게 th:object를 사용했다면 *{...} 로도 표기가 가능하고 ${...} 로도 표기가 가능하다.

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


폼 생성 시에 이렇게 처리해주면 스프링MVC가 처리하듯이 히든 태그를 자동으로 만들어준다. 따라서 체크박스가 체크되지 않았을 때는 false로 처리되게끔 자동으로 도와준다.


작성된 폼을 확인할 때도 이를 확인할 수 있는데 이때 페이지 소스 보기를 통해 확인해보면 체크되어있는 경우에는 checked="checked" 를 확인할 수 있다.


만약, 체크가 되지 않은 경우에는 checked="checked" 가 없어서 체크표시가 되지 않은 채로 보여진다.

profile
안녕하세요. 백엔드 개발자가 되고 싶은 Kade 입니다.

0개의 댓글