JS로 Pagination 구현하기

eunoia·2021년 6월 21일
28
post-thumbnail

출처

🤔 Pagination?

페이지네이션이란 콘텐츠를 여러 페이지고 나누고, 이전 혹은 다음 페이지로 넘어가거나 특정 페이지로 넘어갈 수 있는 일련의 링크를 페이지 상단이나 하단에 배치하는 방법입니다.

✅ 필요한 Pagination 조건

게시판을 더 쉽게 볼 수 있고 사용자의 접근성을 높일 수 있게 Pagnation을 적용하기로 했습니다.💪

Pagination을 구상하면서 필요한 요구 조건들은 총 네 가지입니다.

🚩 한 페이지에 페이지 링크는 10개로 보여준다.
🚩 한 페이지에 20개씩 게시물을 보여준다.
🚩 이전, 다음 버튼이 존재한다.
🚩 처음으로, 마지막으로 버튼이 존재한다.

👩‍💻 JS로 Pagination 개발

🚩한 페이지에 페이지 링크는 10개로 보여준다.

total : 462

1 ... 10
11 ... 20
21 ... 23

위와 같이 페이지네이션을 생성하기 위해서는 네 가지의 값이 필요합니다.

화면에 보여질 페이지 그룹
화면에 보여질 첫번째 페이지
화면에 보여질 마지막 페이지
총 페이지 수

🔎 총 페이지 수화면에 보여질 페이지 그룹은 게시물 전체 개수와 현재 페이지를 이용해 구합니다.

총 페이지 수 = Math.ceil(전체 개수/ 한 페이지에 나타낼 데이터 수);
화면에 보여질 페이지 그룹 = Math.ceil(현재 페이지/ 한 화면에 나타낼 페이지 수);

🔎 화면에 그려질 첫 번째 페이지마지막 페이지 는 위에서 구한 화면에 보여질 페이지 그룹을 이용해 를 구합니다.

화면에 그려질 첫 번째 페이지 : 화면에 그려질 마지막 페이지 - (한 화면에 나타낼 페이지 - 1)
	(단, 계산된 값이 0 이하이면 첫번째 페이지는 1이다.)

화면에 그려질 마지막 페이지 : 화면에 보여질 페이지 그룹 * 한 화면에 나타낼 페이지
	(단, 계산된 값이 총 페이지수보다 많으면 마지막 페이지는 은 총 페이지 수이다.)

이렇게 네 가지 값의 계산이 끝났습니다.

이제, 이 네 가지 값을 이용해 PaginationDOM에 그려줍니다.

renderPagination: function (currentPage) {
	// 현재 게시물의 전체 개수가 20개 이하면 pagination을 숨깁니다.
	if (_totalCount <= 20) return; 

	var totalPage = Math.ceil(_totalCount / 20);
	var pageGroup = Math.ceil(currentPage / 10);
	
	var last = pageGroup * 10;
	if (last > totalPage) last = totalPage;
	var first = last - (10 - 1) <= 0 ? 1 : last - (10 - 1);

	const fragmentPage = document.createDocumentFragment();
  if (prev > 0) {
	  var allpreli = document.createElement('li');
	  allpreli.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='allprev'>&lt;&lt;</a>`);
	
	  var preli = document.createElement('li');
	  preli.insertAdjacentHTML("beforeend", `<a href='#js-ottom' id='prev'>&lt;</a>`);
	
	  fragmentPage.appendChild(allpreli);
	  fragmentPage.appendChild(preli);
	}

  for (var i = first; i <= last; i++) {
	  const li = document.createElement("li");
	  li.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='page-${i}' data-num='${i}'>${i}</a>`);
	  fragmentPage.appendChild(li);
  }

  if (last < totalPage) {
	  var allendli = document.createElement('li');
	  allendli.insertAdjacentHTML("beforeend", `<a href='#js-bottom'  id='allnext'>&gt;&gt;</a>`);
	
	  var endli = document.createElement('li');
	  endli.insertAdjacentHTML("beforeend", `<a  href='#js-bottom'  id='next'>&gt;</a>`);
	
	  fragmentPage.appendChild(endli);
	  fragmentPage.appendChild(allendli);
  }

    document.getElementById('js-pagination').appendChild(fragmentPage);
		// 페이지 목록 생성
}

🚩한 페이지에 20개씩 게시물을 보여준다.

1페이지 : 20개
2페이지 : 40개
3페이지 : 60개
.
.
.
N페이지 : (N * 20)개

각 페이지마다 20개씩 게시물을 보여주기 위해 페이지 번호를 서버로 전송해 page에 따라 20개씩 결과를 받습니다.

🔎 페이지네이션 페이지를 클릭했을 때 이벤트를 등록해 페이지 숫자를 서버로 넘겨줍니다.

