들어가며

이번 강좌에서는 A23 데이터 편집하기(Editing)에서 배워보았던 행 삽입 / 행 추가에 대하여 조금 더 자세히 배워보도록 하겠습니다.

이론

행 삽입 / 행 추가 방법은 두가지 방법이 존재합니다. 그리드에서 직접 키 입력을 이용하여 추가하는 방법이 있습니다. 또 다른 하나는 리얼그리드에서 제공하는 API를 사용하여 추가하는 방법이 있습니다.

API를 이용하여 추가하는 방법은 또 두 가지 수준에서 선택할 수 있습니다. Grid 수준, DataProvider 수준 입니다. 이 두 개의 수준에서 지원하는 API는 차이가 존재합니다. 우선 그리드 수준에서는 GridView.beginInsertRow(), GridView.beginAppendRow() 를 사용하여 행을 추가할 수 있고, 데이터프로바이더 수준에서는 LocalDataProvider.insertRow(), LocalDataProvider.insertRows()를 사용하여 행을 추가 할 수 있습니다.

아래에서는 이 두개의 차이가 무엇인지 각각의 API를 통해 확인해보고, 해당 기능을 습득해보도록 하겠습니다.

그리드에서 행 추가 하기

우선 그리드에서 행을 삽입하거나 추가하기 위해서는 사전에 확인을 해야 할 것이 있습니다. 그리드의 editOptions()insertable, appendable 이 두 속성이 그것입니다. 이 두 개의 속성이 true 로 되어 있어야 사용자의 키 입력이나 API 를 통해 행 삽입이나 추가가 가능합니다.

그리드의 editOptions의 속성을 변경하는 것은 GridBase.setEditOptions()을 통해 가능합니다. 설정 방법을 잘 모르시겠다면 연계 강좌인 A23 데이터 편집하기(Editing)을 다시 한번 학습해보세요.

editOptions()을 설정하셨다면 먼저 키보드로 삽입 / 추가 하는 방법은 아래와 같습니다.
삽입 : 삽입할 위치에서 INSERT key 를 입력합니다.
추가 : 가장 마지막 행에서 DOWN ARROW key를 입력합니다.

다음은 리얼그리드가 제공하는 API를 통해 삽입하는 방법을 배워보도록 하겠습니다.
GridView.beginInsertRow(itemIndex)를 사용하여 원하는 위치에 삽입할 수 있습니다.
GridView.beginAppendRow()을 사용하면 가장 마지막 행에 추가됩니다.

그리드 수준에서 추가한 경우 그리드는 행 추가 후 편집상태에 들어가고 편집 완료(GridBase.commit())되기 전까지는 DataProvider에 반영되지 않습니다. 따라서 사용자나 개발자가 필요에 따라 편집을 취소(ESC key or GridBase.cancel())하여 행 삽입/추가를 무효화 시킬 수 있습니다.

데이터 프로바이더에서 행 추가 하기

데이터 프로바이더에서 추가하는 것인 그리드에 비해 매우 간단합니다. 여기에서 행을 추가하는 것은 API를 통해서만 가능하고, 데이터 프로바이더는 삽입의 개념만 있기 때문에 LocalDataProvider.insertRow(), LocalDataProvider.insertRows()만 있습니다.

그리드 수준에서의 삽입과 추가는 단순히 행만 추가하고 데이터의 입력은 없었습니다. 반면 데이터 프로바이더에서의 삽입은 데이터까지 함께 입력할 수 있고 이미 commit()까지 완료된 상태와 같습니다. 따라서 cancel()을 사용하여 삽입된 행을 취소할 수 없으며, 취소가 필요할 경우 LocalDataProvider.removeRow()등의 함수를 사용하여 행을 삭제해야만 합니다.

LocalDataProvider.insertRow(row, values)
row : 삽입할 위치의 dataRow
values : 입력할 한 행의 데이터, 입력할 데이터를 필드 순서대로 입력하거나 json타입의 데이터로 입력할 수 있습니다.

