들어가며

이번 강좌에서는 B7-2 Insert and Add Rows에 이어 행 삽입과 추가에 대해 배운것을 응용하여 처리하는 법을 배워보도록 하겠습니다.

이론

본 강좌를 진행하기에 앞서 아래 강좌를 선행 학습 하시기 바랍니다.

B7-2 Insert and Add Rows 강좌를 잘 따라하셨다면 그리드의 beginInsertRow()와 데이터프로바이더의 insertRow()의 차이를 아시리라 생각됩니다.

일반적으로 원하는 위치에 그리드에 행을 삽입하거나 추가하려고 할때 사용하는 API는 dataProvider.insertRow()dataProvider.addRow일 것 입니다.

해당 API를 사용하여 행 추가시 개발자의 의도와 다르게 엉뚱한 위치로 삽입되는 경우가 있습니다.
왜 그런 일이 발생할까요? 그 이유는 바로 위의 선행학습에서 이야기한 dataRow(rowId)나 itemIndex의 지정이 잘못되었기 때문일 확률이 높습니다.

또 다른 이유로는 그리드의 옵션중 sortMode, filterMode가 ‘auto’(기본값)로 되어 있다면 행 추가가 이루어진 후 자기 조건에 맞는 위치로 이동되어 엉뚱한 위치로 삽입되는 것처럼 보일 수 있습니다. 이런 경우는 아래와 같이 ‘explicit’ 로 지정해주어 사용자가 소트나 필터를 다시 수행했을때에만 적용되도록 해야 합니다.

gridView.setOptions({
    sortMode: "explicit",
    filterMode: "explicit"
});

처음 조회시 그리드의 itemIndex와 dataRow는 동일한 번호를 같습니다. 그러나 그리드가 소트되거나 필터링 되면 동일하지 않게 됩니다. 이것을 간과하고 소트되거나 필터링된 그리드에 행 삽입시 dataRow 값에 눈에 보이는 순서인 itemIndex를 지정하게 되면 다른 위치로 행 삽입이 일어나게 되는 것이지요.

소트되거나 필터링된 그리드에서 원하는 위치에 행을 추가하려면 GridView.beginInsertRow()를 사용해야 합니다.
RealGridJS 1.1.26버전 이상이라면 dataProvider.insertRow()도 가능 합니다.

실습에서는 행 추가시 발생할 수 있는 다양한 문제를 확인하고 해결해보도록 하겠습니다.

실습

실습에서는 sortMode와 filterMode가 ‘auto’ 일때의 동작을 확인하고 ‘explicit’로 변경 후 어떻게 동작하는지 확인하기로 하겠습니다.

  1. 버튼을 클릭하면 이름 컬럼을 오름차순 정렬을 합니다.

     //복구모드: explicit 지정
     $("#btnOrderBy").click(function () {
         gridView.orderBy(["field3"],["ascending"])
     });
  2. dataProvider.insertRow()를 사용하여 3행 전도연과 4행 전지현 사이에 빈 행을 삽입해보도록 하겠습니다. (전도연 dataRow: 0, 전지현 dataRow: 4 입니다.)

        
     $("#btnInsertRow0").click(function () {
         dataProvider.insertRow(4, []);  //전지현의 dataRow 4 위에 삽입..
     });
  3. sortMode가 “auto”이기 때문에 의도한 위치에 삽입되지 않고 첫 행으로 이동합니다. 소트 방향에 따라 마지막 행으로 삽입될 수도 있습니다.

  4. 이번에는 gridView.beginInsertRow()를 사용하여 3행 이선희와 4행 전도연 사이에 빈 행을 삽입해보도록 하겠습니다. 눈에 보이는 순서인 itemIndex를 사용하기 때문에 정렬과 상관 없이 전도연이 위치한 순서 3를 지정합니다.
    (이선희 itemIndex: 2, 전도연 itemIndex: 3)

        
     $("#btnInsertRow1").click(function () {
         gridView.beginInsertRow(3);     
     });

    버튼을 클릭하면 행이 추가 됩니다. 이름컬럼에만 “하하”라고 입력 후 다른 행을 클릭하거나 이동하여 행을 커밋(commit())시킵니다. 이름 컬럼으로 정렬되어 있기 때문에 방금 추가한 하하는 맨 마지막 행으로 이동하게 됩니다.

  5. 2번, 4번 과정에서 발생되었던 의도되지 않은 행 이동을 방지하기 위해 sortMode를 “explicit”로 지정합니다. 필터링시에도 같은 현상이 일어나기때문에 filterMode도 같이 지정하겠습니다.
    (실습의 편의를 위해 그리드는 초기상태로 바꾸도록 하겠습니다.)

        
     $("#btnSetOptions").click(function () {
         gridView.orderBy([],[]);
    
         var data = [
             ["배우", "여자", "전도연", "100", "100", "90", "70", "95", "100", "80"],
             ["가수", "여자", "이선희", "100", "100", "90", "70", "95", "100", "80"],
             ["배우", "여자", "하지원", "100", "100", "90", "70", "95", "100", "80"],
             ["가수", "여자", "박정현", "100", "100", "90", "70", "95", "100", "80"],
             ["배우", "여자", "전지현", "100", "100", "90", "70", "95", "100", "80"]
         ];
         dataProvider.setRows(data);   
    
         //sortMode, filterMode 설정
         gridView.setOptions({
             sortMode: "explicit",
             filterMode: "explicit"
         })
     });
  6. 1번의 버튼을 클릭하여 이름 컬럼을 오름차순 정렬을 합니다.

  7. 2번의 버튼을 클릭하여 결과를 확인 합니다. 정상적으로 전도연과 전지현 사이에 빈 행이 삽입됩니다.
    새로 추가된 행의 itemIndex는 3이며 dataRow는 4 입니다.
    dataRow가 4인 이유는 dataRow가 3과 4사이에 신규행이 추가되면서 신규행이 4가 되고 그 이후의 데이터행은 +1 이 되기 때문입니다.

  8. 3번의 버튼을 클릭하여 결과를 확인 합니다. gridView.beginInsertRow(3) 이기 때문에 전도연과 새로 추가된 행 사이에 추가 됩니다.

  9. 현재까지 실습한 내용으로는 내가 지정한 행의 위로 행 삽입이 이루어졌습니다. ex) beginInsertRow(3) : 3번째 위에 행추가. 업무에 따라 아래에 추가하고 싶은 경우는 beginInsertRow()의 2번째 인자인 shift를 true로 지정하면 아래에 추가 됩니다.

        
     $("#btnInsertRow2").click(function () {
         gridView.beginInsertRow(1, true);
     });

    버튼을 클릭하면 이선희와 전도연 사이에 행이 삽입 됩니다. shift를 지정하지 않았다면 박정현과 이선희 사이에 추가되었을 것입니다.

