[JS] 필터 구현해보기

19·2022년 7월 27일
0

JS

목록 보기
3/3
post-custom-banner

필터 구현 (서버)
서버에서 구현하는 거 보다 클라이언트에서 구현하는 게 더 어려웠다.
기존에 '모집중' / '모집 마감'으로 나눠서 게시글을 조회할 수 있는 필터가 있었는데, 여기에 추가적으로 구현하려 하다 보니까 꼬인? 느낌
어찌어찌 하긴 했는데, 깔끔하게 된 것 같지는 않아..ㅜ


적용

select 태그를 사용해서 필터를 적용했다.

| home.hbs

<div class="control select is-info">
    <select id="sort-post" name="sort-post" class="sort-post" onchange="sortPost()">
        <option value="1">최신순</option>
        <option value="2">인기순</option>
        <option value="3">댓글순</option>
    </select>
</div>
  • 변경이 일어나면 onChange속성을 통해 sortPost()를 실행!

| home.js

// 모집 중 / 모집 마감 버튼 클릭에 따른 이벤트
window.recruitmentStateCheckbox = () => {
    localStorage.setItem('check', $('#recruitmentStateCheckbox').is(':checked'));
    let value = $('#sort-post option:selected').val();
    if ($('input:checkbox[id="recruitmentStateCheckbox"]').is(':checked')) {
        if (value == '1') {
            getPosts();
        }
        else if (value == '2') {
            sortHitsPost();
        }
        else if (value == '3') {
            sortCommentsSizePost();
        }
    }
    else {
        if (value == '1') {
            getRecrutingPosts();
        }
        else if (value == '2') {
            sortRecruitingHitsPost();
        }
        else if (value == '3') {
            sortRecruitingCommentsSizePost();
        }
    }
};

// 필터 (Select) 변경 감지
window.sortPost = () => {
    $('#home-section-post').empty();
    let value = $('#sort-post option:selected').val();
    if ($('input:checkbox[id="recruitmentStateCheckbox"]').is(':checked')) {
        if (value == '1') {
            getPosts();
        }
        else if (value == '2') {
            sortHitsPost();
        }
        else if (value == '3') {
            sortCommentsSizePost();
        }
    }
    else {
        if (value == '1') {
            getRecrutingPosts();
        }
        else if (value == '2') {
            sortRecruitingHitsPost();
        }
        else if (value == '3') {
            sortRecruitingCommentsSizePost();
        }
    }
};

깔끔하다고 느끼지 못했던 부분이다.
조건문을 통해 '모집 완료'된 게시글까지 조회하는 체크박스가 체크되어 있는지를 확인한다.

위의 함수는 '모집 중' / '모집 마감' 버튼 클릭에 따른 이벤트를 처리하는 함수이고,
아래 함수는 필터 (select태그) 변경 감지됐을 때, value값에 따라 이벤트를 처리하는 함수이다.

  1. '모집 중' / '모집 마감' 버튼이 체크되어 있다면 변경된 select값이 1/2/3 여부에 따라 분기 처리 (모집 완료된 게시글까지 조회)
  2. '모집 중' / '모집 마감' 버튼이 체크되어 있지 않다면 변경된 select값이 1/2/3 여부에 따라 분기 처리 (모집 중인 게시글만 조회)

조회수 순 (인기순)

