본문 바로가기

자료

Grid 라이브러리-Datatables 사용법/예제

728x90

기본 사용

음.. 이건 그냥 스크린샷으로 대체합니다.

공식홈페이지에 들어가시면 메인페이지에 등장합니다. 

 

 

윗 스크린샷에서 설명이 생략된 #myTable 은 아래와 같은 구조로 만드시면 되고, 

서버사이드로 데이터를 처리하여 데이터테이블을 만들 시 <tbody>를 선언하시고 실제로 값을 넣으시면 됩니다.

저는 ajax로 처리할 예정이라서 <thead>만 사용했습니다. 

 

공식홈페이지에선 데이터가 100,000건 이상이면 서버사이드로 처리하라고 권장하고 있습니다. 

<table id="myTable">

    <thead>

        <tr>

            <th>컬럼1</th>

            <th>컬럼2</th>

            <th>컬럼3</th>

        </tr>

    </thead>

</table>

AJAX

아래와 같이 사용합니다. 기본은 GET 방식입니다. 

데이터를 받아오고, columns로 json의 키 값에 맞춰 선언해 줍니다. 

data를 4개 선언하셨으면, HTML의 <table>에도 4개의 컬럼이 있어야 됩니다. 

 

 var table = $('#myTable').DataTable({

     ajax: {

        'url':'MOCK_DATA.json', 

        //'type': 'POST',

        'dataSrc':''

     },

    columns: [

        {"data": "id"},

        {"data": "first_name"},

        {"data": "last_name"}, 

        {"data": "email"}

    ]

});

주의하실 점은, 위의 dataSrc 라는 옵션입니다. 

datatables 가 Ajax로 데이터를 가져올 때는 기본적으로 아래와 같이 최상위에 "data" 라는 키를 가진 형태이어야 합니다.

