today_is

[ javascript ] hidden 을 이용한 다중필터 본문

front

[ javascript ] hidden 을 이용한 다중필터

ye_rang 2024. 2. 21. 09:44

오늘의 목표

다중 필터를 이용하여, 여러개의 조건에 대한 결과를 출력하자 (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