개발관련/삽질

Vanilla(Pure)-JavaSciprt 게시판 페이징 - 1(기본/응용)

동팡 2021. 7. 27. 02:01

목차

  • 시리즈 소개
  • 개요
  • 라이브러리 소개
  • 데모 - 1
  • 데모 - 2
  • 데모 - 3
  • 데모 - 4
  • 마치며, 다음 시리즈

 

시리즈 소개

본 시리즈는 웹페이지 앞단에서 게시판 페이징을 하는 방법을 소개한다. 즉, JavaScript에서 어떻게 페이징 처리하는지 확인할 수 있다. 피곤하지 않으면 2장 라이브러리 최적화 작업을 진행할 예정이다. 요즘 바빠서 너무 피곤하다... 

  • Pure-JavaSciprt 게시판 페이징 - 1(기본/응용)
  • Pure-JavaSciprt 게시판 페이징 - 2(라이브러리 최적화)

 

개요

[들어가면서...]

웹 페이지에서 제일 많이 사용하는 기능은 단연 게시판이다. 그리고 신입 개발자가 처음에 직면하는 벽이 게시판 페이징 작업이다. 게시판 페이징 작업을 구글링 하여 구현하는 거는 진짜 쉽지 않을 것이다. 게시판 페이징 개발 스타일이 다양해서 이것저것 참고하다가 실패할 것이다. 차라리 책에서 제공하는 게시판 페이징 코드를 활용하는 게 정신 건강에 좋을 것이다. 

 

[게시판 페이징 개발 스타일]

그렇다면 어떻게 개발 스타일이 다를까? 다음과 같다.

  • Java(Spring) / JSP(JSTL) 백단 게시판 페이징 
  • JS 앞단 게시판 페이징

백단 게시판 페이징 스타일은 옛날 스타일이다. 백단에서 게시판 페이징에 필요한 데이터를 가공하여 앞단에 전달, JSP영역에서 JSTL 반복문을 사용하여 게시판 페이징을 구현한다. 단점은 1) 페이지 이동할 때마다 페이지 깜박임, 2) JSP에 종속적인 개발 방법이다. 앞단 게시판 페이징은 REST API가 많이 부각되면서 생기지 않았나 생각한다. 백단 기술 스택에 종속적이지 않고 페이지 깜박이는 현상도 없다. 필자 또한 후자를 소개하고자 한다. 

 

[게시판 페이징 라이브러리]

JS 게시판 페이징 라이브러리는 다양하다. 필자는 JS 개발하면서 2~3개 정도 사용했던 기억이 있다. 웹 페이지 특성상 가시적인 요소가 다분하기 때문에 요구사항이 많다. 이와 같은 요구사항을 모두 충족하는 게시판 페이징 라이브러리는 존재하지 않는다. 비약이 심했지만 진짜 찾다 포기했다. 또한 요구사항 충족을 위한 라이브러리 스터디와 분석이 필요하다. 해당 사항으로 인해 작업 속도가 더 느려질 수 있다. 그래서 결국 필자는 별도의 라이브러리를 개발하여 사용하고 있다. 이유는 단순하다. 외주작업을 혼자 하는데 지랄 같은 요구사항 이행하려면 기능 추가가 가능한 라이브러리가 필요하다. 그리고 실무에서 좀 있다 보면 게시판 페이징 라이브러리를 개발하는 것은 많이 어렵지 않을 것이다. 

 

 

[실무에서 게시판 페이징 디테일]

외주/회사 업무에서 겪은 게시판 페이징 요구사항은 다음과 같다.

  • 체크박스를 이용한 테이블 제어
  • 특정 로우에 이벤트 핸들링
  • 특정 열에 이벤트 핸들링
  • 특정 로우, 열에 이벤트 핸들링
  • 게시판 로우 제어
  • 퍼블리셔와의 템플릿 협업

주로 업무 시스템 개발하는 인원은 이것보다 좀 더 다양한 요구사항을 겪을 것이다. 필자는 다음의 요구사항 때문에 직접 만들기로 결심했다. 실제 개발 결과물이다.

특정 열에 이벤트 핸들링

