today_is
[ javascript ] hidden 을 이용한 다중필터 본문
오늘의 목표
다중 필터를 이용하여, 여러개의 조건에 대한 결과를 출력하자 (OR 조건)
배열에 사용할 수 있는 함수
함수 | 기능 |
arr.forEach | 단순 반복 |
arr.filter | 조건 필터 |
arr.toSorted | 정렬 |
arr.map | 재구성 |
arr.slice | 잘라내기 |
arr.includes | 포함여부 확인 |
코드 해석
[ 다중필터 ]
boxList 는 check box의 내용을 모두 불러온것 (querySelect 로 불러온건 모두 nodeList)
-> const boxList = document.querySelectorAll('div.left > label > input[type="checkbox"]')
배열에서 원하는 속성만 가져오거나, 별도의 속성을 추가해서 가져올때 Array.map 사용
map 을 이용하여 name 속성에 있는 데이터에서 a 를 지우고(replace) 정수(+)만 남긴다
-> const checkedArray = Array.from(boxList).filter(e => e.checked).map(e => +e.name.replace('a', ''))
반복문을 이용하여, 소수점 아래 지움(floor)
-> const age = Math.floor(+tr.children[1].innerText / 10) * 10
체크박스에 체크가 되어있는 목록에서 해당 나이가 있다면
-> if(checkedArray.includes(age)) {
hidden 목록에서 제거
-> tr.classList.remove('hidden') }
아니라면, hidden 에 추가
-> else { tr.classList.add('hidden') }
체크박스를 클릭하면 filterHandler 실행
-> boxList.forEach(box => box.onclick = filterHandler
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#root {
display: flex;
width: 500px;
height: 350px;
}
.left {
display: flex;
flex-direction: column;
width: 100px;
}
.left > label {
flex: 1
}
table {
border-collapse: collapse;
border: 2px solid black;
}
td {
border: 1px solid grey;
padding: 10px 20px;
}
tr.hidden {
display: none;
}
</style>
</head>
<body>
<h1>다중조건필터</h1>
<hr>
<div id="root">
<div class="left">
<label><input type="checkbox" name="a10">10대</label>
<label><input type="checkbox" name="a20">20대</label>
<label><input type="checkbox" name="a30">30대</label>
<label><input type="checkbox" name="a40">40대</label>
<label><input type="checkbox" name="a50">50대</label>
</div>
<div class="right">
<table>
<tr>
<td>남도일</td>
<td>17</td>
</tr>
<tr>
<td>카리나</td>
<td>25</td>
</tr>
<tr>
<td>이지은</td>
<td>31</td>
</tr>
<tr>
<td>홍진호</td>
<td>42</td>
</tr>
<tr>
<td>유재석</td>
<td>51</td>
</tr>
<tr>
<td>천우희</td>
<td>37</td>
</tr>
<tr>
<td>윈터</td>
<td>23</td>
</tr>
<tr>
<td>나루토</td>
<td>16</td>
</tr>
</table>
</div>
</div>
<!-- 다중 필터 -->
<script>
const boxList = document.querySelectorAll('div.left > label > input[type="checkbox"]') // NodeList
function filterHandler(event) {
const checkedArray = Array.from(boxList).filter(e => e.checked).map(e => +e.name.replace('a', ''))
console.log(checkedArray)
const trList = document.querySelectorAll('table > tbody > tr')
trList.forEach(tr => {
const age = Math.floor(+tr.children[1].innerText / 10) * 10
if(checkedArray.includes(age)) {
tr.classList.remove('hidden')
}
else {
tr.classList.add('hidden')
}
})
}
boxList.forEach(box => box.onclick = filterHandler)
</script>
</body>
</html>
[ 만약, 클릭이벤트의 대상만 처리한다면 (다중조건 X) ]
<script>
const boxList = document.querySelectorAll('div.left > label > input[type="checkbox"]')
function filterHandler(event) {
// 배열에서 원하는 속성만 가져오거나
// 별도의 속성을 추가해서 가져올때 Array.map 사용
const checkedArray = Array.from(boxList).map(e => {
const ob = {
age : +e.name.replace('a', ''),
checked : e.checked
}
return ob
})
console.log(checkedArray)
// 만약, 다중조건이 아니라 클릭이벤트의 대상만 처리한다면
const flag = +event.target.name.replace('a', '')
const trList = document.querySelectorAll('table > tbody > tr')
trList.forEach(tr => {
const value = +tr.children[1].innerText
if(flag <= value && value < flag + 10 ) {
tr.classList.remove('hidden')
}
else {
tr.classList.add('hidden')
}
})
}
boxList.forEach(box => box.onclick = filterHandler)
</script>
결과
[ 필터 사용전 원본 ]
[ 20대 필터링 결과 ]
[ 10, 20, 30대 필터링 결과 ]
study_review
처음에는 opacity를 생각했지만, 해당 요소의 배치는 페이지에서 여전히 남아있기 때문에 새로운 방법을 모색하게 되었다
원본 데이터를 삭제하지 않고 필요에 따라 잠시 숨기는 방법을 찾다가 hidden 속성을 떠올릴 수 있었다
조건 충족 여부에 따라 해당 클래스에 hidden을 추가하거나 삭제하여,
사용자 입장에서는 조건에 맞지 않는 데이터는 보이지 않도록 로직을 구성했다 !
이걸 이용해서, 프로젝트에 사용해도 좋을 것 같다 !
'front' 카테고리의 다른 글
[ javascript - AJAX ] (0) | 2024.02.20 |
---|---|
[ js ] json 파일로 화면 구현 (0) | 2024.02.19 |
[ javascript ] 검색필터 (0) | 2024.01.26 |
[ javascript ] 클릭이벤트 (0) | 2024.01.24 |
[ javascript ] 정렬 (0) | 2024.01.22 |