LocalDataProvider.insertRows(row, rows, start, count, rowEvents)
row : 삽입할 위치의 dataRow
rows : 입력할 여러 행의 데이터들, 필드 순서대로 된 데이터들의 배열이거나 json타입의 데이터들의 배열을 지정합니다.
start : rows에서 지정된 데이터셋 중에서 몇번째 행부터 가져올 것인지를 지정합니다.
count : start 행에서 시작해서 몇개의 행을 삽입할 것인를 지정합니다.
rowEvents : true 로 지정하면 행이 삽입될때마다 LocalDataProvider.onRowInserted 가 발생하고, false 로 지정하면 모든 행이 삽입된 후 LocalDataProvider.onRowsInserted 가 발생합니다.

실습

실습에서는 위에서 언급한 API들을 실행해보면서 기능을 습득하고 LocalDataProvider.onRowInserted(), LocalDataProvider.onRowsInserted() 이 두 개의 콜백함수가 어느 경우에 발생하는지 확인해보도록 하겠습니다.

  1. 버튼을 클릭하면 콜백 함수를 설정합니다.

     $("#btnSetCallback").click(function () {
         dataProvider.onRowInserted = function (provider, row) {
           alert("onRowInserted - 한행씩 " + row);
         };
         dataProvider.onRowsInserted = function (provider, row, count) {
           alert("onRowsInserted - 한번만 " + row + ',' + count);
         };    
     });
  2. 버튼을 클릭하면 2행에 비어있는 한 행이 삽입됩니다.

     $("#btnBeginInsertRow").click(function () {
         gridView.beginInsertRow(1);    
     });
  3. 버튼을 클릭하면 마지막행에 비어있는 한 행이 추가됩니다.

     $("#btnBeginAppendRow").click(function () {
         gridView.beginAppendRow();    
     });
  4. 버튼을 클릭하면 5행에 배우 원빈이 삽입됩니다.

     $("#btnInsertRow").click(function () {
         var values = ['배우', '남자', '원빈', '7', '100', '90', '80', '70', '60', '50'];
         dataProvider.insertRow(4, values);    
     });
  5. 버튼을 클릭하면 9행과 10행 사이에 3개의 행이 추가됩니다.

     $("#btnInsertRows1").click(function () {
         var rows = [
           ['배우', '남자', '김상중', '11', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '황정민', '12', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '유해진', '13', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '오달수', '14', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '송강호', '15', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '유아인', '16', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '강동원', '17', '100', '90', '80', '70', '60', '50']
         ];
         dataProvider.insertRows(9, rows, 0, 3, true);      
     });
  6. 버튼을 클릭하면 첫행에 4개의 행이 추가됩니다.

     $("#btnInsertRows2").click(function () {
         var rows = [
           ['배우', '남자', '김상중', '11', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '황정민', '12', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '유해진', '13', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '오달수', '14', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '송강호', '15', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '유아인', '16', '100', '90', '80', '70', '60', '50'],
           ['배우', '남자', '강동원', '17', '100', '90', '80', '70', '60', '50']
         ];
         dataProvider.insertRows(0, rows, 3, 4, false);      
     });

실행화면

  1. 버튼을 클릭하면 콜백 함수를 설정합니다. 화면에는 아무 변화가 없습니다.

  2. 버튼을 클릭하면 2행에 비어있는 한 행이 삽입됩니다. 행이 삽입된 후 바로 ESC key를 누르면 행 삽입이 취소되며, 데이터를 입력 후 commit() 되기 전이라면 ESC key를 두번 입력하면 행 삽입이 취소 됩니다. 데이터를 입력 후 commit() 되면 콜백이 발생합니다.

  3. 버튼을 클릭하면 마지막행에 비어있는 한 행이 추가됩니다. 행이 추가된 후 바로 ESC key를 누르면 행 추가가 취소되며, 데이터를 입력 후 commit() 되기 전이라면 ESC key를 두번 입력하면 행 추가가 취소 됩니다. 데이터를 입력 후 commit() 되면 콜백이 발생합니다.

  4. 버튼을 클릭하면 5행에 배우 원빈이 삽입됩니다. 버튼을 클릭하자마자 콜백이 발생합니다. 삽입된 행을 ESC key를 입력하여 행 삽입을 취소 할 수 없습니다.

  5. 버튼을 클릭하면 9행과 10행 사이에 3개의 행이 추가됩니다.(김상중~유해진) 버튼을 클릭하자마자 한행이 삽입 될때마다 콜백이 발생합니다.

  6. 버튼을 클릭하면 첫행에 4개의 행이 추가됩니다.(오달수~강동원) 버튼을 클릭하자마자 4개의 행이 삽입된 후 콜백이 한번만 발생합니다.

