API를 호출한 데이터에서 목록조회시 페이지를 해야 할 경우가 생겼다..
보통 DB를 통해 조회하여 페이징하는 코드는 많이 있지만,
ajax를 통해 목록을 모두 조회 후, 자바스크립트(제이쿼리)로 페이징 하는 법을 찾아봤다.
JQuery를 이용한 table pagination
참고: https://gabrieleromanato.name/jquery-easy-table-pagination/
요약하자면, 커스텀 이벤트 'repaginate'를 사용하여 조회 한 데이터를 모두 숨겼다가 페이지 번호에 따라서 목록을 보여주는 식으로 구현을 한다.
루프를 실행하여 모든 페이지 매김 버튼을 생성하고. click각 버튼에 이벤트를 첨부한다. 또한 jQuery의 이벤트 데이터 를 사용하여 현재 페이지 번호를 저장한다. 각 버튼은 사용자 정의 repaginate 이벤트를 트리거 한다.
그리하여.. 코드는 아래와 같다. (주석을 보면 이해할 수 있을 것이다.)
또한 ajax callback 부근에 해당 함수를 호출시키고
데이터 조회하는 테이블에는 class = 'paginated'가 선언 되어있어야 한다.
// ajax 결과 페이징..
function page() {
var reSortColors = function($table) {
$('tbody tr:odd td', $table).removeClass('even').removeClass('listtd').addClass('odd');
$('tbody tr:even td', $table).removeClass('odd').removeClass('listtd').addClass('even');
};
$('.paginated').each(function() {
var pagesu = 10; //페이지 번호 갯수
var currentPage = 0;
//var numPerPage = 10; //목록의 수
var numPerPage = 15; //목록의 수
var $table = $(this);
//length로 원래 리스트의 전체길이구함
var numRows = $table.find('tbody tr').length;
//Math.ceil를 이용하여 반올림
var numPages = Math.ceil(numRows / numPerPage);
//리스트가 없으면 종료
if (numPages==0) return;
//pager라는 클래스의 div엘리먼트 작성
var $pager = $('<td align="center" id="remo" colspan="10"><div class="pager"></div></td>');
var nowp = currentPage;
//var endp = nowp+10;
var endp = nowp+pagesu;
//페이지를 클릭하면 다시 셋팅
$table.bind('repaginate', function() {
//기본적으로 모두 감춘다, 현재페이지+1 곱하기 현재페이지까지 보여준다
$table.find('tbody tr').hide().slice(currentPage * numPerPage, (currentPage + 1) * numPerPage).show();
$("#remo").html("");
if (numPages > 1) { // 한페이지 이상이면
if (currentPage < 5 && numPages-currentPage >= 5) { // 현재 5p 이하이면
nowp = 0; // 1부터
endp = pagesu; // 10까지
} else {
nowp = currentPage -5; // 6넘어가면 2부터 찍고
endp = nowp+pagesu; // 10까지
}
if (numPages < endp) { // 10페이지가 안되면
endp = numPages; // 마지막페이지를 갯수 만큼
nowp = numPages-pagesu; // 시작페이지를 갯수 -10
}
if (nowp < 1) { // 시작이 음수 or 0 이면
nowp = 0; // 1페이지부터 시작
}
} else { // 한페이지 이하이면
nowp = 0; // 한번만 페이징 생성
endp = numPages;
}
// [처음]
$('<br /><span class="page-number" cursor: "pointer">[처음]</span>').bind('click', {newPage: page}, function(event) {
currentPage = 0;
$table.trigger('repaginate');
$($(".page-number")[2]).addClass('active').siblings().removeClass('active');
}).appendTo($pager).addClass('clickable');
// [이전]
$('<span class="page-number" cursor: "pointer"> [이전] </span>').bind('click', {newPage: page}, function(event) {
if (currentPage == 0) return;
currentPage = currentPage-1;
$table.trigger('repaginate');
$($(".page-number")[(currentPage-nowp)+2]).addClass('active').siblings().removeClass('active');
}).appendTo($pager).addClass('clickable');
// [1,2,3,4,5,6,7,8]
for (var page = nowp ; page < endp; page++) {
$('<span class="page-number" cursor: "pointer" style="margin-left: 8px;"></span>').text(page + 1).bind('click', {newPage: page}, function(event) {
currentPage = event.data['newPage'];
$table.trigger('repaginate');
$($(".page-number")[(currentPage-nowp)+2]).addClass('active').siblings().removeClass('active');
}).appendTo($pager).addClass('clickable');
}
// [다음]
$('<span class="page-number" cursor: "pointer"> [다음] </span>').bind('click', {newPage: page}, function(event) {
if (currentPage == numPages-1) return;
currentPage = currentPage+1;
$table.trigger('repaginate');
$($(".page-number")[(currentPage-nowp)+2]).addClass('active').siblings().removeClass('active');
}).appendTo($pager).addClass('clickable');
// [끝]
$('<span class="page-number" cursor: "pointer"> [끝]</span>').bind('click', {newPage: page}, function(event) {
currentPage = numPages-1;
$table.trigger('repaginate');
$($(".page-number")[endp-nowp+1]).addClass('active').siblings().removeClass('active');
}).appendTo($pager).addClass('clickable');
$($(".page-number")[2]).addClass('active');
reSortColors($table);
});
$pager.insertAfter($table).find('span.page-number:first').next().next().addClass('active');
$pager.appendTo($table);
$table.trigger('repaginate');
});
}
// css
.clickable {cursor: pointer;}
.hover {text-decoration: underline;}
.active{ width:10px; height:10px; background:#f60; color:white;}
눈으로 봐서 이해가 잘 되지않으면 디버거를 해보면서 하면 될 듯 하다..
오픈소스가 있어서 참 편하기도 한데, 고수의 영역은 끝이없고, 갈 길이 먼거 같아 씁쓸하기도 했다.