있을 수 있지만, 각 열에 별개의 이벤트 핸들링을 지원하는 게시판 페이징 라이브러리를 찾지 못했다. 1년 전에 개발한 라이브러리이다.. 기억을 되살리고 테스트하여 시리즈를 연재한다.

 

라이브러리 소개

게시판 페이징을 하기 위한 복잡한 Pure-JS 라이브러리이다. 대단한 기능은 없다. 말마따나 복잡하다. 필자가 봐도 복잡하다. 라이브러리 최적화가 필요하기는 하다.  해당 라이브러리를 사용하기 위한 필수 값이 존재한다. 당연 필수 값은 게시판 페이징에 사용되는 데이터들이다. 데이터들은 백단 API를 이용해서 반환받을 수 있다.

  • total: 게시판 페이징 데이터의 총 로우 수
  • limit: 게시판에 뿌려질 데이터의 개수
  • offset: 게시판 페이지의 위치 
  • datas: 게시판에 뿌려질 데이터 

Oracle 외의 RDBMS를 이용하여 게시판 페이징을 했으면 limit, offset을 알 수 있다. RDBMS에서 limit, offset과 같은 의미고 같은 기능이다. 

 

아 참고로 바빠서 넣지 못한 기능이 페이징 넘버링에 대한 이벤트 바인딩이다. Prev, Next, 페이지 넘버에 대한 이벤트 바인딩은 사용자가 직접 추가해야 한다. 

(라이브러리 최적화 때 이벤트 바인딩 기능을 추가하면 괜찮을 것 같다.) 

 

소개는 짧게 하고 바로 데모를 진행한다. 

 

데모 1: 게시판 페이징 기본

백문이불여일견 JS 피들을 확인한다. 차근차근 진행하기 위해 이벤트 바인딩은 하지 않았다. JS, HTML 영역을 보면 쉽게 이해할 수 있다.

JS 영역

function renderTableList(tableDivEl, pageDivEl, tlbLibOpt) {
    var tblPageEl = new TblPager( tableDivEl, pageDivEl, tlbLibOpt).generateTablePage();
}

HTML 영역

<body>
  <!-- table -->
  <div id="tblArea"></div>
  <!-- //table -->
  <!-- pagination -->
  <div id="pageArea"></div>
  <!-- //pagination -->

</body>

 

설명

  • TEST DATAS는 백단 API에서 데이터를 받았다는 가정이다.
  • div의 id는 꼭 위와 같이 설정한다.
  • tlbLibOpt의 Object Literal은 라이브러리가 지정한 값만 사용해야 한다. 
  • headers를 이용하여 백단 API에서 받은 것을 사용자가 보기 좋게 TH 문구를 바꾼다. header는 tlbLibOpt에 꼭 추가해야 한다. 
  • tlbLibOpt의 변수명을 보면 대강 의미를 이해할 수 있다.

 

데모 2: 게시판 페이징, 이벤트 핸들링 추가

백문이불여일견 JS 피들을 확인한다. 페이지 번호와 Prev, Next에 이벤트 바인딩하였다. 이벤트 바인딩을 사용자가 하기 때문에 중복 코드와 복잡성을 가중한다. JS 피들에서 번호를 누르면 이동되는 것을 확인할 수 있다.

데모 2의 코드 플로우는 다음과 같다(추상화). 

  1. 페이지 DOM 로드 완료 후, 백단 API을 호출한다.
  2. 백단 API에서 받은 데이터를 JS DOM 랜더링 함수에 전달한다.
  3. JS DOM 랜더링 함수는 DOM을 생성/수정한다. 
  4. DOM 랜더링 완료 후 특정 DOM에 이벤트를 추가한다.
  5. 특정 DOM의 이벤트가 발생하면 2번부터 반복한다.

데모 2의 코드 플로우는 다음과 같다(구체화).

  1. 페이지 DOM 로드 완료 후, 게시판 페이징 백단 API을 호출한다.
  2. 백단 API에서 받은 데이터를 게시판 페이징 랜더링 함수에 전달한다.
  3. 랜더링 함수는 게시판 페이징 함수를 호출하여 DOM을 생성/수정한다.
  4. 게시판 항목(DOM) 랜더링 완료 후 페이지 번호, Prev/Next에 이벤트를 추가한다.
  5. 페이지 번호를 누르면 2번부터 반복한다.

 

