드래그해서 순서를 바꿀 수 있는 리스트 만들기(jQuery UI - Sortable)

프로그래밍/자바스크립트 2018. 8. 31. 22:47
반응형

순서가 있는 리스트에서 드래그 앤 드랍을 이용해서 아이템의 순서를 바꿀 수 있는 UI(사용자 인터페이스)가 jQuery UI에서 지원이 됩니다. Sortable 기능을 사용하면 원하는 기능을 구현할 수 있습니다.


jQuery UI 사이트의 예제에는 기존에 존재하는 리스트 항목을 드래그 앤 드랍으로 순서를 바꿀 수 있는 예제만 나옵니다. 이 글에서는 순서를 바꾸는것 외에 아이템을 추가하고, 삭제하는 기능까지 구현해 보겠습니다.


첫 번째 예제는 Sortable의 기본 기능을 확인해보고, 두 번째 예제에서는 추가, 삭제 기능도 포함된 예제를 보도록 하겠습니다.



1. 필요한 js 라이브러리들 불러오기


<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />

<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js" ></script>

<script type="text/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js" ></script>


jQuery 라이브러리, jQuery UI 라이브러리와 스타일 시트가 필요합니다. 예제에서는 외부 라이브러리를 불러 사용했지만 필요하다면 다운로드 받아서 사이트에 넣어서 사용해도 됩니다.



2. Sortable 기본 기능


예제는 <ul> 태그를 사용하여 리스트를 구현한 것 입니다. 실행결과를 먼저보고, 예제 코드를 보도록 하겠습니다.



2.1. 예제 실행 결과




결과 이미지는 세 번째 아이템을 드래그해서 네 번째 아래로 이동중인 상태입니다. jQuery UI를 사용하면 이런 구현현을 쉽게 할 수 있습니다.



2.2. 리스트 구현 태그


드래그 가능한 리스트에 사용된 기본 HTML 소스가 되겠습니다. <ul> 태그를 사용했지만, 내부에 다른 태그를 가질 수 있는 어떤 태그도 가능합니다.


<ul id="sortable">

  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>

  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>

  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>

  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>

  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>

</ul>


"ui-state-default""ui-icon", "ui-icon-arrowthick-2-n-s" 클래스는 jQuery UI 스타일 시트에 포함되어 있습니다.



2.3. 드래그 가능한 리스트로 만들기


$(function() {

    $("#sortable").sortable();

    $("#sortable").disableSelection();

});


- $("#sortable").sortable() : id가 "sortable" 인 태그의 내부에 포함된 태그를 사용해서 드래그 가능한 리스트를 만듭니다.

- $("#sortable").disableSelection() : 이 부분은 반드시 필요한 부분은 아닌데, 아이템 내부의 글자를 드래그 해서 선택하지 못하도록 하는 기능 입니다.



간단하게 jQuery UI Sortable의 기본 기능을 알아 보았습니다. 이제는 드래그 하여 순서를 변경할 수 있는 리스트에 아이템을 추가하고 삭제할 수 있는 예제를 만들어 보겠습니다. 이 예제는 <div> 태그를 사용해서 구현했습니다.



3. 추가, 삭제 기능이 있는 리스트 만들기


리스트의 기능입니다.

- 순서 텍스트와 입력필드를 가진 아이템을 리스트에 추가합니다.

- 각 아이템들을 마우스로 드래그해서 순서를 변경할 수 있습니다.

- 순서 변경시 아이템의 번호는 화면 순서대로 다시 매겨집니다.

- 아이템에 마우스를 오버하면 "삭제" 버튼이 보여지고 클릭하면 삭제됩니다.





3.1. UI 에사용된 태그 입니다.


<div>

    <div style="float:left;width:100px;">아이템 추가 : </div>

    <div style="clar:both;">

        <input type="button" id="addItem" value="추가" onclick="createItem();" />

        <input type="button" id="submitItem" value="제출" onclick="submitItem();" />

    </div>

</div>