// 인기순 정렬 (모집 완료 포함)
window.sortHitsPost = () => {
    $('#home-section-post').empty();
    $.ajax({
        type: 'GET',
        url: process.env.BACKEND_HOST + '/post/list/hits',
        success: function (response) {
            let posts = response;

            for (let index = 0; index < posts.length; index++) {
                let id = posts[index]['id'];
                let title = posts[index]['title'];
                let meetingType = posts[index]['meetingType'];
                let period = posts[index]['period'];
                let hits = posts[index]['hits'];
                let recruitmentState = posts[index]['recruitmentState'] ? '모집 완료' : '모집 중';

                let recruitmentStateColor = posts[index]['recruitmentState'] ? 'is-default' : 'is-pink';
                let recruitmentStateColorBack = posts[index]['recruitmentState'] ? 'is-white' : 'is-gray';

                let cardHTML = `<div id=${id} class="card ${recruitmentStateColorBack}">
                                    <div class="card-header">
                                        <p class="card-header-title"token interpolation">${id})">${title}</p>
                                        <div class="content bookmark">
                                            <i class="fa-regular fa-bookmark"token interpolation">${id})"></i>
                                        </div>
                                    </div>

                                    <div class="card-content"token interpolation">${id})">
                                        <div class="card-content-box">
                                            <div class="content">
                                                <span>기간</span>
                                                <span class="bubble-item bubble">${period}</span>
                                            </div>

                                            <div class="content">
                                                <span>모임 방식</span>
                                                <span class="bubble-item bubble">${meetingType}</span>
                                            </div>

                                            <div class="content">
                                            <span>모집 현황</span>
                                            <span class="bubble-item ${recruitmentStateColor}">${recruitmentState}</span>
                                        </div>

                                        </div>
                                        <div class="card-content-box">
                                        <div>
                                            <div class="content">
                                                <i class="fa-regular fa-eye"></i>
                                                <span>${hits}</span>
                                            </div>
                                        </div>
                                        </div>
                                    </div>
                                </div>`;

                $('#home-section-post').append(cardHTML);
            }
            resizeHomeContainer();
        }
    });
};
  • 서버에 조회수 기준 내림차순으로 게시글 목록을 요청한다.



댓글 많은 순

// 댓글수 순 정렬  (모집 완료 포함)
window.sortCommentsSizePost = () => {
    $('#home-section-post').empty();
    $.ajax({
        type: 'GET',
        url: process.env.BACKEND_HOST + '/post/list/comments',
        success: function (response) {
            console.log(response);
            let posts = response;

            for (let index = 0; index < posts.length; index++) {
                let id = posts[index]['id'];
                let title = posts[index]['title'];
                let meetingType = posts[index]['meetingType'];
                let period = posts[index]['period'];
                let hits = posts[index]['hits'];
                let recruitmentState = posts[index]['recruitmentState'] ? '모집 완료' : '모집 중';

                let recruitmentStateColor = posts[index]['recruitmentState'] ? 'is-default' : 'is-pink';
                let recruitmentStateColorBack = posts[index]['recruitmentState'] ? 'is-white' : 'is-gray';

                let cardHTML = `<div id=${id} class="card ${recruitmentStateColorBack}">
                                    <div class="card-header">
                                        <p class="card-header-title"token interpolation">${id})">${title}</p>
                                        <div class="content bookmark">
                                            <i class="fa-regular fa-bookmark"token interpolation">${id})"></i>
                                        </div>
                                    </div>

                                    <div class="card-content"token interpolation">${id})">
                                        <div class="card-content-box">
                                            <div class="content">
                                                <span>기간</span>
                                                <span class="bubble-item bubble">${period}</span>
                                            </div>

                                            <div class="content">
                                                <span>모임 방식</span>
                                                <span class="bubble-item bubble">${meetingType}</span>
                                            </div>

                                            <div class="content">
                                            <span>모집 현황</span>
                                            <span class="bubble-item ${recruitmentStateColor}">${recruitmentState}</span>
                                        </div>

                                        </div>
                                        <div class="card-content-box">
                                        <div>
                                            <div class="content">
                                                <i class="fa-regular fa-eye"></i>
                                                <span>${hits}</span>
                                            </div>
                                        </div>
                                        </div>
                                    </div>
                                </div>`;

                $('#home-section-post').append(cardHTML);
            }
            resizeHomeContainer();
        }
    });
};
  • 서버에 댓글이 많은 순서대로 정렬된 게시글 목록을 요청한다.


소감

너무 어려웠따ㅏ..
select의 onChange는 변경되었을 때만 동작한다.
때문에, 모집마감/모집중 버튼만 체크/체크해제 하면 필터(인기순/댓글순)가 동작하지 않는다.
이 부분에서 많은 삐걱임이 있었지만 어찌어찌 구현은 했는데, 깔끔하게는 하지 못한 것 같다.
너무 지저분하고 중복도 있고 ㅎㅎ

profile
하나씩 차근차근
post-custom-banner

0개의 댓글