데모 3: 게시판 페이징, 응용 - 요구사항 진행1

백문이불여일견 JS 피들을 확인한다. 퍼블리셔가 작업한 템플릿에 CSS의 기능을 죽이지 않고 JS 코드를 삽입해야 한다. 또한 고객의 요구사항을 몇 개 이행해야 한다. 이번 데모는 다음과 같은 요구사항을 이행한다.

  • 퍼블리셔가 작업한 템플릿이 적용된 게시판 페이징
  • 특정 로우, 특정 열 데이터 핸들링
  • 특정 열 데이터 핸들링

tlbLibOpt변수에 다음의 사항을 추가하였다.

tlbLibOpt : {
  tableInfo: {
    options: {
      tableClassName: "tableClassName",
      customBeforeThTag: function() { return tableColGroup },
      customThTag: function(headerVal) {
        if ( headerVal === "aaa" ) 
          return { start: "<th><span class='no_arrow'>", end: "</span></th>" }
        else 
           return { start: "<th><span>", end: "</span></th>"}
      },
      customTdBodyTag: function( headerVal, index ) {
        if (index == 2 && headerVal === "bbb") {
          return { start: "<td><span><b>", end: "</td></span></b>" }
        } else {
          return { start: "<td><span>", end: "</td></span>" }
         }
	  },
      customTdBodyValue: function( headerVal, listValue ) {
        if ( headerVal === 'bbb' ) {
          if ( listValue === true) {
            return '성공'
          } else {
            return '실패'
          }
        }

        return listValue
      }
    }
  },
  pageInfo: {
    options: {
      customPrev: {
        start: "<a href='#none'",
        end: "> <<<< </a>",
      },          
      customNext: {
      	start: "<a href='#none'",
        end: "> >>>> </a>",
      },
      customPageNum: {
        totalStart:"<span>",
        start: "<a href='#none'>",
        end: "</a>",
        totalEnd:"</span>"
      }
    }
  }
}

나참 드럽게 복잡하다;;

  • tableClassName: 생성되는 테이블에 class 이름을 추가한다.
  • customBeforeThTag: 테이블의 colgroup을 추가하기 위한 공간이다. <table><colgroup><thead>
  • customThTag: 콜백 함수를 추가했다. headerVal을 활용하여 특정 열에 다른 th 태그를 사용할 수 있다.
  • customTdBodyTag: TD의 특정 열 특정 로우에 특정 태그를 사용할 수 있다.
  • customTdBodyValue: TD의 특정 열 특정 로우에 값을 제어할 수 있다. 
  • customPrev/Next: 뒤로 가기에 특정 태그를 사용할 수 있다(이미지 삽입할 수 있다.).
  • customPageNum: 페이지 넘버링에 특정 태그를 삽입할 수 있다. 

개발자 도구를 활용하여 HTML 태그 랜더링이 어떻게 변했는지 확인할 수 있다. 

 

데모 4: 게시판 페이징, 응용 - 요구사항 진행2

 

백문이불여일견 JS 피들을 확인한다. 데모 3을 베이스로 다음의 추가 요구사항을 이행한다. 

  • 체크 박스 처리
  • 특정 로우, 특정 열 이벤트 바인딩
  • 특정 로우 이벤트 바인딩

 

마치며, 다음 시리즈

인터넷에 돌아다니는 게시판 페이징 테마(CSS)를 사용하여 추가 데모를 시연할 것이다. 또한 데모에서 불편한 사항을 개선할 예정이다. 당장 눈에 보이는 불편한 사항은 다음과 같다.

  • 사용자는 페이징 1~10, Prev, Next DOM의 이벤트 바인딩을 해야한다. 
  • 사용자는 체크 박스의 이벤트 바인딩을 해야한다.
  • 사용자는 테이블 로우 클릭 이벤트 바인딩을 해야한다.
  • 라이브러리에서 제공하는 기타 유틸 함수가 부족하다.

다음 시리즈는 위의 열거한 사항을 기반으로 추가 분석을 실시하여, 라이브러리 최적화 작업을 진행한다. 진행한 결과물에 테마를 입혀 데모를 시연한다.