새로운 웹을 개발하게 되어 작업을 하던 중
회원가입에 들어가는 약관 동의 체크박스를 만들게 되었습니다.
그런데 그냥 체크박스만 하면 되는게 아니라
- 전체 선택
- 전체 해제
- 전체선택 후 하나만 해제했을 때, 전체선택도 해체 해주기
- 개별 선택으로 전체 다 선택되었을 때, 전체선택에도 체크 해주기
등 조건이 많았습니다.
이전에도 만든 일이 있었지만 또 헤매어서 이번 기회에 정리를 해보면 좋을 것 같아 작성합니다.
jquery를 사용합니다.
결론만 알고 싶으시다면 마지막에 있습니다.
다만 많은 분들께서 내용이 좋다고 해주셔서 프론트엔드에 막 입문하신 분께서는 한번 찬찬히 읽어보시길 추천드립니다.
고민하는 과정을 기록해 놓았습니다.
예제 HTML
<div class="checkbox_group">
<input type="checkbox" id="check_all" >
<label for="check_all">전체 동의</label>
<input type="checkbox" id="check_1" class="normal" >
<label for="check_1">개인정보 처리방침 동의</label>
<input type="checkbox" id="check_2" class="normal" >
<label for="check_2">서비스 이용약관 동의</label>
<input type="checkbox" id="check_3" class="normal" >
<label for="check_3">마케팅 수신 동의</label>
</div>
저는 checkbox_group 이라는 div를 하나 만들어서 그 안에서만 작동하도록 만들겠습니다.
혹시 여러개를 한 페이지에 써야 할 지도 모르니까요 or 컴포넌트 형식으로 만들기 위해서입니다.
전체선택에만 check_all 이라는 아이디를 주고,
나머지 요소에는 normal 이라는 클래스를 주어 구별하였습니다.
구현 과정
1. 전체 선택
2. 전체 해제
전체 선택, 전체 해제는 쉽습니다.
// 체크박스 전체 선택
$(".checkbox_group").on("click", "#check_all", function () {
var checked = $(this).is(":checked");
if(checked){
$(this).parents(".checkbox_group").find('input').prop("checked", true);
} else {
$(this).parents(".checkbox_group").find('input').prop("checked", false);
}
});
먼저 전체선택이 체크가 되어있는지 확인 한 후,
체크가 되어 있으면 div.checkbox_group 의 input들에 모두 checked, true 속성을 줍니다.
체크가 해제 되면 모두 checked, false 속성을 줍니다.
3. 전체선택 후 하나만 해제했을 때, 전체선택도 해체 해주기
전체선택이 아닌 나머지 요소들을 클릭 했을 때에만 작동해야 하므로 normal 클래스 클릭시에만 작동하도록 합니다.
// 체크박스 개별 선택
$(".checkbox_group").on("click", ".normal", function() {
var checked = $(this).is(":checked");
if (!checked) {
$("#check_all").prop("checked", false);
}
});
그 요소의 checked 속성을 판단한 뒤, 체크 해제가 되어 있다면 전체선택의 체크박스도 해제되어야 합니다.
그렇다고 전체 해제가 되는건 아닙니다.
4. 개별 선택으로 전체 다 선택되었을 때, 전체선택에도 체크 해주기
이 부분에서 시간을 좀 썼습니다.
예를 들어, id가 check_1, check_2 만 선택되어 있을 때에는 전체선택이 되지 않았을 때입니다.
그런데 check_3이 체크가 되면 전체선택이 된 것이기 때문에 전체 선택에도 체크가 되어야 합니다.
첫번째 방법으로는
1. normal을 클릭한다.
2. each로 normal의 체크 여부를 검사한다.
3. 배열에 넣어준다.
4. 그 배열에 false가 하나라도 있으면 전체선택을 해제한다.
이렇게 하려고 만들고 있었습니다.
그런데 결국 어찌됐든 false가 하나만 있으면 전체 선택을 해제 해주면 된다는 생각에
다시 생각해보았습니다.
그래서 나온
두번째 방법은 and or을 이용한 방식입니다.
1. normal을 클릭한다.
2. each로 normal의 체크 여부를 검사한다.
3. true인 값에 false가 하나라도 들어가면 false가 나오도록 &&을 쓴다.
4. false가 나왔으니 전체선택을 해제한다.
두 방법을 글로 적으니 4줄로 같게 나오는 것 같아 왜 바꾸나 싶은 것도 있지만
첫번째 방법에서 배열을 이용하면 배열 만드랴, 배열에 값들 넣으랴, 배열 다 검사하랴 불편해 보였습니다.
하지만 두번째 방법에서는 하나의 값이 마지막에 나오는게 true냐 false냐에 따라만 구분해주면 됩니다.
그래서 나온 코드는 위에서 이어서,
// 체크박스 개별 선택
$(".checkbox_group").on("click", ".normal", function() {
var checked = $(this).is(":checked");
if (!checked) {
$("#check_all").prop("checked", false);
} else {
var is_checked = true;
$(".checkbox_group .normal").each(function(){
is_checked = is_checked && $(this).is(":checked");
});
if(!checked){
$("#check_all").prop("checked", false);
}
}
});
이렇게 나왔고, 작동이 잘 되었습니다.
그런데 뭔가.. 쓸데없이 길다는 생각에 살펴보니 제일 마지막 줄이 거슬립니다.
그래서 이렇게 바꿨습니다.
// 체크박스 개별 선택
$(".checkbox_group").on("click", ".normal", function() {
var checked = $(this).is(":checked");
if (!checked) {
$("#check_all").prop("checked", false);
} else {
var is_checked = true;
$(".checkbox_group .normal").each(function(){
is_checked = is_checked && $(this).is(":checked");
});
$("#check_all").prop("checked", is_checked);
}
});
그래서 됐다~ 하고 글을 적고 있으니, 다시 보이는 허점...
each로 하나씩 돌려서 검사할거면 위에 코드가 없어도 되지 않나 싶었습니다.
// 체크박스 개별 선택
$(".checkbox_group").on("click", ".normal", function() {
var is_checked = true;
$(".checkbox_group .normal").each(function(){
is_checked = is_checked && $(this).is(":checked");
});
$("#check_all").prop("checked", is_checked);
});
다 쓰고나니 엄청 간결해졌네요.
블로그 글을 쓰는 의미가 하나 더 생긴 것 같습니다.
코드에 대해서 더 자세히 살펴 볼 기회도 되었습니다.
정리
예제 HTML
<div class="checkbox_group">
<input type="checkbox" id="check_all" >
<label for="check_all">전체 동의</label>
<input type="checkbox" id="check_1" class="normal" >
<label for="check_1">개인정보 처리방침 동의</label>
<input type="checkbox" id="check_2" class="normal" >
<label for="check_2">서비스 이용약관 동의</label>
<input type="checkbox" id="check_3" class="normal" >
<label for="check_3">마케팅 수신 동의</label>
</div>
JS
// 체크박스 전체 선택
$(".checkbox_group").on("click", "#check_all", function () {
$(this).parents(".checkbox_group").find('input').prop("checked", $(this).is(":checked"));
});
// 체크박스 개별 선택
$(".checkbox_group").on("click", ".normal", function() {
var is_checked = true;
$(".checkbox_group .normal").each(function(){
is_checked = is_checked && $(this).is(":checked");
});
$("#check_all").prop("checked", is_checked);
});
코드가 짧아지는건 언제나 보기 좋습니다.
자유롭게 링크 공유해주세요~
'웹 프로그래밍' 카테고리의 다른 글
[JS] var, let, const 비교, 차이 (0) | 2020.05.13 |
---|---|
[JS] input[type=input] 일 때, 글자 수 제한 (0) | 2020.05.07 |
[CORS] 가끔씩 겪는 CORS, 로컬에서 발생시 해결 (0) | 2020.04.10 |
[Node.js] PM2 서버 자동 실행 하는 명령어 및 방법 (0) | 2020.04.07 |
[DB] 데이터베이스 기본 개념 (0) | 2020.04.04 |
댓글