본문 바로가기

javascript

계층형 selectBox 구현하기

계층형으로 DB에 저장되어 있는 값을 가지고 상위 레벨의 selectBox를 선택하면 하위 레벨의 selectBox가 생성되는 기능을 구현해보았다.

 

<div id="lists">
    <select id="list_1" name="list_1" >
        <option value="">선택</option>
        <c:forEach items="${selectList}" var="list">
            <option value="${list.name}">${list.name}</option>
        </c:forEach>
    </select>
</div>

 

처음 페이지를 불러올 때 최상위 ROOT 데이터는 받아온 상태이므로 표출시킨다.

id는 공통되는 이름과 레벨 단위를 조합하여 만든다.

 

$(document).ajaxStop(function(){
    $("[id^='list_']").change(function() {
        fnList($(this).attr("id"), $(this).val());
    })
});

 

공통으로 시작하는 id에 change 이벤트를 걸고, 선택한 selectBox의 id와 value를 파라미터로 받는 function을 만들어준다.

select 태그 id에 val() 함수를 사용하니 선택된 옵션의 값이 들어왔다.

ajaxStop은 다음 레벨 선택시에 이전 ajax가 미완료된 상태로는 change 이벤트가 실행되지 않아서 추가해주었다.

 

 

function fnList(selectId, name) {
    let p = selectId.split('_');
    let id = p[0];
    let num = Number(p[1]) + 1;
    // 1
    if (name == '') {
        for(let i = num;;i++) {
            if ($("#"+id+"_" +i).length > 0) {
                $("#"+id+"_" +i).remove();
            } else {
                break;
            }
        }
        return;
    }

    $.ajax({
        url: "/list.do",
        type: 'POST',
        data: {"upprNm" : name},
        success: function (data) {
            let nmList = data.nmList;
            if (nmList.length > 0) {
                // 2
                for(let i = num;;i++) {
                    if ($("#"+id+"_" +i).length > 0) {
                        $("#"+id+"_" +i).remove();
                    } else {
                        break;
                    }
                }

                let html = '';
                html += '<select id="'+ id + '_' + num + '" name="' + id + '_' + num + '">';
                html += '<option value="">선택</option>';
                $.each(nmList, function(i){
                    html += '<option value="' + nmList[i].name + '">' + nmList[i].name  + '</option>';
                })
                html += '</select>';

                $("#lists").append(html);
            }
        },
        error : function(jqxhr, status, error) {
            let msg = jqxhr.status + " , " + status + " , " + error;
            alertBox(msg + "\n에러가 발생 했습니다. 관리자에게 문의 하세요");
        }
    });    
}

 

새로 추가해줄 selectBox에 1이 증가된 id를 부여할 수 있도록 파라미터로 받아온 id를 구분자로 잘라준다. 

만약 value가 없는 옵션을 선택했다면 해당 레벨 이하의 selectBox는 지워주고 return 해주기 위해 반복문 //1 을 먼저 실행한다.

ajax로 데이터를 받아온 후에도 하위 레벨은 지워야하기 때문에 반복문 //2 를 먼저 실행한다.

 

그리고 html 로 넣어줄 내용을 만들어준 다음 selectBox의 부모 태그 아이디에 append 해주면 된다.

 

 

+++ 41번 라인에서 div에 append 를 해주니 추가되는 selectBox간 간격이 맞지 않고 따로 style을 줘도 적용이 되지가 않았다. 그래서 $("#"+selectId).after(html); 로 수정하여 이전 selectBox 다음 태그에 추가되도록 하니 style이 적용되었다.