1. 개요
위와 같은 체크박스에서 구현해야 할 로직은,
- 전체 체크박스 체크 시 하위 항목 모두 체크
- 전체 체크박스 체크 해제시 하위 항목 모두 체크 해제
- 하위 항목 체크 해제시 전체 체크박스 체크 해제
- 하위 항목 모드 체크시 전체 체크박스 체크
이렇게 4가지로 볼 수 있습니다. html구성은 아래와 같습니다.
<div class="floor">
<input type="checkbox" name="all" id="all" checked>
<label for="all">전체</label>
<input type="checkbox" name="detail" id="good" checked>
<label for="good" class="mgl15">양호</label>
<input type="checkbox" name="detail" id="weak" checked>
<label for="weak" class="mgl15">취약</label>
</div>
2. 전체 선택, 해제 구현
로직을 구현하기 위해서 jquery를 이용했습니다. 구현한 로직은 아래와 같습니다.
// 전체 체크, 전체 체크 해제
$('input:checkbox[name="all"]').on('click', function(){
var chk = $(this).is(":checked");
if(chk){
$('.floor input:checkbox').prop('checked', true);
}else{
$('.floor input:checkbox').prop('checked', false);
}
});
2.1. 간결하게 리팩토링
원하는대로 동작하기는 했지만 구글링 결과 each를 사용하여 조금더 한결한 코드로 바꿀 수 있다는 것을 알았습니다.
// 전체 체크, 전체 체크 해제
$('input:checkbox[name="all"]').on('click', function (){
$(this).parent(".floor").find('input')
.prop("checked", $(this).is(":checked"));
});
전체 체크, 전체 체크해제 부분부터 보자면, name이 all인 곳에 checked값을 해당 부모 class의 input 태그의 모든 property에 주입합니다.
개별 체크는 위의 참고링크로는 해결 할 수 없었습니다. 위의 링크에서는 $(this)를 사용하며 비교하므로 모든 항목을 비교하는 것이 아닌 코드입니다.
그래서 한 항목이 체크가 해제되어 있어도 다른 항목을 체크하게 되면 전체가 체크되어 버리는 오류가 발생합니다.
3. 개별선택시 전체 항목 체크 변화
$('input:checkbox[name="detail"]').on('click', function () {
let total = $('input:checkbox[name="detail"]').length;
let checked = $('input:checkbox[name="detail"]:checked').length;
if(total == checked) $("#all").prop("checked", true);
else $("#all").prop("checked", false);
});
개별 체크는 하위 항목의 전체 개수와, 체크되어있는 항목 수를 비교하여 로직을 구현하였습니다.
4. 참고
여기서 생각할 부분은 클릭이벤트 on(‘click’)과 click()의 차이입니다. on(‘click’)은 동적으로 이벤트를 바인딩 할 수 있지만, click()은 최초에 선언된 element에만 동작합니다.
예를들어
<ul id="myTask">
<li>Coding</li>
<li>Answering</li>
<li>Getting Paid</li>
</ul>
$("#myTask").children().click(function(){$(this).remove();});
위와 같은 코드에서 li클릭하면 li 태그에 바인딩된 click이벤트가 실행되어 li 태그가 제거되지만, 동적으로 새운 li를 추가한다면 click()는 동작하지 않습니다.
click()이벤트는 최초에 페이지를 로딩할 떄 선언되어 있던 element에 이벤트를 바인딩하고 나서는 동적으로 바인딩 하지 않기 떄문입니다. 반면, on(“click”)이벤트를 사용하면 동적으로 이벤트를 바인딩 시킬 수 있습니다.
또한, click()은 element 만큼 개별 핸들러를 필요로해서 메모리 사용량이 증가합니다. on(“click”)은 하나의 핸들러가 동작합니다.
댓글남기기