easyui-datagrid编辑模式详解
⼀,建⽴编辑器
从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,就可以这样调⽤ inputbobox(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.ssage = '结束⽇期必须⼤于开始⽇期';
30            return CurDate > startDate;
31        },
editorjs
32        message: ''
33    },
34 });
有了以上两点基本知识,这三个需求处理起来就很顺利了。第⼀个需求,根据不同的数据渲染不同的界
⾯。在此我看到了 onBeforeEdit 根据字⾯意思就是在开始编辑之前,官⽅解释,⽤户在开始编辑⼀⾏数据时触发。也就是说,在这个事件激发之前,datagrid根本还没有建⽴或初始编辑器控件,⽽我们⼜知道datagrid 编辑是通过列属性中editor中options渲染控件的,那在这⾥改变options的值不就好了么,于是在onBeforeEdit我敲上了⼀下js代码:
1 var zSelected = dtnz.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和edatec
ompare,我们知道需要传⼊⼀个被⽐较⽇期控件的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"] = FullYear();
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也明⽩是在什么时候调⽤的,可以做哪些事,还等待合适的需求⼜来在讲解!