{

  "data": [

    {

      "id": "1",

      "name": "Tiger Nixon",

      "position": "System Architect",

      "salary": "$320,800",

      "start_date": "2011/04/25",

      "office": "Edinburgh",

      "extn": "5421"

    },

    {

      "id": "2",

      "name": "Garrett Winters",

      "position": "Accountant",

      "salary": "$170,750",

      "start_date": "2011/07/25",

      "office": "Tokyo",

      "extn": "8422"

    }

즉 서버단에서 데이터를 던져줄 때 "data" 키로 전달하던가

dataSrc 옵션을 사용해 키 값을 직접 변경하셔야 합니다.

제가 사용할 데이터는 이중구조가 아니기 때문에 ""로 처리했습니다. (제가 사용한 데이터)

여기서 한 30분 삽질한 것 같습니다.. ㅠㅠ

스타일

기본 스타일도 상당히 깔끔하긴 하지만 부트스트랩의 테이블처럼 클래스명을 통해 간단한 스타일을 줄 수 있습니다.

hover, stripe, compact 등등 여러 옵션이 있구요, 클래스명에 display를 사용하시면 stripe hover order-column row-border 옵션이 모두 사용됩니다. 

 

이외에도 추가로 css와 js파일을 추가해서 아래와 같이 가져다 쓸 수 있습니다. 

https://datatables.net/examples/styling/semanticui.html

https://datatables.net/examples/styling/jqueryUI.html

https://datatables.net/examples/styling/material.html

https://datatables.net/examples/styling/uikit.html

언어 변경

Loading.. 이라든가 Show 10 entries 와 같은 텍스트들 전부 한글로 변경할 수 있습니다. 

아래와 같이 선언할 때 옵션을 주시면 됩니다.

var table = $('#myTable').DataTable({

    "language": {

        "emptyTable": "데이터가 없어요.",

        "lengthMenu": "페이지당 _MENU_ 개씩 보기",

        "info": "현재 _START_ - _END_ / _TOTAL_건",

        "infoEmpty": "데이터 없음",

        "infoFiltered": "( _MAX_건의 데이터에서 필터링됨 )",

        "search": "에서 검색: ",

        "zeroRecords": "일치하는 데이터가 없어요.",

        "loadingRecords": "로딩중...",

        "processing":     "잠시만 기다려 주세요...",

        "paginate": {

            "next": "다음",

            "previous": "이전"

        }

    },

});

옵션이 엄청나게 많은데, 이 정도만 바꾸셔도 영어는 안 보일 겁니다. 

아래에서 더 찾아보실 수 있습니다.

https://datatables.net/reference/option/language

셀 데이터 커스텀

지금은 columns 옵션에서 data: key값을 통해 정직한 데이터만 뿌려주고 있습니다.

약간의 수정을 통해 만약에 돈과 관련된 컬럼이라면 '\' 혹은 '-원' 같이 글자를 붙여주거나

url주소라면 <a>태그로 변경하거나 다운로드 처리를 하고,

다른 컬럼의 값과 혼용해서 사용하는 등등의 처리를 할 수 있겠습니다. 

 

아래와 같이 추가로 선언해 처리하시면 됩니다.

row['컬럼명'] 을 사용해 동일한 라인에 위치한 데이터의 다른 값을 사용할 수도 있습니다. 

....생략

    columns: [

        {"data": "id"},

        ....

        {"data": "url",

            "render": function(data, type, row){

                if(type=='display'){

                    data = '<a href="'+ data + '">' + 링크로 이동 + '</a>';

                }

                return data;

            }

    ]

....

    }},

반응형

가장 인상깊은 부분입니다. 아래와 같이 기기를 넘나들며 완벽하게 대응할 수 있습니다. 

 

 

추가적으로 아래 두 개의 파일이 더 필요합니다.

//cdn.datatables.net/responsive/2.2.3/css/dataTables.responsive.css

//cdn.datatables.net/responsive/2.2.3/js/dataTables.responsive.js

 

그리고 선언할 때 옵션 하나만 더해주시면 됩니다.

$('#myTable').DataTable( {

    responsive: true

} );

다만 테이블 크기가 처음 켜질 때의 브라우저 크기에 맞춰 고정되는 것으로 보입니다. 

그래서 저는 table 자체에 추가로 width: 100% 를 주고 사용합니다. 

컬럼별 검색

datatables의 검색은 모든 컬럼을 대상으로 합니다. 강력하고 심플하고 편하긴 하지만 컬럼별로 검색할 수 있으면 더 좋지 않을까요? <select> 태그를 통해 선택한 컬럼에서만 검색이 되도록 추가해 봅시다.

 

직접 HTML에 선언하셔도 되지만, 저는 검색 바로 옆에 달고 싶어서 해당 위치에 직접 밀어넣었습니다.

그리고 반복문으로 컬럼명에 따른 <option>도 추가했습니다.

 

  /* Column별 검색기능 추가 */

    $('#myTable_filter').prepend('<select id="select"></select>');

    $('#myTable > thead > tr').children().each(function (indexInArray, valueOfElement) { 

        $('#select').append('<option>'+valueOfElement.innerHTML+'</option>');

    });

그리고 아래와 같이 원래 있던 검색기능을 unbind 한 뒤에, select 옵션으로 선택된 컬럼만 검색하도록 다시 이벤트를 추가했습니다. $('.dataTables_filter input') 은 검색 input 이고, draw()는 키가 눌릴 때마다 테이블을 다시 그려 줍니다.

 

(이렇게 변경됐습니다)

 

   $('.dataTables_filter input').unbind().bind('keyup', function () {

        var colIndex = document.querySelector('#select').selectedIndex;

        table.column(colIndex).search(this.value).draw();

    });

날짜 기간 검색

여기에 기간별로 데이터를 조회할 수 있는 기능을 추가해 보겠습니다. 

이것도 셀렉트박스로 연,월 처리할 수 있지만, 그냥 input 태그로 처리하기로 합니다. 

아래와 같이 ~부터 ~까지를 위한 input 태그 2개를 밀어넣습니다. 

 $('#myTable_filter').prepend('<input type="text" id="toDate" placeholder="yyyy-MM-dd"> ');

    $('#myTable_filter').prepend('<input type="text" id="fromDate" placeholder="yyyy-MM-dd">~');

여기가 좀 까다로운데요, datatable을 선언하기 전에 search 기능에 약간 손을 봐 줍시다.

조건이 4개인 이유는, ~부터 혹은 ~까지 중 하나만 입력해도 검색이 이루어지게 하기 위함입니다.

https://datatables.net/manual/plug-ins/search 여기를 참고하실 수 있습니다.

 

true가 리턴되면 검색이 이뤄지구요, false가 리턴되면 무시합니다. 

$.fn.dataTable.ext.search.push(

    function(settings, data, dataIndex){

        var min = Date.parse($('#fromDate').val());

        var max = Date.parse($('#toDate').val());

        var targetDate = Date.parse(data[5]);



        if( (isNaN(min) && isNaN(max) ) || 

            (isNaN(min) && targetDate <= max )|| 

            ( min <= targetDate && isNaN(max) ) ||

            ( targetDate >= min && targetDate <= max) ){ 

                return true;

        }

        return false;

    }

)

분명히 맞게 쓴 것 같은데 작동을 안해서 삽질을 했는데, 위에서 컬럼별 검색기능을 추가하면서 검색기능이 겹쳤습니다. 

아래와 같이 날짜를 입력하는 input 에만 이벤트를 리바인딩 처리했습니다.

 

$('#toDate, #fromDate').unbind().bind('keyup',function(){

    table.draw();

})

FOOTER와 SUMMARY

검색이 이루어지면 표 아래 요약본이 나오면 좋겠다고 합니다. 

예를 들어 금액이라면 금액총합이 나와야 합니다. 모두 나와야 하는 것은 아니고 검색을 통해 필터링된 데이터에 대한 통계가 나와야 합니다. 

 

그럼 <table> 태그로 가서, 우리가 갖고 있지 않은 <tfoot> 태그를 선언해 줍니다. 

그리고 <tr> 아래 <th>를 컬럼 수만큼 선언해주시는데 저는 8개 컬럼 중 2개의 컬럼만 필요해서 아래와 같이 처리했습니다. 

<tfoot>

    <tr>

        <th colspan="2" style="text-align:right;white-space:nowrap;">TOTAL : </th>

        <th colspan="6" style="text-align:left;white-space:nowrap;"></th>

    </tr>

</tfoot>

그리고, datatable의 옵션을 설정할 때, 아래와 같이 "footerCallback" 옵션과 콜백메서드를 사용합니다. 

아래 column() 부분은 차례대로 컬럼(인덱스 말고 컬럼명으로도 사용가능)과 사용할 데이터 옵션입니다. 

search: 'applied' 라고 설정하면 필터링된 데이터만 사용하구요. 

page: 'current' 라고 설정하면 현재 페이지의 데이터만 사용하는 등의 옵션을 줄 수 있습니다.

 

서버사이드로 처리하신다면 좀 더 손댈 부분이 많겠네요.

 

아래에서 전체 옵션을 확인하세요. 

https://datatables.net/reference/type/selector-modifier

 

  /* Footer에 금액총합 구하기,

            * filtered data 총합만 계산하도록 함.*/

        "footerCallback":function(){

            var api = this.api(), data;

            var result = 0;

            api.column(7, {search:'applied'}).data().each(function(data,index){

                result += parseFloat(data);

            });

            $(api.column(3).footer()).html(result.toLocaleString()+'원');

        },

.toLocaleString()은 천단위로 컴마를 찍어줍니다. 

 

그리고 해당 콜백메서드는 5개의 파라미터를 받을 수 있습니다. 저는 사용하지 않았는데 아래에서 확인해 보세요.

https://datatables.net/reference/option/footerCallback

 

아래와 같이 필터링 된 데이터의 금액총합을 구했습니다.

 

(아름답습니다.. )

엑셀EXCEL로 EXPORT

데이터를 엑셀로 빼고 싶다고 요청이 추가됐습니다. 

그것도 필터링 된 데이터만 파일로 다운로드 받아졌으면 좋겠다고 하네요. 

 

그런데 이 기능 또한 datatables는 가지고 있습니다. 

이 기능을 보고 얼마나 감동했는지 모릅니다 ㅠ_ㅠ 

  1. 클립보드로 복사하기
  2. CSV 파일
  3. Excel 파일
  4. PDF 파일
  5. 프린트

위 다섯 가지의 기능을 제공합니다. 

 

다만 저 기능을 다 가져오려면 추가되는 파일이 좀 많은데요, 저는 CSV 파일로만 export 하는 걸로 하겠습니다. 

그럼 아래 두 개만 추가하시면 됩니다.

https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js

https://cdn.datatables.net/buttons/1.5.2/js/buttons.html5.min.js

 

그리고 아래와 같이 사용합니다. 

 

$(document).ready(function() {

    $('#myTable').DataTable( {

        dom: 'Blfrtip',

        buttons: [{

            extend: 'csvHtml5',

            text: 'Export CSV',

            footer: true,

            className: 'exportBtn'

        }]

    } );

} );

이렇게 선언하는 것만으로 버튼을 누르자마자 footer가 포함된 데이터가 (그것도 필터링된!) csv 파일로 다운로드됩니다.

dom 옵션의 Blfrtip 은 단어가 아니라, 알파벳 하나하나에 의미가 있어 옵션을 주는 방식입니다.

아래와 같은데요, 비워놓을시 디폴트값은 lfrtip 입니다. 여기에 Buttons의 B 가 추가되는 것이라고 보면 됩니다. 

순서를 바꾸면 위치도 바꿀 수 있습니다. 예를 들어 f 를 p 바로 이전에 두면 페이징 위에 필터링 input이 위치합니다. 

  • l - length changing input control
  • f - filtering input
  • t - The table!
  • i - Table information summary
  • p - pagination control
  • r - processing display element

아래와 같이 필터링 된 검색결과에서 엑셀버튼을 누르면, 

 

다운로드된 파일에서 필터링 된 결과와 동일한 데이터를 담은 csv 파일을 얻을 수 있습니다. 

새로고침

사용자와 상호작용하며 데이터가 실시간으로 바뀌어야 할 때도 있죠. 

간단한 예를 들어 승인버튼 같은게 있겠네요. 

데이터 업데이트를 하시고 아래와 같이 사용해 주세요. 

 

/* 페이지 고정 */

$('#dataList').DataTable().ajax.reload(null, false);

기타 기능

이 외에도 하나의 포스팅으로 설명하기 어려운 만큼 다양한 옵션이 있습니다. 

orderMulti: true 를 설정하면 쉬프트키를 이용해 여러 컬럼을 동시에 정렬할 수 있구요. 

order : [[index, 'desc']] 와 같이 설정하면 처음 datatable이 그려질 때 선택한 컬럼이 역순으로 정렬됩니다.

헤더/컬럼/푸터 고정, Row grouping, 리오더, 스크롤러 등..

 

이번에 사용하진 않았지만 Editor 기능을 통해 테이블에서 CRUD 도 가능합니다. (이 기능은 유료입니다)

 

아래 링크에서 포스팅에 사용한 코드를 보실 수 있습니다. 

CODE : https://github.com/SaintSilver/datatables-ex

DEMO : https://saintsilver.github.io/datatables-ex/

kutar37.tistory.com/entry/Grid-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%ACDatatables-%EC%82%AC%EC%9A%A9%EB%B2%95%EC%98%88%EC%A0%9C

 

728x90