C5 행의 상태 또는 셀의 값에 따른 셀의 editable 변경
들어가며
이번 강좌에서는 행의 상태 또는 다른 컬럼의 값에 따라 셀의 편집 가능 여부를 조정하는 방법에 대해 배워보겠습니다.
이론
새로 추가된 행인 경우에만 컬럼의 값을 수정할 수 있도록 변경하는 것은 업무프로그램에서 자주 요구되는 내용중 하나입니다. RealGrid의 경우 특정 row의 편집여부를 지정할수는 없지만 이벤트를 이용해서 그리드 전체의 editable을 변경하여 처리할 수 있습니다.
이번 강좌에서 배울 내용은
- 신규행인 경우에는 모든 컬럼을 편집할수 있도록 변경
- 기존행(DB조회등)인 경우 특정컬럼만 편집할수 있도록 변경
- 다른 컬럼의 값에 따라 특정컬럼을 편집할수 있도록 변경
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);
        }
    };
};
실습
실습에서는 새로 추가된행인 경우에는 모든 컬럼을 편집할 수 있고 기존행인 경우 직업컬럼만 편집할 수 있도록 코드를 작성하겠습니다.
추가로 직업이 배우인 데이터는 국어컬럼을 수정할 수 있도록 만들겠습니다.
- 
    이벤트에 필요한 코드 추가. 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>
참조
 RealGrid HELP
 RealGrid HELP