본문 바로가기
jqGrid

jqGrid - 그리드 내부 스크롤 시 그리드 컬럼 show/hide

by sinabeuro 2021. 6. 16.
728x90

안녕하세요. 오늘도 현업에서 제가 구현했던 기능을 소개하려고 합니다.

그리드 내부를 스크롤할 시 그리드 컬럼이 show/hide되는 재미있는 기능입니다. 

먼저 스크린샷 이미지로 어떤 기능인지 살펴보겠습니다.

위 스크린샷 이미지에서 볼 수 있듯이 가로 스크롤을 옵션명까지 이동하면 그 앞에 있는 컬럼들이 hide됩니다. 

그리고 더보기 버튼이 생기는 것을 볼 수 있습니다. 더보기 행을 클릭하면 다시 hide된 컬럼들이 show가 됩니다.

가로 스크롤을 하면 체크박스를 볼 수가 없기에 체크박스를 유지하는 방법의 일환으로 해당 기능을 개발하게 되었습니다.

여담으로 그리드의 frozen 기능이 있는데 frozen은 앞에 있는 행부터 하나씩 고정하는 기능입니다. frozen으로도 체크박스를 유지할 수 있기에, 지금 올리는 기능은 협업에서 사용하지 않을 예정입니다. 코드를 버리기 아까운 마음에 블로그에 적어봅니다. ㅠㅠ

그래고 그리드 가로 스크롤 이벤트는 상당히 흥미로울 것입니다.

 

 

1. grid선언 js코드

var gridList = $("#moPrdOptManagerGridList");
gridList.jqGrid("GridUnload");
gridList.jqGrid($.extend(true, {}, jqGirdOpt, {
  url: "/product/rest/productOptionManager/selectOptList",
  mtype: "POST",
  datatype: "local",
  multiselect: true,
  autowidth: true,
  cellEdit : false,
  shrinkToFit: false,
  pager: "#moPrdOptManagerGridPager",
  colModel: [
    { name: "prevCol", index: "prevCol", label: "더보기", align: "center", width: 40
    , cellattr: function(rowId, tv, rowObject, cm, rdata) {
      if(Number(rowId)==1) {
      	return 'rowspan='+ $this.paramVo.rowCount + ', style="text-align:center;background-color:#23c6c8;"'
      } else {
      	return 'style="display:none"';
      }
    }, hidden: true },
    { name: "prdGroupNm", index: "prdGroupNm", label: "상세브랜드명", align: "center", width: 80 },
  ...
  ],
  // 셀 클릭 이벤트
  onCellSelect: function(rowId, colIndex, cellCont) {
    if (colIndex > 0) {
      var model = gridList.jqGrid("getGridParam", "colModel")[colIndex];
      var rowData = gridList.jqGrid("getRowData", rowId);
      var isChecked = $("#jqg_moPrdOptManagerGridList_1").prop("checked");
      // 더보기 클릭
      if (model.name == "prevCol") {
        gridList
        .jqGrid('showCol','prdGroupNm')
        .jqGrid('showCol','prdNoTxt')
        .jqGrid('showCol','prdNm')
        .jqGrid('hideCol','prevCol');
        Vue.nextTick(function(){
          if(isChecked == false) {
              $("#jqg_moPrdOptManagerGridList_1").prop("checked", false);
          }
        });
      }
    }
  },
  ...
}));

위와 같이 그리드를 일단 선언하고 가로 스크롤을 만들기 위해서는 autowidth를 꼭 true로 해야합니다.

colModel에서 '더보기(prevCol)'컬럼은 hidden: true 값을 디폴트로 주었습니다. 그리드를 로드하게 되면 해당 컬럼은 보이지않습니다.  또한 '더보기(prevCol)'의 celattr에 가로 셀병합 속성(rowspan)을 주었습니다. 

여담이지만 해당 그리드를 hidden: true을 함으로써 celattr에 설정한 return 'style="display:none"'가 먹히지 않습니다. 그래서 다음에 설명할 가로 이벤트를 처리하는 js에서 '더보기(prevCol)' 셀들에게 display:none 속성을 다시 적용했습니다.

onCellSelect 함수는 '더보기(prevCol)' 셀을 클릭할 시 다시 숨겨진 컬럼들을 보이게하는 기능을 구현한 것입니다. 중요한 부분은 $("그리드Id").jqGrid('showCol', ~)와 $("그리드Id").jqGrid('hideCol', ~)부분입니다. 이 함수의 나머지 부분은 그저 css를 처리하기 위한 코드임으로 크게 신경쓰실 필요는 없을 것 같습니다.

 

 

2. 그리드 가로 스크롤 js이벤트 코드

$(".ui-jqgrid-bdiv").scroll(function(e){
  var horizontal = e.currentTarget.scrollLeft;
  /*var vertical = e.currentTarget.scrollTop;*/
  if(horizontal != undefined && horizontal != null && horizontal > 280 ) {
    var model = gridList.jqGrid("getGridParam", "colModel");
    var prdGroupNmModel = model.filter(i => i.name=='prdGroupNm');
    if(prdGroupNmModel[0].hidden == false) {
      gridList
      .jqGrid('hideCol','prdGroupNm')
      .jqGrid('hideCol','prdNoTxt')
      .jqGrid('hideCol','prdNm')
      .jqGrid('showCol','prevCol');
      $("td[aria-describedby='moPrdOptManagerGridList_prevCol']").each(function(index, item) {
        if(index != 0) {
            $(item).css("display", "none");
        }
      });
      Vue.nextTick(function(){
          $(".ui-jqgrid-bdiv").scrollLeft(-30);
      });
    }
  }
});

대망의 가로 스크롤 이벤트 부분입니다. $(".ui-jqgrid-bdiv").scroll(function(e){ ... }) 와 같이 선언하면 그리드 내부 가로 스크롤에 이벤트가 걸립니다. horizontal 변수에 가로 스크롤의 위치를 담아 가로 스크롤이 280px에 도달하면 그리드 컬럼을 숨기는 이벤트가 발생합니다. 

      $("td[aria-describedby='moPrdOptManagerGridList_prevCol']").each(function(index, item) {
        if(index != 0) {
            $(item).css("display", "none");
        }
      });

위와 같은 코드는 앞서 설명한 '더보기(prevCol)'컬럼을 hidden: true으로 설정했기에 celattr함수의 return 'style="display:none"'이 먹히지 않는 문제로 인해 작성한 코드입니다. 

'더보기(prevCol)'컬럼의 셀 중에 첫번째 셀을 제외하고 나머지를 display: none하셔야 정상적으로 가로 병합된 모습이 보여집니다.

 

      Vue.nextTick(function(){
          $(".ui-jqgrid-bdiv").scrollLeft(-30);
      });

위 코드를 통해서 스크롤 이벤트와 조건절이 끝나고 가장 마지막에 실행되도록 Vue.nextTick(function(){ ... })을 사용했습니다. (참고로 굳이 Vue.nextTick(function(){ ... })을 하지 않아도 이벤트는 정상적으로 실행됩니다.) 

마지막으로 scrillLeft를 통해 가로 스크롤을 왼쪽 끝으로 당김으로써 그리드 컬럼 hide 기능이 완료됩니다.

 

이 코드를 현업에서 없어도 되는 기능이라 판단됭어 지우게 됐습니다. ㅠㅠ

지우기 전에 아쉬운 마음에 블로그에 담겨봅니다.

다음에는 더욱 흥미로운 코드를 찾아뵙도록하겠습니다.

728x90

댓글