들어가며

이번 강좌에서는 행의 상태 또는 다른 컬럼의 값에 따라 셀의 편집 가능 여부를 조정하는 방법에 대해 배워보겠습니다.

이론

새로 추가된 행인 경우에만 컬럼의 값을 수정할 수 있도록 변경하는 것은 업무프로그램에서 자주 요구되는 내용중 하나입니다. RealGrid의 경우 특정 row의 편집여부를 지정할수는 없지만 이벤트를 이용해서 그리드 전체의 editable을 변경하여 처리할 수 있습니다.

이번 강좌에서 배울 내용은

  1. 신규행인 경우에는 모든 컬럼을 편집할수 있도록 변경
  2. 기존행(DB조회등)인 경우 특정컬럼만 편집할수 있도록 변경
  3. 다른 컬럼의 값에 따라 특정컬럼을 편집할수 있도록 변경
GridBase.onCurrentRowChagned 이벤트

onCurrentRowChanged 이벤트는 그리드에서 선택된 Row가 변경되거나 Sorting, Filtering이 발생해서 선택된 셀의 DataRow가 변경될때 발생합니다. 선택된 행이 신규행인지를 판단하기 위해서 사용합니다.

grid.onCurrentRowChanged = function (grid, oldRow, newRow) {
    var provider = grid.getDataProvider();
    var columns = grid.getColumnNames();
    var editable = newRow < 0 || provider.getRowState(newRow) === "created";

    if (!editable) { // 신규행이 아니면. 전체컬럼 editable:false
        columns.forEach(function(obj) {
            grid.setColumnProperty(obj,"editable",false)
        });
        var value = provider.getValue(newRow,"field1");
        // editable을 true로할 컬럼
        if (value === "배우") {
            columns = ["col1","col4"]
        } else {
            columns = ["col1"];
        };
    };
    columns.forEach(function(obj) {
        grid.setColumnProperty(obj,"editable",true)
    });
};
GridBase.onEditCommit 이벤트

셀 편집이 완료되어 editor의 내용이 그리드 내부버퍼에 저장되기 직전에 발생하는 이벤트입니다. 컬럼의 값에 따라서 다른 컬럼의 편집여부를 결정하기 위해 사용합니다.

grid.onEditCommit = function (grid, index, oldValue, newValue) {
    if (index.dataRow >= 0 && grid.getDataProvider().getRowState(index.dataRow) !== "created" && index.fieldName === "field1") {
        if (newValue === "배우") {
            grid.setColumnProperty("col4","editable",true);
        }
        else {
            grid.setColumnProperty("col4","editable",false);
        }
    };
};

실습

실습에서는 새로 추가된행인 경우에는 모든 컬럼을 편집할 수 있고 기존행인 경우 직업컬럼만 편집할 수 있도록 코드를 작성하겠습니다. 추가로 직업이 배우인 데이터는 국어컬럼을 수정할 수 있도록 만들겠습니다.

  1. 이벤트에 필요한 코드 추가.

     grid.onCurrentRowChanged = function (grid, oldRow, newRow) {
         var provider = grid.getDataProvider();
         var columns = grid.getColumnNames();
         var editable = newRow < 0 || provider.getRowState(newRow) === "created";
    
         if (!editable) { // 신규행이 아니면. 전체컬럼 editable:false
             columns.forEach(function(obj) {
                 grid.setColumnProperty(obj,"editable",false)
             });
             var value = provider.getValue(newRow,"field1");
             // editable을 true로할 컬럼
             if (value === "배우") {
                 columns = ["col1","col4"]
             } else {
                 columns = ["col1"];
             };
         };
         columns.forEach(function(obj) {
             grid.setColumnProperty(obj,"editable",true)
         });
     };    
     grid.onEditCommit = function (grid, index, oldValue, newValue) {
         if (index.dataRow >= 0 && grid.getDataProvider().getRowState(index.dataRow) !== "created" && index.fieldName === "field1") {
             if (newValue === "배우") {
                 grid.setColumnProperty("col4","editable",true);
             }
             else {
                 grid.setColumnProperty("col4","editable",false);
             }
         };
     };
     provider.onRowDeleted = function (provider, row) {
         gridView.onCurrentRowChanged(gridView,gridView.getCurrent().dataRow,gridView.getCurrent().dataRow)
         // 데이터가 삭제되는 경우 onCurrentRowChange가 발생하지 않게 때문에 이벤트를 실행하는 코드를 추가.
     }
     provider.onRowsDeleted = function (provider, rows) {
         gridView.onCurrentRowChanged(gridView,gridView.getCurrent().dataRow,gridView.getCurrent().dataRow)
         // 
     }
     

실행화면

직업이 배우인 행은 직업과 국어 컬럼이 편집가능합니다. 직업이 배우가 아닌 행은 직업 컬럼만 편집가능합니다. 신규행은 전체 컬럼이 편집가능합니다.

전체 소스코드

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.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);

    gridView.setEditOptions({insertable:true, appendable:true});

    var data = [
        ["가수", "여자", "정수라", "80", "99", "90", "90", "100", "100", "90"],
        ["배우", "여자", "송윤아", "10", "33", "90", "70", "60", "100", "80"],
        ["배우", "여자", "전도연", "20", "22", "90", "70", "60", "100", "80"],
        ["가수", "여자", "이선희", "40", "33", "90", "70", "60", "100", "80"],
        ["배우", "여자", "하지원", "10", "11", "90", "70", "60", "100", "80"],
        ["가수", "여자", "소찬휘", "30", "55", "90", "70", "60", "100", "80"],
        ["가수", "여자", "박정현", "40", "22", "90", "70", "60", "100", "80"],
        ["배우", "여자", "전지현", "20", "44", "90", "70", "60", "100", "80"]
    ];
    dataProvider.setRows(data);
    gridView.onEditCommit = function (grid, index, oldValue, newValue) {
        if (index.dataRow >= 0 && dataProvider.getRowState(index.dataRow) !== "created" && index.fieldName === "field1") {
            if (newValue === "배우") {
                grid.setColumnProperty("col4","editable",true);
            }
            else {
                grid.setColumnProperty("col4","editable",false);
            }
        };
    };
    gridView.onCurrentRowChanged = function (grid, oldRow, newRow) {
        var columns = grid.getColumnNames();
        var editable = newRow < 0 || dataProvider.getRowState(newRow) === "created";

        if (!editable) { // 신규행이 아니면. 전체컬럼 editable:false
            columns.forEach(function(obj) {
                grid.setColumnProperty(obj,"editable",false)
            });
            var value = dataProvider.getValue(newRow,"field1");
            // editable을 true로할 컬럼
            if (value === "배우") {
                columns = ["col1","col4"]
            } else {
                columns = ["col1"];
            };
        };
        columns.forEach(function(obj) {
            grid.setColumnProperty(obj,"editable",true)
        });

    };
    dataProvider.onRowDeleted = function (provider, row) {
        gridView.onCurrentRowChanged(gridView,gridView.getCurrent().dataRow,gridView.getCurrent().dataRow)
        // 데이터가 삭제되는 경우 onCurrentRowChange가 발생하지 않게 때문에 이벤트를 실행하는 코드를 추가.
    }
    dataProvider.onRowsDeleted = function (provider, rows) {
        gridView.onCurrentRowChanged(gridView,gridView.getCurrent().dataRow,gridView.getCurrent().dataRow)
    }
});   
</script>
HTML
<div id="realgrid" style="width: 100%; height: 200px;"></div>

참조