[JS] 탭 + 체크박스로 선택값 보여주기

merci·2023년 2월 25일
0

구인구직 프로젝트

목록 보기
2/10

구직사이트를 만들다가 체크박스에서 체크된 조건에 따라 검색을 하고 싶었다.

이것 저것 검색해서 만들었는데 까먹기 전에 기록하자.



버튼 탭 active 속성 주기

체크박스에 4개의 탭이 있는데 각 탭을 눌렀을때 아래의 테이블이 바껴야 한다.

탭을 구현한 코드는

        <ul class="nav nav-pills nav-justified">
            <li class="nav-item mx-2">
                <button class="nav-link active tap-btn" id="btn1" onclick="openTab(event, 'tab1')">지역별</button>
            </li>
            <li class="nav-item mx-2">
                <button class="nav-link tap-btn" " id="btn2" onclick="openTab(event, 'tab2')">기술별</button>
            </li>
            <li class="nav-item mx-2">
                <button class="nav-link tap-btn" id="btn3" onclick="openTab(event, 'tab3')">직무별</button>
            </li>
            <li class="nav-item mx-2">
                <button class="nav-link tap-btn" id="btn4" onclick="openTab(event, 'tab4')">경력별</button>
            </li>
        </ul>



선택된 버튼은 class="active"를 가져야 불이 들어오는데 이를 위해서 openTab()함수를 등록한다.

    function openTab(evt, tabName) {
        let tablinks;
        // 모든 탭 버튼에서 active 클래스를 제거
        tablinks = document.getElementsByClassName("tap-btn");
        for (i = 0; i < tablinks.length; i++) {
            tablinks[i].classList.remove("active");
        }
        evt.currentTarget.classList.add("active");
    }

getElementsByClassName() 를 이용하면 내가 지정해준 이름을 가진 모든 태그를 컨트롤할 수 있다.
리턴하는 값은 배열이므로 반복을 이용한다.

classList를 이용하면 각각의 태그의 class 속성에 접근할 수 있다.
이벤트의 currentTarget은 내가 조작한 태그를 가져온다.


다른 탭을 누르면 다른탭에 불이 들어온다. ( 중간에 초기화 버튼 추가함)




테이블 변경하기

탭 선택에 따른 다른 테이블을 보여주기 위해서는 다음과 같은 코드가 필요하다.

    document.getElementById("btn1").addEventListener("click", function () {
        changeTable("btn1");
    });
    document.getElementById("btn2").addEventListener("click", function () {
        changeTable('btn2');
    });
    document.getElementById("btn3").addEventListener("click", function () {
        changeTable("btn3");
    });
    document.getElementById("btn4").addEventListener("click", function () {
        changeTable("btn4");
    });



버튼 태그의 id를 이용해서 클릭시 동작할 함수를 등록한다.

    function changeTable(btn) {
        if (btn === 'btn1') {
            $("#my-table-body1").show();
            $('#my-table-body2').hide();
            $('#my-table-body3').hide();
            $('#my-table-body4').hide();
        }
        if (btn === 'btn2') {
            $("#my-table-body1").hide();
            $('#my-table-body2').show();
            $('#my-table-body3').hide();
            $('#my-table-body4').hide();
        }
        if (btn === 'btn3') {
            $("#my-table-body1").hide();
            $('#my-table-body2').hide();
            $('#my-table-body3').show();
            $('#my-table-body4').hide();
        }
        if (btn === 'btn4') {
            $("#my-table-body1").hide();
            $('#my-table-body2').hide();
            $('#my-table-body3').hide();
            $('#my-table-body4').show();
        }
    }



함수로 들어온 파라미터를 조건으로 각 테이블을 show()hide() 로 조작한다.

<div id="my-table-body1" style="display: block;">  // 초기 테이블 설정
<div id="my-table-body2" style="display: none;">   // 두번째 테이블
<div id="my-table-body2" style="display: none;">   // 세번째 테이블
<div id="my-table-body2" style="display: none;">   // 네번째 테이블




체크박스 선택

체크박스를 선택하면 선택된 조건들을 표시하고 싶었다.
이를 위해서는 각 체크박스를 클릭했을때 반응할 함수를 등록해야 한다.

    const checkboxes = document.querySelectorAll('input[type="checkbox"]');

위 코드를 이용해서 type="checkbox" 의 속성을 가진 input태그들을 checkboxes 배열에 저장한다.

checkboxes.forEach(function (checkbox) {
        checkbox.addEventListener('click', function () {
            addressValues = getCheckedValues("address");
            skillValues = getCheckedValues("skill");
            positionValues = getCheckedValues("position");
            careerValue = $("input[name='career']:checked").val();
        });
    });

forEach를 이용해서 배열을 순환하면서 각 체크박스에 함수를 등록한다.


내부 함수인 getCheckedValues() 는 다음과 같다.

    let addressValues;
    let skillValues;
    let positionValues;
    let careerValue;

    function getCheckedValues(name) {
        var checkedValues = [];
        var checkboxes = document.getElementsByName(name);
        for (var i = 0; i < checkboxes.length; i++) {
            if (checkboxes[i].checked) {
                checkedValues.push(checkboxes[i].value);
            }
        }
        return checkedValues;
    }