$("#js-pagination a").click(function (e) {
    e.preventDefault();
    var $item = $(this);
    var $id = $item.attr("id");
    var selectedPage = $item.text();

    list.renderPagination(selectedPage);//페이지네이션 그리는 함수
    list.search(selectedPage);//페이지 그리는 함수
});

✔ 서버로 전송된 페이지 숫자를 이용해 startNum을 페이지 숫자로 받고 endNum페이지 숫자 * 20을 해 쿼리를 작성했습니다.

SELECT *
FROM (
    SELECT ROW_NUMBER() OVER (/**orderby**/) NUM, LIST.*
    FROM DAMS_PGM_EPISODE_VIEW LIST
    /**where**/
)
WHERE NUM BETWEEN :startRow  AND :endRow 
ORDER BY NUM

이렇게 되면 20개씩 게시물이 페이지에 맞게 가져와 집니다.

🚩이전, 다음 버튼이 존재한다.

이전 버튼 : 화면에 그려진 첫번째 페이지 - 1
다음 버튼 : 화면에 그려진 마지막 페이지 + 1

🔎 버튼을 클릭했을 때 페이지 숫자가 아닌 next prev이면 알맞게 계산된 값을 페이지 숫자로 넘겨줍니다.

var next = last + 1;
var prev = first - 1;

$("#js-pagination a").click(function (e) {
  e.preventDefault();
  var $item = $(this);
  var $id = $item.attr("id");
  var selectedPage = $item.text();

  if ($id == "next") selectedPage = next;
  if ($id == "prev") selectedPage = prev;

  list.renderPagination(selectedPage);//페이지네이션 그리는 함수
  list.search(selectedPage);//페이지 그리는 함수
});

🚩처음으로, 마지막으로 버튼이 존재한다.

처음으로 버튼 : 1
마지막으로 버튼 : 총 페이지 수

🔎 버튼을 클릭했을 때 페이지 숫자가 아닌 첫번째 페이지와 마지막 페이지를 넘겨줍니다.

$("#js-pagination a").click(function (e) {
  e.preventDefault();
  var $item = $(this);
  var $id = $item.attr("id");
  var selectedPage = $item.text();

  if ($id == "next") selectedPage = next;
  if ($id == "prev") selectedPage = prev;
  if ($id == "allprev") selectedPage = 1;
  if ($id == "allnext") selectedPage = totalPage;

  list.renderPagination(selectedPage);//페이지네이션 그리는 함수
  list.search(selectedPage);//페이지 그리는 함수
});

최종 결과 ✌

최종 코드 👀

function renderPagination(currentPage) {
  if (_totalCount <= 20) return; 

  var totalPage = Math.ceil(_totalCount / 20);
  var pageGroup = Math.ceil(currentPage / 10);

  var last = pageGroup * 10;
  if (last > totalPage) last = totalPage;
  var first = last - (10 - 1) <= 0 ? 1 : last - (10 - 1);
  var next = last + 1;
  var prev = first - 1;

  const fragmentPage = document.createDocumentFragment();
  if (prev > 0) {
    var allpreli = document.createElement('li');
    allpreli.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='allprev'>&lt;&lt;</a>`);

    var preli = document.createElement('li');
      preli.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='prev'>&lt;</a>`);

      fragmentPage.appendChild(allpreli);
      fragmentPage.appendChild(preli);
  }
	
  for (var i = first; i <= last; i++) {
    const li = document.createElement("li");
    li.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='page-${i}' data-num='${i}'>${i}</a>`);
    fragmentPage.appendChild(li);
  }

  if (last < totalPage) {
    var allendli = document.createElement('li');
    allendli.insertAdjacentHTML("beforeend", `<a href='#js-bottom'  id='allnext'>&gt;&gt;</a>`);

    var endli = document.createElement('li');
    endli.insertAdjacentHTML("beforeend", `<a  href='#js-program-detail-bottom'  id='next'>&gt;</a>`);

    fragmentPage.appendChild(endli);
    fragmentPage.appendChild(allendli);
  }

  document.getElementById('js-pagination').appendChild(fragmentPage);
  // 페이지 목록 생성

  $(`#js-pagination a`).removeClass("active");
  $(`#js-pagination a#page-${currentPage}`).addClass("active");

  $("#js-pagination a").click(function (e) {
    e.preventDefault();
    var $item = $(this);
    var $id = $item.attr("id");
    var selectedPage = $item.text();

    if ($id == "next") selectedPage = next;
    if ($id == "prev") selectedPage = prev;
    if ($id == "allprev") selectedPage = 1;
    if ($id == "allnext") selectedPage = totalPage;

    list.renderPagination(selectedPage);//페이지네이션 그리는 함수
    list.search(selectedPage);//페이지 그리는 함수
  });
};
profile
💻 .net, Spring

2개의 댓글

comment-user-thumbnail
2022년 11월 10일

좋은 글이네요 !

답글 달기
comment-user-thumbnail
2023년 3월 20일

Math.ceil(462/20) 이면 24아닐까요?_?

답글 달기