전체 소스코드

SCRIPT
<link rel="stylesheet" href="/css/bootstrap.css">
<script type="text/javascript" src="/script/jquery-1.112.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.0.14.min.js"></script>
<script type="text/javascript" src="/script/realgridjs-api.1.0.14.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);

    //필드 배열 객체를  생성합니다.
    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",
            header : {
                text: "직업"
            },
            width : 60
        },
        {
            name: "col2",
            fieldName: "field2",
            header : {
                text: "성별"
            },
            width: 50
        },
        {
            name: "col3",
            fieldName: "field3",
            header : {
                text: "이름"
            },
            width: 80
        },
        {
            name: "col4",
            fieldName: "field4",
            header : {
                text: "국어"
            },
            width: 80
        },
        {
            name: "col5",
            fieldName: "field5",
            header : {
                text: "수학"
            },
            width: 80
        },
        {
            name: "col6",
            fieldName: "field6",
            header : {
                text: "민법"
            },
            width: 80
        },
        {
            name: "col7",
            fieldName: "field7",
            header : {
                text: "한국사"
            },
            width: 80
        },
        {
            name: "col8",
            fieldName: "field8",
            header : {
                text: "영어"
            },
            width: 80
        },
        {
            name: "col9",
            fieldName: "field9",
            header : {
                text: "과학"
            },
            width: 80
        },
        {
            name: "col10",
            fieldName: "field10",
            header : {
                text: "사회"
            },
            width: 80
        }
    ];
    //컬럼을 GridView에 입력 합니다.
    gridView.setColumns(columns);

    var data = [
        ["배우", "여자", "전도연", "0", "70", "90", "70", "60", "100", "80"],
        ["가수", "여자", "이선희", "1", "33", "90", "70", "60", "100", "80"],
        ["배우", "여자", "하지원", "2", "100", "90", "70", "60", "100", "80"],
        ["가수", "여자", "박정현", "3", "90", "90", "70", "60", "100", "80"],
        ["배우", "여자", "전지현", "4", "100", "90", "70", "60", "100", "80"],
        ["가수", "남자", "이승환", "7", "100", "100", "100", "100", "100", "100"],
        ["가수", "남자", "신해철", "8", "100", "100", "100", "100", "100", "100"],
        ["가수", "남자", "타블로", "9", "100", "100", "100", "100", "100", "100"],
        ["가수", "남자", "토이", "10", "100", "100", "100", "100", "100", "100"]
    ];
    dataProvider.setRows(data);

    gridView.setOptions({
        indicator: {visible: true},        
        checkBar: {visible: false},
        stateBar: {visible: true},
        edit: {insertable: true, appendable: true}
    });

    //버튼을 클릭하면 콜백 함수를 설정합니다.
    $("#btnSetCallback").click(function () {
        dataProvider.onRowInserted = function (provider, row) {
          alert("onRowInserted - 한행씩 " + row);
        };
        dataProvider.onRowsInserted = function (provider, row, count) {
          alert("onRowsInserted - 한번만 " + row + ',' + count);
        };    
    });  

    //버튼을 클릭하면 2행에 비어있는 한 행이 삽입됩니다. 
    $("#btnBeginInsertRow").click(function () {
        gridView.beginInsertRow(1);    
    });

    //버튼을 클릭하면 마지막행에 비어있는 한 행이 추가됩니다.   
    $("#btnBeginAppendRow").click(function () {
        gridView.beginAppendRow();    
    });

    //버튼을 클릭하면 5행에 배우 원빈이 삽입됩니다.
    $("#btnInsertRow").click(function () {
        var values = ['배우', '남자', '원빈', '50', '100', '90', '80', '70', '60', '50'];
        dataProvider.insertRow(4, values);    
    });

    //버튼을 클릭하면 9행과 10행 사이에 3개의 행이 추가됩니다.
    $("#btnInsertRows1").click(function () {
        var rows = [
          ['배우', '남자', '김상중', '11', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '황정민', '12', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '유해진', '13', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '오달수', '14', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '송강호', '15', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '유아인', '16', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '강동원', '17', '100', '90', '80', '70', '60', '50']
        ];
        dataProvider.insertRows(9, rows, 0, 3, true);      
    });

    //버튼을 클릭하면 첫행에 4개의 행이 추가됩니다.
    $("#btnInsertRows2").click(function () {
        var rows = [
          ['배우', '남자', '김상중', '11', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '황정민', '12', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '유해진', '13', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '오달수', '14', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '송강호', '15', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '유아인', '16', '100', '90', '80', '70', '60', '50'],
          ['배우', '남자', '강동원', '17', '100', '90', '80', '70', '60', '50']
        ];
        dataProvider.insertRows(0, rows, 3, 4, false);      
    });
});   
 