입력된 name을 가진 태그들을 순환하는데 각 체크박스가 체크되었다면 checkedValues 배열에 체크박스의 value를 저장 후 배열을 리턴한다.

각 탭에 따른 체크박스의 name은 address, skill, position, career 인데 체크된 value들을 저장했으면 ajax를 이용해서 선택한 배열로 비동기 통신을 한다.

검색해보고 비슷하지만 다른 코드도 추가함

	$("input:checkbox[name='categoryName']").each(function() {
    		if ($(this).is(":checked ")) {
    			categoryName.push($(this).val());
            }
    	});




ajax로 배열 통신

각 버튼이 클릭되었을때 선택된 버튼에 따른 결과값을 다음처럼 보여주고 싶었다.

이를 위해선 체크박스를 클릭할때마다 ajax로 통신을 해야하는데 체크박스 이벤트 리스너에 등록된 함수에 ajax를 추가한다.

    checkboxes.forEach(function (checkbox) {
        checkbox.addEventListener('click', function () {
            addressValues = getCheckedValues("address");
            skillValues = getCheckedValues("skill");
            positionValues = getCheckedValues("position");
            careerValue = $("input[name='career']:checked").val();

            let data = {
                address: addressValues,
                skill: skillValues,
                position: positionValues,
                career: careerValue
            }
            $.ajax({
                type: "post",
                url: "/jobs/info/list",
                data: JSON.stringify(data),
                headers: {
                    "content-type": "application/json; charset=utf-8"
                },
                dataType: "json"
            }).done((res) => {
                newbtn(res.data);
            }).fail((err) => {
            });
        });
    });

선택된 배열들은 data 에 넣고 JSON.stringify(data)으로 json 으로 변환한뒤 post 요청을 보낸다.
get을 해도 되지만 주소창이 너무 길어질것 같아서 post로 보내고 싶었다.



요청을 받는 컨트롤러는

    @PostMapping("/jobs/info/list")
    public ResponseEntity<?> searchJobsSize(@RequestBody JobsCheckBoxReqDto jDto, Model model){
        if( jDto.getCareer() == null || jDto.getCareer().isEmpty()){
            jDto.setCareer("");
        }
        List<JobsSearchRespDto> jDtos = jobsRepository.findByCheckBox(jDto);
        return new ResponseEntity<>(new ResponseDto<>(1, "검색 성공", jDtos.size()), HttpStatus.OK);
    }

career 는 라디오 버튼으로 선택되지 않으면 공백으로 변환해줬다.
검색을 하는 findByCheckBox() 메소드는 입력된 데이터를 조건으로 걸어서 레코드의 수를 리턴해준다.




체크박스에 선택된 내용 표시

ajax로 선택된 내용을 전송하는것도 중요하지만 화면에서 현재 선택된 체크박스들을 보여주고 싶었다.

rendering() 함수를 이용해서 선택된 체크박스를 표현해보자.

    const checkboxes = document.querySelectorAll('input[type="checkbox"]');
    function rendering(checkboxes) {
        if (checkboxes.length > 0) {
            checkboxes.forEach(function (checkbox) {
                render(checkbox);
            });
        }
    }

    function render(values) {
        if (values !== undefined) {
            let el = `
            <h5 class="selectBox-remove me-2"><span class="badge bg-light text-dark" 
					   value=`+ values + `>` + values + `  X 
            </span>
            </h5>
        `;
            $('#selected').append(el);
        }
    }

선택된 체크박스가 존재할때 각 체크박스를 render() 로 그린다.

체크박스를 선택하지 않으면 value가 undefined 이므로 선택되었다면 위와 같은 간단한 태그를 테이블 밑에 append()로 추가한다.

체크박스가 추가선택 되면 추가된것만 그려야 하는데 foreach를 이용해서 그리면 누적된 내용이 추가되므로 간단한게 지우고 다시 그려봤다.

    const checkboxes = document.querySelectorAll('input[type="checkbox"]');
    checkboxes.forEach(function (checkbox) {
        checkbox.addEventListener('click', function () {
            addressValues = getCheckedValues("address");
            skillValues = getCheckedValues("skill");
            positionValues = getCheckedValues("position");
            careerValue = $("input[name='career']:checked").val();

            let data = {
                address: addressValues,
                skill: skillValues,
                position: positionValues,
                career: careerValue
            }
            $('.selectBox-remove').remove();
            rendering(addressValues);
            rendering(skillValues);
            rendering(positionValues);
            render(careerValue);

            // $('.remove-card').remove();
            $.ajax({
                type: "post",
                url: "/jobs/info/list",
                data: JSON.stringify(data),
                headers: {
                    "content-type": "application/json; charset=utf-8"
                },
                dataType: "json"
            }).done((res) => {
                newbtn(res.data);
            }).fail((err) => {
            });
        });
    });


제대로 통신을 받으면 newbtn(res.data)을 실행한다.

    function newbtn(num){
        $('#search-info-btn').text( "'"+num+"' 건 검색하기");
    }



버튼을 선택하고 다른 탭으로 이동해서 선택해도 잘 표현된다.

profile
작은것부터

0개의 댓글