一,建立編輯器
從api得知,擴展一種新的編輯器類型,需要提供以上幾個方法。項目中正好需要一個checkbox 類型編輯器,但在easyui中並沒提供這樣的編輯器,那我們可以通過擴展編輯器來解決,擴展如下
1 $.extend($.fn.datagrid.defaults.editors, { 2 checkbox: {//調用名稱 3 init: function (container, options) { 4 //container 用於裝載編輯器 options,提供編輯器初始參數 5 var input = $('<input type="checkbox" class="datagrid-editable-input">').appendTo(container); 6 //這里我把一個 checkbox類型的輸入控件添加到容器container中 7 // 需要渲染成easyu提供的控件,需要時用傳入options,我這里如果需要一個combobox,就可以 這樣調用 input.combobox(options); 8 return input; 9 }, 10 getValue: function (target) { 11 //datagrid 結束編輯模式,通過該方法返回編輯最終值 12 //這里如果用戶勾選中checkbox返回1否則返回0 13 return $(target).prop("checked") ? 1 : 0; 14 }, 15 setValue: function (target, value) { 16 //datagrid 進入編輯器模式,通過該方法為編輯賦值 17 //我傳入value 為0或者1,若用戶傳入1則勾選編輯器 18 if (value) 19 $(target).prop("checked", "checked") 20 }, 21 resize: function (target, width) { 22 //列寬改變后調整編輯器寬度 23 var input = $(target); 24 if ($.boxModel == true) { 25 input.width(width - (input.outerWidth() - input.width())); 26 } else { 27 input.width(width); 28 } 29 } 30 } 31 });
新的編輯擴展好以后,跟系統默認的編輯器使用方式一樣:
二 , 獲取編輯器
datagrid 通過調用 beginEdit 傳入要開始編輯行的對應的索引,該行進入編輯模式。通過 endEdit 或者 cancleEdit結束編輯模式,endEdit會提交一個數據變更記錄,cancleEdit會還原為初始數據。
getEditors以及getEditor 返回指定行當前編輯器,getEditor 底層調用getEditors 方法。getEditors 返回一個編輯器對象數組。
三,編輯器事件
一個項目中存在這樣三個需求
1,根據不同的操作結果,渲染不同編輯控件的操作模式,如以下圖所示,用戶選擇小組1,日期控制范圍必須到天,右側日期控件提供按天選擇展示。用戶選擇小組6,日期控制范圍到月就可以了,右側日期控件提供按月選擇展示。
2,列表中存在開始日期,和結束日期必須控制開始日期不能大於結束日期或者結束日期不能大於開始日期
3,根據用戶選擇的開始日期,提取對應的年份。
針對這兩個需求,該怎么實現呢?
先來了解下datagrid在編輯模式提供哪些可用事件,以及如何擴展一個新數據驗證規則
API中提供事件:
擴展數據驗證規則:
1 $.extend($.fn.validatebox.defaults.rules, { 2 //驗證開始日期只能小於結束日期 3 sdatecompare: { 4 validator: function (value, param) { 5 var end = param[0]; 6 if (typeof end == 'string') { 7 end = $(param[0]);//結束日期 selector 8 } 9 if (!end.datebox("getValue")) { 10 return true; 11 } 12 var endDate = new Date(end.datebox("getValue")); 13 var CurDate = new Date(value); 14 return CurDate < endDate; 15 }, 16 message: '開始日期必須小於結束日期' 17 }, 18 edatecompare: { 19 validator: function (value, param) { 20 var start = param[0]; 21 if (typeof start == 'string') { 22 start = $(param[0]); //開始日期 selector 23 } 24 if (!start.datebox("getValue") || !value) { 25 return true; 26 } 27 var startDate = new Date(start.datebox("getValue")); 28 var CurDate = new Date(value); 29 $.fn.validatebox.defaults.rules.edatecompare.message = '結束日期必須大於開始日期'; 30 return CurDate > startDate; 31 }, 32 message: '' 33 }, 34 });
有了以上兩點基本知識,這三個需求處理起來就很順利了。第一個需求,根據不同的數據渲染不同的界面。在此我看到了 onBeforeEdit 根據字面意思就是在開始編輯之前,官方解釋,用戶在開始編輯一行數據時觸發。也就是說,在這個事件激發之前,datagrid根本還沒有建立或初始編輯器控件,而我們又知道datagrid 編輯是通過列屬性中editor中options渲染控件的,那在這里改變options的值不就好了么,於是在onBeforeEdit我敲上了一下js代碼:
1 var zSelected = fazgl.grdtnz.datagrid("getSelected"); 2 var ksOpts = $(this).datagrid("getColumnOption", "F_KSRQ"); 3 var jsOpts = $(this).datagrid("getColumnOption", "F_JSRQ"); 4 var rendmodes = ["year", 'month'];//easyui calendar 中擴展一個mode屬性,用於顯示選擇到月或者到天 5 $.extend(ksOpts.editor.options, { mode: rendmodes[zSelected.F_SFFT] }); 6 $.extend(jsOpts.editor.options, { mode: rendmodes[zSelected.F_SFFT] });
通過驗證這個思路完全正確,合理處理了根據不同數據展現不同界面的需求。第一個需求到此結束,現在聚焦到第二個需求,開始日期必須小於結束日期,從上面擴展的數據驗證規則sdatecompare和edatecompare,我們知道需要傳入一個被比較日期控件的selector。那該怎么實現呢?在回看一下 API,其中有onBeginEdit 這么一個事件,通過查閱源碼,了解到datagrid在激發該事件時已經對應的編輯控件已經創建完畢,那通過datagrid 提供方法 getEditors或者getEditor得到編輯器,其中的target不就是需要的selector么! 於是乎,我在onBeginEdit 中敲下了如下代碼:
1 var editors = $(this).datagrid("getEditors", index); 2 var ed_Ksrq = editors[0];//開始日期編輯器 3 var ed_Jsrq = editors[1];//結束日期編輯器 4 //easyui 日期控件從 textbox擴展,所有需要得到對應textbox的options才能加入驗證規則 5 var ksopts = $(ed_Ksrq.target).datebox("textbox").validatebox("options"); 6 ksopts.validType = ksopts.validType || {};//如果編輯器最初設置,對應編輯器validType為null,這里做下為空判斷 7 $.extend(ksopts.validType, { sdatecompare: [ed_Jsrq.target] }); 8 var jsopts = $(ed_Jsrq.target).datebox("textbox").validatebox("options"); 9 jsopts.validType = jsopts.validType || {}; 10 $.extend(jsopts.validType, { edatecompare: [ed_Ksrq.target] });
經過測試,思路完全正確,成功實現動態加入驗證規則。有了以上經驗,對於第三個需求,感覺已經沒有什么難度了,datagrid提供 onEndEdit(銷毀編輯器前) ,onAfterEdit(銷毀編輯器后),都會返回 一個changes 對象,里邊保存了變更的數據,於是我在onEndEdit 寫下了如下代碼:
1 var nrow = {}; 2 3 //判斷是否有更改開始日期 4 5 if (changes["F_KSRQ"]) { 6 7 var kAry = changes.F_KSRQ.split("-"); 8 9 var date = new Date(parseInt(kAry[0]), parseInt(kAry[1]) - 1); 10 11 nrow["F_NIAN"] = date.getFullYear(); 12 13 nrow["F_KSY"] = kAry[1]; 14 15 nrow.F_KSRQ = row.F_KSRQ + "-" + "01"; 16 17 } 18 19 //更新數據 20 21 $(this).datagrid("updateRow", { 22 23 index: index, 24 25 row: nrow 26 27 }); 28 29 nrow = null;
這樣就 onCancelEdit 這個事件沒有講解了,不過根據api也明白是在什么時候調用的,可以做哪些事,還等待合適的需求又來在講解!