<br />

<div id="itemBoxWrap"></div>



- "추가" 버튼은 아이템을 리스트에 추가합니다.

- "제출" 버튼은 아이템내의 입력필드에 입력한 내용을 제출하는 것을 가정합니다.

- <div id="itemBoxWrap"></div> : 리스트가 생성될 태그 입니다.



3.2. 리스트를 구성할 스타일 시트


<style>

.itemBox {

    border:solid 1px black;

    width:400px;

    height:50px;

    padding:10px;

    margin-bottom:10px;

}

.itemBoxHighlight {

    border:solid 1px black;

    width:400px;

    height:50px;

    padding:10px;

    margin-bottom:10px;

    background-color:yellow;

}

.deleteBox {

    float:right;

    display:none;

    cursor:pointer;

}

</style>


- itemBox : 리스트에 포함될 아이템을 위한 스타일 입니다.

- itemBoxHighlignt : 아이템을 드래그하면 놓은 자리를 알려주는 스타일 입니다.

- deleteBox : 아이템 삭제 버튼의 스타일 입니다. 이 버튼은 아이템에 마우스를 올리면 보여집니다.



3.3. 리스트 생성 코드


$(function() {

    $("#itemBoxWrap").sortable({

        placeholder:"itemBoxHighlight",

        start: function(event, ui) {

            ui.item.data('start_pos', ui.item.index());

        },

        stop: function(event, ui) {

            var spos = ui.item.data('start_pos');

            var epos = ui.item.index();

   reorder();

        }

    });

});


- $("#itemBoxWrap").sortable() : id 가 "itemBoxWrap" 인 태그를 리스트로 만듭니다.

- placeholder:"itemBoxHighlight" : 이 옵션은 드래그 중인 아이템이 놓일 자리를 표시할 스타일을 지정합니다.

- start: function(event, ui) { ... } : 드래그 시작시 호출되는 이벤트 핸들러 입니다.

- ui.item.index() : 드래그 하는 아이템의 위치를 가져옵니다. 첫 번째 아이템을 0 입니다.

- ui.item.data(key, value) : 아이템에 키, 값 쌍으로 데이터를 저장할 수 있습니다.

- stop: function(event, ui) { ... } : 드랍하면 호출되는 이벤트 핸들러 입니다.

- reorder() : 순서가 변경되면 모든 itemBox 내의 itemNum(입력필드 앞의 숫자)의 번호를 순서대로 다시 붙입니다.


function reorder() {

    $(".itemBox").each(function(i, box) {

        $(box).find(".itemNum").html(i + 1);

    });

}



3.4. 아이템 추가하기


아이템 추가 버튼을 누르면 실행됩니다.


function createItem() {

    $(createBox())

    .appendTo("#itemBoxWrap")

    .hover(

        function() {

            $(this).css('backgroundColor', '#f9f9f5');

            $(this).find('.deleteBox').show();

        },

        function() {

            $(this).css('background', 'none');

            $(this).find('.deleteBox').hide();

        }

    )

.append("<div class='deleteBox'>[삭제]</div>")

.find(".deleteBox").click(function() {

        var valueCheck = false;

        $(this).parent().find('input').each(function() {

            if($(this).attr("name") != "type" && $(this).val() != '') {

                valueCheck = true;

            }

        });


        if(valueCheck) {

            var delCheck = confirm('입력하신 내용이 있습니다.\n삭제하시겠습니까?');

        }

        if(!valueCheck || delCheck == true) {

            $(this).parent().remove();

            reorder();

        }

    });

    // 숫자를 다시 붙인다.

    reorder();

}



- $(createBox()).appendTo("#itemBoxWrap") : createBox()를 호출하여 아이템을 구성할 태그를 반환받아서 jQuery 객체로 만듭니다. 만들어진 아이템을 id가 "itemBoxWrap" 인 태그에 추가합니다.


// 아이템을 구성할 태그를 반환합니다.

// itemBox 내에 번호를 표시할 itemNum 과 입력필드가 있습니다.

