들어가며

이번 강좌에서는 삽입/추가된(이하 추가) 행만 편집 가능하게 처리하는 방법을 배워보도록 하겠습니다.

이론

그리드에 행을 추가하는 방법은 크게 두가지로 나누어 볼 수 있습니다.

1. GridView에서 행을 추가하는 방법

GridView.Editptions의 insertable, appendable 속성이 true 이면 GridView.beginInsertRow(), GridView.beginAppendRow()로 행을 추가할 수 있습니다.
또한 사용자가 키보드로 Ctrl + Insert 키를 입력해서 같은 효과를 볼 수 있습니다.

2. DataProvider에서 행을 추가하는 방법

DataProvider.insertRow()로 행을 추가하는 방법이 있습니다.

행 추가에 대한 자세한 내용은 B7-2 Insert and Add Rows를 참고하세요.

위의 두가지 방법의 차이점은 아래와 같습니다.
GridView에서 행을 추가하게 되면 GridView에는 하나의 행이 추가되지만 DataProvider에는 행이 추가되지 않습니다. 이런 상태를 Inserting 상태(Indicator에 종이형태+표식) 라 하는데 이 상태에서는 ESC key를 누르면 행 추가를 취소할 수 있습니다. DataProvider에 행이 추가되는 시점은 한 행의 편집이 끝난 시점(commit(), StateBar에 +표식)이며 이 상태에서는 ESC key를 입력해도 행 추가가 취소 되지 않습니다.

DataProvider에서 행을 추가하게 되면 DataProvider에 하나의 행이 추가되고 동시에 GridView에도 하나의 행이 추가 됩니다.(StateBar에 +표식)

행 추가 상태에 대해서 조금 더 깊이 살펴보겠습니다.
GridView에서 행 추가를 한 Inserting 상태이면(아직 Commit()전) 그 행의 itemIndex는 추가된 행의 순서 0 이상이며 dataRow는 -1 이 됩니다. (현재까지는 dataProvider에 행이 추가되지 않았기 때문에 당연히 행 상태(Row State)는 가질 수 없습니다.) 이후 행의 편집이 완료되면(commit()) 그 시점에 dataProvider에 행이 추가되어 dataRow가 지정되고 행 상태는 created로 변경되게 됩니다.

DataProvider에서 행 추가를 한 경우는 itemIndex와 dataRow가 갹 순서에 맞게 지정되며 행 상태는 created로 지정됩니다.

Editable 변경 시점

리얼그리드는 그리드나 컬럼별로 editable을 지정할 수 있으며 동적으로 특정 셀만 editable을 변경하는 것은 지원하지 않습니다.
동적으로 editable을 변경하는 것은 선택된 행이 바뀔때마다(GridView.onCurrentRowChanged()) 그리드나 컬럼의 editable을 변경하여 기능상 유사하게 처리할 수 있습니다.

이 내용을 토대로 삽입/추가된 행만 편집 가능하게 처리해보도록 하겠습니다.

실습

실습에서는 행을 추가해 보고 추가된 행만 편집 가능하게 하거나 특정 컬럼만 편집 가능하게 처리해보도록 하겠습니다.

  1. 추가된 행만 편집 가능하게, 조회된 행은 수정 불가하게 처리하겠습니다.

     //선택된 행이 변경되었을때의 동작  
     $("#btnSetOnCurrentRowChanged").click(function () {
         gridView.onCurrentRowChanged = function (grid, oldRow, newRow) {
             var curr = grid.getCurrent();
             var rowState = newRow > -1 ? dataProvider.getRowState(newRow) : "";
             //그리드에 beginInsertRow(), beginAppendRow()로 행이 추가된 경우 || dataProvider에 새로 추가된 행인 경우
             var editable =  (newRow == -1 && curr.itemIndex > -1) || (rowState == "created");
    
             grid.setEditOptions({
                 "editable": editable
             })    
         }
     });
  2. 현재 선택되어 있는 행과 다른 행을 선택한 후 값을 수정해보세요.(수정되지 않습니다)

  3. Ctrl + Insert 키를 입력해서 빈 행을 추가하고 값을 입력해보세요.(행을 바꾸면 commit()이 됩니다.)

  4. 추가한 행과 추가하지 않은 행을 선택해보면서 값을 수정해보세요. (추가된 행만 값이 수정됩니다.)

  5. 이번에는 추가된 행중 특정 컬럼만 편집 가능하게(직업은 수정 불가, 나머지 컬럼만 수정 가능하게 처리), 조회된 행은 수정 불가하게 처리하겠습니다.

     //선택된 행이 변경되었을때의 동작  
     $("#btnSetOnCurrentRowChanged1").click(function () {
         gridView.onCurrentRowChanged = function (grid, oldRow, newRow) {
             var curr = grid.getCurrent();
             var rowState = newRow > -1 ? dataProvider.getRowState(newRow) : "";
             //그리드에 beginInsertRow(), beginAppendRow()로 행이 추가된 경우 || dataProvider에 새로 추가된 행인 경우
             var editable =  (newRow == -1 && curr.itemIndex > -1) || (rowState == "created");
    
             grid.setEditOptions({
                 "editable": editable
             })     
    
             grid.setColumnProperty("col1", "editable", !editable);
             grid.setColumnProperty("col2", "editable", editable);
             grid.setColumnProperty("col3", "editable", editable);
             grid.setColumnProperty("col4", "editable", editable);
             grid.setColumnProperty("col5", "editable", editable);
             grid.setColumnProperty("col6", "editable", editable);
             grid.setColumnProperty("col7", "editable", editable);
             grid.setColumnProperty("col8", "editable", editable);
             grid.setColumnProperty("col9", "editable", editable);
             grid.setColumnProperty("col10", "editable", editable);
    
         }
     });
  6. 버튼을 클릭하면 직업이 배우인 신규 행이 추가 됩니다.
     //직업이 배우인 행 추가.  
     $("#btnInsertRow").click(function () {
         dataProvider.insertRow(0, ["배우"]);
     });
  7. 추가한 행과 추가하지 않은 행을 선택해보면서 값을 수정해보세요. (추가된 행의 직업컬럼을 제외한 컬림의 값이 수정됩니다.)

