B7-5 Row States
들어가며
이번 강좌에서는 A23 데이터 편집하기(Editing)에서 배워보았던 행 상태(RowState)에 대하여 조금 더 자세히 배워보도록 하겠습니다.
이론
RealGrid는 행의 상태를 관리할 수 있습니다. 이 행이 편집된 행인지, 추가된 행인지, 삭제된 행인지, 또는 추가된 후 삭제된 행인지를 확인 할 수 있습니다. 행의 상태를 관리하기 위해서는 기본적으로 dataProviderOptions의 속성중 checkStates
속성값이 true로 되어 있어야 합니다. 기본값이 true이므로 별다른 설정은 필요 없습니다.
RealGrid는 사용자의 액션(추가, 수정, 삭제)에 따라 자동으로 행 상태를 관리합니다. 또한 RealGrid는 개발자의 의도에 따라 임의로 행 상태를 관리할 수도 있습니다. 아래에서는 행 상태의 종류와 행 상태에 관련된 API를 확인해보도록 하겠습니다.
행 상태(RowState)의 종류
none
: 로드된 후 변경이 없는 상태.
created
: 새로 추가된 행의 상태.
updated
: 로드된 후 하나 이상의 필드 값이 변경된 상태. created
행은 값이 변경 되어도 updated
로 변경되지 않습니다.
deleted
: 로드된 후 삭제된 행의 상태.
createAndDeleted
: 추가된 후 삭제한 행의 상태.
deleted
나 createAndDeleted
상태는 dataProvider.options.softDeleting 의 값이 true 일 경우에만 가질 수 있습니다. softDeleting = false 라면 행 삭제시 행 상태를 바꾸지 않고 바로 dataProvider에서 삭제하기 때문 입니다.
RowState 와 관련된 API들
-
DataProvider.setRowState(row, state, force)
지정한 행의 RowState를 변경하는 함수입니다.
row
: 변경하려는 dataRow를 지정합니다.
state
: 변경하려는 행 상태를 지정합니다.
force
: 현재 행 상태를 관리하지 않는 상태(checkStates=false)여도 강제로 행에 rowState를 지정할 것인지의 여부 -
DataProvider.setRowStates(rows, state, force, rowEvents) 지정한 행들의 RowState를 변경하는 함수입니다.
rows
: 변경하려는 dataRows를 지정합니다.
state
: 변경하려는 행 상태를 지정합니다.
force
: 현재 행 상태를 관리하지 않는 상태(checkStates=false)여도 강제로 행에 rowState를 지정할 것인지의 여부
rowEvents
: RowState가 변경될때 onRowStateChanged() 콜백함수를 변경되는 행 수 만큼 호출되도록 할 것인지 아니면 한번만 호출되도록 할 것인지의 여부. -
DataProvider.getRowState(row)
지정한 행의 RowState가 무엇인지 알아볼때 사용하는 함수입니다.
row
: dataRow를 지정합니다. -
DataProvider.getRowStateCount(rowStates)
지정한 RowStates에 해당하는 행들의 개수가 몇개인지 알아볼때 사용하는 함수입니다.
rowStates
: 개수가 몇개인지 알려고 하는 rowState를 지정합니다. ‘created’ 같이 문자열 형태나 [‘created’, ‘updated’] 같이 array 형태의 문자열 사용이 가능합니다. -
DataProvider.getStateRows(rowState)
지정한 RowState에 해당하는 행들을 알고 샆을때 사용하는 함수입니다. 결과는 배열로 리턴됩니다.
rowState
: 알고싶은 행 상태를 지정합니다. -
DataProvider.getAllStateRows()
RowState가 ‘none’이 아닌 모든 행의 번호를 상태별로 가져옵니다. 결과값은 ‘created’, ‘updated’, ‘deleted’, ‘createAndDeleted’ 상태 이름들을 속성으로 갖는 object이며 각 속성의 값은 해당 상태의 dataRow 배열입니다. -
DataProvider.clearRowStates(deleteRows, rowEvents)
행들에 지정되어 있는 RowState를 모두 제거한다.
deleteRows
: false 로 지정하면 모든 행들의 RowState만 ‘none’ 상태로 변경합니다. true로 지정하면 ‘deleted’나 ‘createAndDeleted’ 상태를 갖는 행들은 실제로 dataProvider에서 삭제하며 이외의 행 상태들은 ‘none’ 상태로 변경합니다.
콜백함수
행 상태 변경시 호출되는 콜백 함수는 아래와 같습니다.
- LocalDataProvider.onRowStateChanged()
- LocalDataProvider.onRowStatesChanged()
- LocalDataProvider.onRowStatesCleared()
실습
실습에서는 위에서 언급한 API들을 실행해보면서 기능을 습득하고, 위에서 언급한 세 개의 콜백함수가 어느 시점에 호출되는지 확인해보도록 하겠습니다.
-
버튼을 클릭하면 콜백 함수를 설정합니다.
$("#btnSetCallback").click(function () { dataProvider.onRowStateChanged = function (provider, row) { alert("onRowStateChanged 호출"); } dataProvider.onRowStatesChanged = function (provider, rows) { alert("onRowStatesChanged 호출"); } dataProvider.onRowStatesCleared = function (provider) { alert("onRowStatesCleared 호출"); } });
-
버튼을 클릭하면 첫 행의 RowState를 ‘created’로 변경합니다.
$("#btnSetRowStateCreated").click(function () { dataProvider.setRowState(0, 'created'); });
-
버튼을 클릭하면 3 행의 RowState를 ‘updated’로 변경합니다.
$("#btnSetRowStateUpdated").click(function () { dataProvider.setRowState(2, 'updated'); });
-
버튼을 클릭하면 5 행의 RowState를 ‘deleted’로 변경합니다.
$("#btnSetRowStateDeleted").click(function () { dataProvider.setRowState(4, 'deleted'); });
-
버튼을 클릭하면 7 행의 RowState를 ‘createAndDeleted’로 변경합니다.
$("#btnSetRowStateCreateAndDeleted").click(function () { dataProvider.setRowState(6, 'createAndDeleted'); });
-
버튼을 클릭하면 9, 10행의 상태를 ‘updated’로 변경합니다.
$("#btnSetRowStatesT").click(function () { dataProvider.setRowStates([8, 9], 'updated', true, true); });
-
버튼을 클릭하면 11, 12행의 상태를 ‘updated’로 변경합니다.
$("#btnSetRowStatesF").click(function () { dataProvider.setRowStates([10, 11], 'updated', true, false); });
-
버튼을 클릭하면 10행의 상태를 가져옵니다.
$("#btnGetRowState").click(function () { var state = dataProvider.getRowState(9); alert(state); });
-
버튼을 클릭하면 ‘deleted’상태인 행의 dataRow 목록을 가져옵니다.
$("#btnGetStateRows").click(function () { var dataRows = dataProvider.getStateRows('deleted'); alert(dataRows); });
-
버튼을 클릭하면 각 RowState 상태에 해당하는 dataRow들을 가져옵니다.
$("#btnGetAllStateRows").click(function () { var states = dataProvider.getAllStateRows(); alert(JSON.stringify(states)); });
-
버튼을 클릭하면 행 상태가 사라집니다.
$("#btnClearRowStatesF").click(function () { dataProvider.clearRowStates(false, false); });
-
버튼을 클릭하면 행 상태가 사라집니다.
$("#btnClearRowStatesT").click(function () { dataProvider.clearRowStates(true, true); });
실행화면
-
버튼을 클릭하면 콜백 함수를 설정합니다. 화면에는 아무 변화가 없습니다.
-
버튼을 클릭하면 첫 행의 RowState를 ‘created’로 변경합니다. (onRowStateChanged 호출)
-
2행을 선택 후
Ctrl
+Insert
key를 입력하여 행을 추가합니다. 행 추가 후 data를 입력하고 편집까지 완료합니다. RowState를 ‘created’로 변경되는 것을 확인하세요. (onRowStateChanged 미호출, 신규 행이기때문에 행 상태가 변경 되는것이 아니기 때문입니다.) -
버튼을 클릭하면 3 행의 RowState를 ‘updated’로 변경합니다. (onRowStateChanged 호출)
-
4행을 선택후 데이터를 수정합니다. RowState를 ‘updated’로 변경되는 것을 확인하세요. (onRowStateChanged 호출)
-
버튼을 클릭하면 5 행의 RowState를 ‘deleted’로 변경합니다. (onRowStateChanged 호출)
-
6행을 선택후
Ctrl
+Del
key를 입력하여 행을 삭제합니다. RowState를 ‘deleted’로 변경되는 것을 확인하세요. (onRowStateChanged 호출) -
버튼을 클릭하면 7 행의 RowState를 ‘createAndDeleted’로 변경합니다. (onRowStateChanged 호출)
-
‘created’ 상태인 2행을 선택 후
Ctrl
+Del
key를 입력하여 행을 삭제합니다. RowState를 ‘createAndDeleted’로 변경되는 것을 확인하세요. (onRowStateChanged 호출, 3번에서는 호출되지 않았던 onRowStateChanged가 ‘created’ 상태에서 변경되었기 때문에 이번에는 호출됩니다.) -
버튼을 클릭하면 9, 10행의 상태를 ‘updated’로 변경합니다. (마지막 파라메터인 rowEvent가 true 일 경우 화면이 갱신되지 않는 버그가 있습니다. 스크롤 바를 움직이면 rowState가 정상적으로 표시됩니다., onRowStateChanged 호출되어야 하나 버그로 인해 호출되지 않습니다.)
-
버튼을 클릭하면 11, 12행의 상태를 ‘updated’로 변경합니다. (onRowStatesChanged 호출)
-
버튼을 클릭하면 10행의 상태를 가져옵니다.
-
버튼을 클릭하면 ‘deleted’상태인 행의 dataRow 목록을 가져옵니다.
-
버튼을 클릭하면 각 RowState 상태에 해당하는 dataRow들을 가져옵니다.
-
버튼을 클릭하면 행 상태가 사라집니다. (onRowStatesCleared 호출, 첫번째 파라메터인
deleteRows
가 false 이기 때문에 행 상태가 ‘deleted’, ‘createAndDeleted’인 행들이 삭제 되지 않고 RowState만 지워졌음을 확인하세요) -
몇 개의 행을
Ctrl
+Del
key를 입력하여 행들을 ‘deleted’ 상태로 만들고, 몇 개의 행은 값을 수정하여 ‘updated’ 상태로 만들어보세요. -
버튼을 클릭하면 행 상태가 사라집니다. (‘deleted’였던 행들은 사라지고, 수정한 행 수 만큼 onRowStateChanged 호출)
전체 소스코드
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"], ["가수", "여자", "이소라", "11", "100", "100", "100", "100", "100", "100"], ["배우", "여자", "강소라", "12", "100", "100", "100", "100", "100", "100"], ["가수", "남자", "타블로", "13", "100", "100", "100", "100", "100", "100"], ["가수", "남자", "이승환", "14", "100", "100", "100", "100", "100", "100"], ["가수", "남자", "토이", "15", "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, updatable: true, editable: true, deletable: true}, sort: {enabled: false}, panel: {visible: false} }); dataProvider.setOptions({ softDeleting: true }) //버튼을 클릭하면 콜백 함수를 설정합니다. $("#btnSetCallback").click(function () { dataProvider.onRowStateChanged = function (provider, row) { alert("onRowStateChanged 호출"); } dataProvider.onRowStatesChanged = function (provider, rows) { alert("onRowStatesChanged 호출"); } dataProvider.onRowStatesCleared = function (provider) { alert("onRowStatesCleared 호출"); } }); //버튼을 클릭하면 첫 행의 RowState를 'created'로 변경합니다. $("#btnSetRowStateCreated").click(function () { dataProvider.setRowState(0, 'created'); }); //버튼을 클릭하면 3 행의 RowState를 'updated'로 변경합니다. $("#btnSetRowStateUpdated").click(function () { dataProvider.setRowState(2, 'updated'); }); //버튼을 클릭하면 5 행의 RowState를 'deleted'로 변경합니다. $("#btnSetRowStateDeleted").click(function () { dataProvider.setRowState(4, 'deleted'); }); //버튼을 클릭하면 7 행의 RowState를 'createAndDeleted'로 변경합니다. $("#btnSetRowStateCreateAndDeleted").click(function () { dataProvider.setRowState(6, 'createAndDeleted'); }); //버튼을 클릭하면 9, 10행의 상태를 'updated'로 변경합니다. $("#btnSetRowStatesT").click(function () { dataProvider.setRowStates([8, 9], 'updated', true, true); }); //버튼을 클릭하면 11, 12행의 상태를 'updated'로 변경합니다. $("#btnSetRowStatesF").click(function () { dataProvider.setRowStates([10, 11], 'updated', true, false); }); //버튼을 클릭하면 10행의 상태를 가져옵니다. $("#btnGetRowState").click(function () { var state = dataProvider.getRowState(9); alert(state); }); //버튼을 클릭하면 'deleted'상태인 행의 dataRow 목록을 가져옵니다. $("#btnGetStateRows").click(function () { var dataRows = dataProvider.getStateRows('deleted'); alert(dataRows); }); //버튼을 클릭하면 각 RowState 상태에 해당하는 dataRow들을 가져옵니다. $("#btnGetAllStateRows").click(function () { var states = dataProvider.getAllStateRows(); alert(JSON.stringify(states)); }); //버튼을 클릭하면 행 상태가 사라집니다. $("#btnClearRowStatesF").click(function () { dataProvider.clearRowStates(false, false); }); //버튼을 클릭하면 행 상태가 사라집니다. $("#btnClearRowStatesT").click(function () { dataProvider.clearRowStates(true, true); }); }); </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="btnSetRowStateCreated">setRowState(0, 'created')</button> 버튼을 클릭하면 첫 행의 RowState를 'created'로 변경합니다. (onRowStateChanged 호출) 3. 2행을 선택 후 `Ctrl`+`Insert`key를 입력하여 행을 추가합니다. 행 추가 후 data를 입력하고 편집까지 완료합니다. RowState를 'created'로 변경되는 것을 확인하세요. (onRowStateChanged 미호출, 신규 행이기때문에 행 상태가 변경 되는것이 아니기 때문입니다.) 4. <button type="button" class="btn btn-primary btn-xs" id="btnSetRowStateUpdated">setRowState(2, 'updated')</button> 버튼을 클릭하면 3 행의 RowState를 'updated'로 변경합니다. (onRowStateChanged 호출) 5. 4행을 선택후 데이터를 수정합니다. RowState를 'updated'로 변경되는 것을 확인하세요. (onRowStateChanged 호출) 6. <button type="button" class="btn btn-primary btn-xs" id="btnSetRowStateDeleted">setRowState(4, 'deleted')</button> 버튼을 클릭하면 5 행의 RowState를 'deleted'로 변경합니다. (onRowStateChanged 호출) 7. 6행을 선택후 `Ctrl`+`Del`key를 입력하여 행을 삭제합니다. RowState를 'deleted'로 변경되는 것을 확인하세요. (onRowStateChanged 호출) 8. <button type="button" class="btn btn-primary btn-xs" id="btnSetRowStateCreateAndDeleted">setRowState(6, 'createAndDeleted')</button> 버튼을 클릭하면 7 행의 RowState를 'createAndDeleted'로 변경합니다. (onRowStateChanged 호출) 9. 'created' 상태인 2행을 선택 후 `Ctrl`+`Del`key를 입력하여 행을 삭제합니다. RowState를 'createAndDeleted'로 변경되는 것을 확인하세요. (onRowStateChanged 호출, 3번에서는 호출되지 않았던 onRowStateChanged가 'created' 상태에서 변경되었기 때문에 이번에는 호출됩니다.) 10. <button type="button" class="btn btn-primary btn-xs" id="btnSetRowStatesT">setRowStates([8, 9], 'updated', true, true)</button> 버튼을 클릭하면 9, 10행의 상태를 'updated'로 변경합니다. (마지막 파라메터인 rowEvent가 true 일 경우 화면이 갱신되지 않는 버그가 있습니다. 스크롤 바를 움직이면 rowState가 정상적으로 표시됩니다., onRowStateChanged 호출되어야 하나 버그로 인해 호출되지 않습니다.) 11. <button type="button" class="btn btn-primary btn-xs" id="btnSetRowStatesF">setRowStates([10, 11], 'updated', true, false)</button> 버튼을 클릭하면 11, 12행의 상태를 'updated'로 변경합니다. (onRowStatesChanged 호출) 12. <button type="button" class="btn btn-primary btn-xs" id="btnGetRowState">getRowState(9)</button> 버튼을 클릭하면 10행의 상태를 가져옵니다. 13. <button type="button" class="btn btn-primary btn-xs" id="btnGetStateRows">getStateRows('deleted')</button> 버튼을 클릭하면 'deleted'상태인 행의 dataRow 목록을 가져옵니다. 14. <button type="button" class="btn btn-primary btn-xs" id="btnGetAllStateRows">getAllStateRows()</button> 버튼을 클릭하면 각 RowState 상태에 해당하는 dataRow들을 가져옵니다. 15. <button type="button" class="btn btn-primary btn-xs" id="btnClearRowStatesF">clearRowStates(false, false)</button> 버튼을 클릭하면 행 상태가 사라집니다. (onRowStatesCleared 호출, 첫번째 파라메터인 `deleteRows`가 false 이기 때문에 행 상태가 'deleted', 'createAndDeleted'인 행들이 삭제 되지 않고 RowState만 지워졌음을 확인하세요) 16. 몇 개의 행을 `Ctrl`+`Del`key를 입력하여 행들을 'deleted' 상태로 만들고, 몇 개의 행은 값을 수정하여 'updated' 상태로 만들어보세요. 17. <button type="button" class="btn btn-primary btn-xs" id="btnClearRowStatesT">clearRowStates(true, true)</button> 버튼을 클릭하면 행 상태가 사라집니다. ('deleted'였던 행들은 사라지고, 수정한 행 수 만큼 onRowStateChanged 호출) <div id="realgrid" style="width: 100%; height: 250px;"></div>
데모 사이트
API 참조
- DataProviderOptions
- DataProvider.setRowState(row, state, force)
- DataProvider.setRowStates(rows, state, force, rowEvents)
- DataProvider.getRowState(row)
- DataProvider.getRowStateCount(rowStates)
- DataProvider.getStateRows(rowState)
- DataProvider.getAllStateRows()
- DataProvider.clearRowStates(deleteRows, rowEvents)
- LocalDataProvider.onRowStateChanged()
- LocalDataProvider.onRowStatesChanged()
- LocalDataProvider.onRowStatesCleared()