실행화면

  1. sortMode가 “auto”이기 때문에 의도한 위치에 삽입되지 않고 첫 행으로 이동합니다.

  2. 이름컬럼에만 “하하”라고 입력 후 다른 행을 클릭하거나 이동하여 행을 커밋(commit())시킵니다. 이름 컬럼으로 정렬되어 있기 때문에 방금 추가한 하하는 맨 마지막 행으로 이동하게 됩니다.

  3. 1번의 버튼을 클릭하여 이름 컬럼을 오름차순 정렬을 합니다.

  4. 2번의 버튼을 클릭하여 결과를 확인 합니다. 정상적으로 전도연과 전지현 사이에 빈 행이 삽입됩니다.
    새로 추가된 행의 itemIndex는 3이며 dataRow는 4 입니다.

  5. 4번의 버튼을 클릭하고 이름컬럼에 “하하”를 입력하고 commit()후 결과를 확인 합니다. gridView.beginInsertRow(3) 이기 때문에 전도연과 새로 추가된 행 사이에 추가 됩니다.

전체 소스코드

SCRIPT
<link rel="stylesheet" href="/css/bootstrap.css">
<script type="text/javascript" src="/script/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="/script/bootstrap.min.js"></script>
<!--realgrid-->
<script type="text/javascript" src="/script/realgridjs-lic.js"></script>
<script type="text/javascript" src="/script/realgridjs_eval.1.1.27.min.js"></script>
<script type="text/javascript" src="/script/realgridjs-api.1.1.27.js"></script>

<script>
var gridView;
var dataProvider;