실행화면

  1. 현재 선택되어 있는 행과 다른 행을 선택한 후 값을 수정해보세요.(수정되지 않습니다)

  2. Ctrl + Insert 키를 입력해서 빈 행을 추가하고 값을 입력해보세요.(행을 바꾸면 commit()이 됩니다.)

  3. 추가한 행과 추가하지 않은 행을 선택해보면서 값을 수정해보세요. (추가된 행만 값이 수정됩니다.)

  4. 추가한 행과 추가하지 않은 행을 선택해보면서 값을 수정해보세요. (추가된 행의 직업컬럼을 제외한 컬림의 값이 수정됩니다.)

전체 소스코드

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.24.min.js"></script>
<script type="text/javascript" src="/script/realgridjs-api.1.1.24.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({
        appendable: true,
        insertable: true
    });

    //필드 배열 객체를 생성합니다.
    var fields = [
        {
            fieldName: "field1"
        },
        {
            fieldName: "field2"
        },
        {
            fieldName: "field3"
        },
        {
            fieldName: "field4",
            dataType: "number"
        },
        {
            fieldName: "field5",
            dataType: "number"
        },
        {
            fieldName: "field6",
            dataType: "number"
        },
        {
            fieldName: "field7",
            dataType: "number"
        },
        {
            fieldName: "field8",
            dataType: "number"
        },
        {
            fieldName: "field9",
            dataType: "number"
        },
        {
            fieldName: "field10",
            dataType: "number"
        }
    ];
    //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 = [
        ["배우", "여자", "전도연", "20", "22", "90", "70", "60", "100", "80"],
        ["가수", "여자", "이선희", "40", "33", "90", "70", "60", "100", "80"],
        ["배우", "여자", "하지원", "10", "11", "90", "70", "60", "100", "80"],
        ["가수", "여자", "박정현", "40", "22", "90", "70", "60", "100", "80"],
        ["배우", "여자", "전지현", "20", "44", "90", "70", "60", "100", "80"]
    ];

    dataProvider.setRows(data);

    //선택된 행이 변경되었을때의 동작, 추가된 행만 수정 가능.  
    $("#btnSetOnCurrentRowChanged").click(function () {
        gridView.onCurrentRowChanged = function (grid, oldRow, newRow) {
            var curr = grid.getCurrent();
            var rowState = newRow > -1 ? dataProvider.getRowState(newRow) : "";
            //그리드에 beginInsertRow(), beginAppendRow()로 행이 추가된 경우 || dataProvider에 새로 추가된 행인 경우
            var editable =  (newRow == -1 && curr.itemIndex > -1) || (rowState == "created");

            grid.setEditOptions({
                "editable": editable
            })    
        }
    });

    //선택된 행이 변경되었을때의 동작, 추가된 행만 수정 가능(직업은 수정 불가)
    $("#btnSetOnCurrentRowChanged1").click(function () {
        gridView.onCurrentRowChanged = function (grid, oldRow, newRow) {
            var curr = grid.getCurrent();
            var rowState = newRow > -1 ? dataProvider.getRowState(newRow) : "";
            //그리드에 beginInsertRow(), beginAppendRow()로 행이 추가된 경우 || dataProvider에 새로 추가된 행인 경우
            var editable =  (newRow == -1 && curr.itemIndex > -1) || (rowState == "created");

            grid.setEditOptions({
                "editable": editable
            })     

            grid.setColumnProperty("col1", "editable", !editable);
            grid.setColumnProperty("col2", "editable", editable);
            grid.setColumnProperty("col3", "editable", editable);
            grid.setColumnProperty("col4", "editable", editable);
            grid.setColumnProperty("col5", "editable", editable);
            grid.setColumnProperty("col6", "editable", editable);
            grid.setColumnProperty("col7", "editable", editable);
            grid.setColumnProperty("col8", "editable", editable);
            grid.setColumnProperty("col9", "editable", editable);
            grid.setColumnProperty("col10", "editable", editable);

        }
    });

    //직업이 배우인 행 추가.  
    $("#btnInsertRow").click(function () {
        dataProvider.insertRow(0, ["배우"]);
    });

});   
</script>
HTML
1. <button type="button" class="btn btn-primary btn-xs" id="btnSetOnCurrentRowChanged">추가된 행만 수정 가능</button> 

2. 현재 선택되어 있는 행과 다른 행을 선택한 후 값을 수정해보세요.(수정되지 않습니다)

3. `Ctrl` + `Insert` 키를 입력해서 빈 행을 추가하고 값을 입력해보세요.(행을 바꾸면 commit()이 됩니다.)

4. 추가한 행과 추가하지 않은 행을 선택해보면서 값을 수정해보세요. (추가된 행만 값이 수정됩니다.)

5. <button type="button" class="btn btn-primary btn-xs" id="btnSetOnCurrentRowChanged1">추가된 행만 수정 가능(직업 수정 불가능)</button> 

6. <button type="button" class="btn btn-primary btn-xs" id="btnInsertRow">직업이 배우인 신규 행이 추가</button> 

7. 추가한 행과 추가하지 않은 행을 선택해보면서 값을 수정해보세요. (추가된 행의 직업컬럼을 제외한 컬림의 값이 수정됩니다.)

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

참조