function createBox() {

    var contents 

        = "<div class='itemBox'>"

        + "<div style='float:left;'>"

        + "<span class='itemNum'></span> "

        + "<input type='text' name='item' style='width:300px;'/>"

        + "</div>"

        + "</div>";

    return contents;

}


- .hover(function(){}, function(){}) : 아이템에 마우스 오버와 아웃시에 동작을 지정합니다. 오버시에는 배경색을 바꾸고 삭제 버튼을 보여줍니다. 아웃시에는 배경을 원래대로 돌리고 삭제 버튼을 숨깁니다.

- .append("<div class='deleteBox'>[삭제]</div>") : 아이템에 삭제 버튼을 추가합니다.

- .find(".deleteBox").click(function() { ... }) : 삭제 버튼을 클릭했을때 동작을 지정합니다. 아이템에 포함된 입력필드에 값이 있으면 정말 삭제할지 물어봅니다.



jQuery UI 의 Sortable 기능을 사용하여 아이템의 순서변경, 추가, 삭제 가 되는 리스트를 만들어 보았습니다. Sortable 기능의 API는 http://api.jqueryui.com/sortable/ 에서 찾아볼 수 있습니다. 예제 소스는 아래에 첨부해 두었습니다.


※ 예제소스

sortable.zip


반응형

댓글을 달아 주세요

  • 맥심매니아 2019.12.21 14:58  댓글주소  수정/삭제  댓글쓰기

    업드려 절!! 감사합니다 필요한 정보였는데 얻어가네요

  • pipescottie 2020.06.20 09:28  댓글주소  수정/삭제  댓글쓰기

    C#에도 이런기능이 있을까요?

    • pentode 2020.06.26 22:44 신고  댓글주소  수정/삭제

      안녕하세요. 방문해 주셔서 감사합니다.

      C#은 제가 해보지 않아서 잘 모르겠네요.

      보통 윈도우용 UI들은 아주 기본적인 것들만 제공 하기 때문에 제공되지 않을 가능성이 높다고 생각됩니다.

      써드파티 UI 또는 공개 UI 등을 검색해 보셔야 할 수도 있겠습니다.

  • corinE 2020.11.11 10:49  댓글주소  수정/삭제  댓글쓰기

    당신은 제 세상을 구했어요!

  • 양지현 2021.06.23 16:08  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 회사에서 갑자기 제이쿼리르 하게돼서 올려주신 글 보고 많은 도움을 받았습니다
    리스트 움직이는거는 해봤는데
    각각의 리스트안에 이미지가 있는 그 이미지들만 서로 드래그해서 변경하려고 하거든요
    이것도 sortable에 start함수에서 이미지소스만 갖고와서 변경하도록 가능할까요?

    • pentode 2021.07.04 20:37 신고  댓글주소  수정/삭제

      안녕하세요. 리스트내의 각 리스트 아이템안에 이미지가 있고, 리스트 아이템을 이동하는게 아니라, 리스트 아이템내의 이미지를 드래그 해서 변경하는것은 sortable로는 안될것 같습니다.

      jquey의 Droppable 같은 것을 이용해서 직접 구현해야 할 것 같네요. 드래그해서 근처에 놓으면 자동으로 정해진 위치에 달라붙는 러버밴드 같은 기능도 직접 구현을 해야 할 것 같습니다.

      성공하길 바랄께요. 방문해 주셔서 감사합니다.^^

  • 오프바이원 고독고자 2021.10.10 19:28  댓글주소  수정/삭제  댓글쓰기

    감사합니다
    열심히 보고있습니다.
    유튜브채널 만드시면 구독하겟습니다

    • pentode 2021.10.31 19:43 신고  댓글주소  수정/삭제

      방문해 주셔서 감사합니다.^^ 일단 계정은 파뒀는데... 현재 너무 힘든 일들이 계속 발생하고 있어서 이 일들이 정리되면 유튜브도 생각하고 있습니다.