Datatables를 이용해서 뿌린 동적 테이블에 대충 이런 체크박스 필터를 붙인 메모이다.
datatable.ajax
데이터로 보내기현재 이 datatable은 서버사이드 렌더링으로 자료를 비동기적으로 받아다가 사용한다.
<table>
태그 바깥의 <form id="filter">
안에 있는 <input class="filter">
체크박스들 상태가 변경될 때마다 그 값을 반영해서 datatable.draw()
이 콜돼야 한다.
이 부분은 대충 이런 느낌으로 구현된다.
var dataTable = $('.datatable').DataTable({
// #1
processing: true,
serverSide: true,
ajax: {
url: "/foo/bar/datatable",
type: 'GET',
// #2
data: function (data) {
// #3
var filters = $('#filter').serializeArray();
for (i = 0; i < filters.length; i++) {
var filter = filters[i];
// #4
if (data[filter.name]) {
data[filter.name] += '|' + filter.value;
} else {
data[filter.name] = filter.value;
}
}
}
}
});
// #5
$('#filter .filter').on('change keyup', function () {
dataTable.draw();
});
data
를 전처리한다. 문서를 보면 콜백에서 딱히 뭘 return
할 필요는 없는 듯..serializeArray()
를 착취하기로 했다.아 참고로 서버쪽에서는 대충 이런 처리를 한다.
if (request()->has('ipsum')) {
// JS에서 정의한 구분자로 분할해서 배열 만들어 WHERE IN 돌림
$ipsums = explode('|', request()->input('ipsum'));
$query->whereIn('lorem.ipsum', $ipsums);
}
위에서 구현한 필터박스는 매우 훌륭하게 동작했으나, 문제가 하나 있다. 새로고침을 하면 체크 상태가 모두 사라져 버린다. 이건 매우 불편한 일인데, 왜냐하면 위의 스크린샷처럼 간단하고 일회용적인 체크박스만 필요한 기능도 있지만, 체크박스의 체크 상태가 저장돼야 하는 꽤 복잡한 datatable도 있었기 때문이다.
DataTables 공식문서를 정말 뭐 빠지게 읽고 조사해서 알아낸 결론만 말하면, 이렇게 하면 된다.
var dataTable = $('.datatable').DataTable({
// #1
stateSave: true,
// #2
stateSaveParams: function (settings, data) {
data.filters = $('#filter').serializeArray();
},
stateLoadParams: function (settings, data) {
if (!data.filters) data.filters = $('#filter').serializeArray();
},
// #3
stateLoaded: function (settings, data) {
var filters = data.filters;
for (i = 0; i < filters.length; i++) {
var filter = filters[i];
// #4
var input = $('#filter__' + filter.name + '__' + filter.value);
if (input) {
// #5
if (input.attr('type') == 'checkbox') {
input.trigger('click');
}
}
}
}
});
DataTable()
인스턴스가 갖고 있던 정보들(검색어, 마지막으로 본 페이지 등)인데, 여기에 더하여 사용자가 원하는 것을 저장할 수 있다.stateSaveParams()
는 .draw()
가 콜되어서 화면을 새로 그리고 그 상태를 저장해야 할 때 실행되며, stateLoadParams()
는 마지막에 저장해둔 상태를 지금 처음으로 불러와 사용해야 할 때 콜된다. 그 2개 내장메소드는, 별다른 리턴 없이 data
인자에 대한 조작만 추가하는 사용자 지정 함수가 있을 경우, 그걸 실행한 다음 최종적으로 자기 할 일을 한다. 맞나? 이 이상은 잘 모르겠음.stateLoaded()
는 그야말로 상태가 완전히 다 로딩됐을 때 콜된다. 이 시점에서 data.filters
에 저장해 둔 내용을 내가 알 수 있으므로, 가져다가 사용한다.#filter
폼 안의 체크박스들에 #filter__lorem__1
같은 ID들을 달아놨다.사실 DataTables 위젯을 더 수려하게 확장하는 다른 방법이 많을 것이다. 하지만 그것까지는 PHP 개발자로서는 잘 못하겠고, 당장 떠오르는 방법만 가지고 이렇게 처리했다.
더 좋은 방법이 있다면 공유 좀 해 주십사 부탁드리는 바다.