html input 타입 중 checkbox는 태생적으로 가지는 한계가 있다. 그것은 바로 체크가 되지 않았을 때 값이 아예 넘어오지 않는다는 것. 개발자는 체크시에는 true로 미체크시에는 false로 값을 받는다면 좋겠지만 checkbox는 그렇게 호락호락한 친구가 아니다.
checkbox는 선택이 되었을 때, on이라는 값이 전송되고 이를 true로 컨버팅하여 알려준다.
하지만, 선택이 되지 않았을 때는 아예 name이 전송되지 않는다.
스프링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로 처리해준다.
따라서 이 방식은 _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>
타임리프에서는 스프링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"
가 없어서 체크표시가 되지 않은 채로 보여진다.