$(document).ready( function(){
    RealGridJS.setTrace(false);
    RealGridJS.setRootContext("/script");
    
    dataProvider = new RealGridJS.LocalDataProvider();
    gridView = new RealGridJS.GridView("realgrid");
    gridView.setDataSource(dataProvider);

    gridView.setEditOptions({
        insertable: true
    });


    //필드 배열 객체를 생성합니다.
    var fields = [
        {
            fieldName: "field1"
        },
        {
            fieldName: "field2"
        },
        {
            fieldName: "field3"
        },
        {
            fieldName: "field4"
        },
        {
            fieldName: "field5"
        },
        {
            fieldName: "field6"
        },
        {
            fieldName: "field7"
        },
        {
            fieldName: "field8"
        },
        {
            fieldName: "field9"
        },
        {
            fieldName: "field10"
        }
    ];
    //DataProvider의 setFields함수로 필드를 입력합니다.
    dataProvider.setFields(fields);

    //필드와 연결된 컬럼 배열 객체를 생성합니다.
    var columns = [
        {
            name: "col1",
            fieldName: "field1",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "직업"
            },
            width : 60
        },
        {
            name: "col2",
            fieldName: "field2",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "성별"
            },
            width: 50
        },
        {
            name: "col3",
            fieldName: "field3",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "이름"
            },
            width: 80
        },
        {
            name: "col4",
            fieldName: "field4",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "국어"
            },
            width: 80
        },
        {
            name: "col5",
            fieldName: "field5",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "수학"
            },
            width: 80
        },
        {
            name: "col6",
            fieldName: "field6",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "민법"
            },
            width: 80
        },
        {
            name: "col7",
            fieldName: "field7",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "한국사"
            },
            width: 80
        },
        {
            name: "col8",
            fieldName: "field8",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "영어"
            },
            width: 80
        },
        {
            name: "col9",
            fieldName: "field9",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "과학"
            },
            width: 80
        },
        {
            name: "col10",
            fieldName: "field10",
            renderer: {
                showTooltip: true
            },
            header : {
                text: "사회"
            },
            width: 80
        }
    ];
    //컬럼을 GridView에 입력 합니다.
    gridView.setColumns(columns);

    var data = [
        ["배우", "여자", "전도연", "100", "100", "90", "70", "95", "100", "80"],
        ["가수", "여자", "이선희", "100", "100", "90", "70", "95", "100", "80"],
        ["배우", "여자", "하지원", "100", "100", "90", "70", "95", "100", "80"],
        ["가수", "여자", "박정현", "100", "100", "90", "70", "95", "100", "80"],
        ["배우", "여자", "전지현", "100", "100", "90", "70", "95", "100", "80"]
    ];
    dataProvider.setRows(data);

    //소트
    $("#btnOrderBy").click(function () {
        gridView.orderBy(["field3"],["ascending"])
    });

    $("#btnInsertRow0").click(function () {
        dataProvider.insertRow(4, []);  //전지현의 dataRow 4 위에 삽입..
    });

    $("#btnInsertRow1").click(function () {
        gridView.beginInsertRow(3);     
    });

    $("#btnSetOptions").click(function () {
        gridView.orderBy([],[]);

        var data = [
            ["배우", "여자", "전도연", "100", "100", "90", "70", "95", "100", "80"],
            ["가수", "여자", "이선희", "100", "100", "90", "70", "95", "100", "80"],
            ["배우", "여자", "하지원", "100", "100", "90", "70", "95", "100", "80"],
            ["가수", "여자", "박정현", "100", "100", "90", "70", "95", "100", "80"],
            ["배우", "여자", "전지현", "100", "100", "90", "70", "95", "100", "80"]
        ];
        dataProvider.setRows(data);   

        //sortMode, filterMode 설정
        gridView.setOptions({
            sortMode: "explicit",
            filterMode: "explicit"
        })
    });

    $("#btnInsertRow2").click(function () {
        gridView.beginInsertRow(1, true);
    });

});   
</script>
HTML
1. <button type="button" class="btn btn-primary btn-xs" id="btnOrderBy">이름 컬럼을 오름차순 정렬</button> 

2. <button type="button" class="btn btn-primary btn-xs" id="btnInsertRow0">3행 전도연과 4행 전지현 사이에 빈 행을 삽입(insertRow())</button> 

3. sortMode가 "auto"이기 때문에 의도한 위치에 삽입되지 않고 첫 행으로 이동합니다.

4. <button type="button" class="btn btn-primary btn-xs" id="btnInsertRow1">다시 3행 이선희와 4행 전도연 사이에 빈 행을 삽입(beginInsertRow())</button> 이름컬럼에만 "하하"라고 입력 후 다른 행을 클릭하거나 이동하여 행을 커밋(commit())시킵니다. 이름 컬럼으로 정렬되어 있기 때문에 방금 추가한 하하는 맨 마지막 행으로 이동하게 됩니다.

5. <button type="button" class="btn btn-primary btn-xs" id="btnSetOptions">그리드 초기화 및 sortMode를 "explicit"로 지정</button> 

6. 1번의 버튼을 클릭하여 이름 컬럼을 오름차순 정렬을 합니다.

7. 2번의 버튼을 클릭하여 결과를 확인 합니다. 정상적으로 전도연과 전지현 사이에 빈 행이 삽입됩니다.  
   새로 추가된 행의 itemIndex는 3이며 dataRow는 4 입니다.     

8. 3번의 버튼을 클릭하여 결과를 확인 합니다. gridView.beginInsertRow(3) 이기 때문에 전도연과 새로 추가된 행 사이에 추가 됩니다.  

4. <button type="button" class="btn btn-primary btn-xs" id="btnInsertRow2">이선희와 전도연 사이에 행이 삽입(beginInsertRow(1, true))</button> 

<div id="realgrid" style="width: 100%; height: 300px;"></div>

참조