gridLib/jqGrid

jqGrid 데이터 한 페이지 씩 들고 오기 (onPaging)

dddzr 2023. 11. 21. 12:42

 

화면 설명

기존 grid의 데이터를 한번에 들고오는데 데이터 양이 많을 때 시간이 너무 오래걸림.

=> 한 페이지씩 들고오도록 하는데 전체 페이지 수를 표시해야 함.

아래 그림에서 textBox는 실제 입력받는 변수x, 눈에 보이도록 임의로 textBox사용함.

화면 설정

select(조회)버튼 클릭하면

1. count쿼리 실행 => 결과값 totalLowCount에 바인딩, totalLowCount가 change 될 때 totalPageNum도 다시 계산

2. onePageSelect쿼리 실행 =>  그리드에 바인딩

3. 그리드 text 설정 (Page {} of {} 부분에 수동으로 값 넣어 줌)

*한 화면에서 여러 그리드를 쓸 경우

$("#gridpager1_center .ui-pg-input")

$("#gridpager1_center .ui-pg-selbox")

 

필요한 변수

let totalRowCount; //총 데이터 수: 가장 처음에 count 쿼리 실행한 결과 값 저장
let totalPageNum; //페이지 수: totalRowCount / limitNum 올림한 값
let offsetNum = 0; //page start row
let currPage = 1; //현재 페이지
let limitNum = 10; //one page row num
let selectBtn; //trigger target

 

필요한 쿼리

--페이지 수 (count 쿼리)
SELECT COUNT({anyColumnName}) AS COUNT FROM {tableName}

--한 페이지의 데이터 들고오기 (onePageSelect 쿼리)
--MySql
SELECT * FROM {tableName} LIMIT {limitNum} OFFSET {offsetNum}

--Oracle 12
SELECT * FROM {tableName} OFFSET {offsetNum} ROWS FETCH NEXT {limitNum} ROWS ONLY

--Oracle 12 이하
SELECT *
FROM (
    SELECT t.*, ROWNUM AS rnum
    FROM (
        SELECT *
        FROM {tableName}
        WHERE ROWNUM <= :offsetNum + :limitNum
    ) t
    WHERE ROWNUM > :offsetNum
);

-- ex) 조회 조건 있을 때
SELECT *
FROM (
    SELECT 
        t.*,
        ROW_NUMBER() OVER (ORDER BY EVENTTIMEKEY DESC) AS rnum
    FROM {tableName} t
    WHERE COLID = @COLID 
      AND EVENTTIME BETWEEN TO_TIMESTAMP(@STARTDATE || ' 00:00:00', 'YYYY-MM-DD HH24:MI:SS') 
                        AND TO_TIMESTAMP(@ENDDATE || ' 23:59:59', 'YYYY-MM-DD HH24:MI:SS') 
)
WHERE rnum BETWEEN @OFFSETNUM + 1 AND @OFFSETNUM + @LIMITNUM

 

 

jqGrid 설정

$(document).ready(function () {
    $("#grid").jqGrid({
        url: 'your_data_url',
        datatype: 'json',
        mtype: 'GET',
        colNames: ['Column1', 'Column2', 'Column3'], // 컬럼 이름들
        colModel: [
            { name: 'col1', index: 'col1', width: 150, align: 'left' },
            { name: 'col2', index: 'col2', width: 150, align: 'left' },
            { name: 'col3', index: 'col3', width: 150, align: 'left' }
        ],
        pager: '#pager', // pager를 표시할 위치 지정
        rowNum: 10, // 페이지당 보여질 행 수
        rowList: [10, 20, 30], // 페이지당 보여질 행 수 선택 옵션
        sortname: 'col1', // 초기 정렬 컬럼
        sortorder: 'desc', // 초기 정렬 순서
        viewrecords: true, // 레코드 수 표시
        gridview: true, // 성능 향상을 위한 옵션
        autoencode: true, // HTML 특수 문자를 인코딩
        caption: 'My Grid', // 그리드 제목
        "onPaging": onPagingFunc // 페이징 함수
    });
});

 

onPageing 함수

페이지 넘기거나 한 페이지에 표시할 row 수를 변경할 때 실행됨.

현재 페이지, 한 페이지에 표시할 row 수를 가지고 limitNum과 offsetNum을 계산하여 데이터 다시 조회.

  function onPagingFunc(pgButton) {
    let currPage = $(".ui-pg-input").val();
    let afterPage = 0;
    let rowCnt = $(".ui-pg-selbox").val();
    let lastPage = $(".ui-pg-input").next()[0].innerHTML;
    if(pgButton == 'records') {
      afterPage = currPage;
      lastPage = Math.ceil(Number($("#totalRowCount").val()) / Number($(".ui-pg-selbox").val())); //Total Row Count / One Page Row Num 올림
      let totalPageNum = lastPage;
      $("#totalPageNum").val(totalPageNum);
    } else if(pgButton.includes("first_")){
      if(currPage == 1) return;
      afterPage = 1;
    } else if(pgButton.includes("prev_")){
      if(currPage == 1) return;
      afterPage = Number(currPage) - 1;
    } else if(pgButton.includes("next_")){
      if(currPage == lastPage) return;
      afterPage = Number(currPage) + 1;
    } else if(pgButton.includes("last_")){
      if(currPage == lastPage) return;
      afterPage = Number(lastPage);
    }
    if(afterPage > lastPage){
      afterPage = lastPage;
    }
    let PageStratRow = afterPage * Number(rowCnt) - Number(rowCnt);
    if(PageStratRow < 0) return;
    $("#currPage").val(afterPage);
    $("#offsetNum").val(PageStratRow);
    $("#limitNum").val(rowCnt);
    $("#selectBtn").trigger("click");
  };

 

기타 함수

//select 버튼을 눌리기 전 화면이 열리자 마자 디폴트 데이터를 뿌릴 경우에만 필요
setTimeout(function(){ 
$("#sp_1_gridpager1")[0].innerHTML = Math.ceil(Number($("#totalPageNum").val()) / 10);
$("#totalPageNum").val($("#sp_1_gridpager1")[0].innerHTML);
}, 100);
  
//조회 조건에 따라 전체 데이터 수가 변경 됐을 때 전체 페이지 수를 다시 계산
$("#totalRowCount").on("change", function(e){
  $("#totalPageNum").val(Math.ceil(Number($("#totalRowCount").val()) / Number($(".ui-pg-selbox").val())));
});