</script>

HTML
1. <button type="button" class="btn btn-primary btn-xs" id="btnSetCallback">SetCallback</button> 버튼을 클릭하면 콜백 함수를 설정합니다. 화면에는 아무 변화가 없습니다.

2. <button type="button" class="btn btn-primary btn-xs" id="btnBeginInsertRow">beginInsertRow(1)</button> 버튼을 클릭하면 2행에 비어있는 한 행이 삽입됩니다. 행이 삽입된 후 바로 `ESC` key를 누르면 행 삽입이 취소되며, 데이터를 입력 후 commit() 되기 전이라면 `ESC` key를 두번 입력하면 행 삽입이 취소 됩니다. 데이터를 입력 후 commit() 되면 콜백이 발생합니다.

3. <button type="button" class="btn btn-primary btn-xs" id="btnBeginAppendRow">beginAppendRow()</button> 버튼을 클릭하면 마지막행에 비어있는 한 행이 추가됩니다. 행이 추가된 후 바로 `ESC` key를 누르면 행 추가가 취소되며, 데이터를 입력 후 commit() 되기 전이라면 `ESC` key를 두번 입력하면 행 추가가 취소 됩니다. 데이터를 입력 후 commit() 되면 콜백이 발생합니다.

4. <button type="button" class="btn btn-primary btn-xs" id="btnInsertRow">insertRow(4, values)</button> 버튼을 클릭하면 5행에 배우 원빈이 삽입됩니다. 버튼을 클릭하자마자 콜백이 발생합니다. 삽입된 행을 `ESC` key를 입력하여 행 삽입을 취소 할 수 없습니다.

5. <button type="button" class="btn btn-primary btn-xs" id="btnInsertRows1">insertRows(9, rows, 0, 3, true)</button> 버튼을 클릭하면 9행과 10행 사이에 3개의 행이 추가됩니다. 버튼을 클릭하자마자 한행이 삽입 될때마다 콜백이 발생합니다.

6. <button type="button" class="btn btn-primary btn-xs" id="btnInsertRows2">insertRows(12, rows, 3, 4, false)</button> 버튼을 클릭하면 12행과 13행 사이에 4개의 행이 추가됩니다. 버튼을 클릭하자마자 4개의 행이 삽입된 후 콜백이 한번만 발생합니다.

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


튜토리얼 참조


데모 사이트


API 참조