ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

EasyUI DataGrid 自定义编辑器类

2026/8/19 11:11:51 拓冰建站 浏览量
EasyUI DataGrid 自定义编辑器类 /********************************************************************* * EasyUI DataGrid 编辑器类ES6版本 * 封装新增、修改、删除三个核心功能 *********************************************************************/ class DataGridEditor{ /** * 构造器初始化 * param {string} selector - 数据表ID选择器如 #dg */ constructor(selector){ this.selector selector; this.$grid $(selector); this.editIndex undefined; // 当前编辑行索引 this.isAdding false; //控制只能新增一行 } /** * 新增在首行插入编辑行 */ add(){ if (this.isAdding) { $.messager.popover({msg:存在未保存的新增记录请先保存或删除,type:error}); return; } // 如果已有编辑行先结束编辑 if (!this._endEditing()) return; // 在首行index0插入空行 this.$grid.datagrid(insertRow, { index: 0, row: {} }); // 开启首行编辑 this.editIndex 0; this.isAdding true; this.$grid.datagrid(beginEdit, 0); this.$grid.datagrid(selectRow, 0); // 聚焦第一个编辑框 this._focusFirstEditor(0); } /** * 修改选中行后进入编辑状态 */ edit(){ // 如果已有编辑行先结束编辑 if (!this._endEditing()) return; var row this.$grid.datagrid(getSelected); if (!row) { $.messager.popover({msg:请先选择一条记录,type:info}); return; } var index this.$grid.datagrid(getRowIndex, row); this.editIndex index; this.$grid.datagrid(beginEdit, index); this.$grid.datagrid(selectRow, index); // 聚焦第一个编辑框 this._focusFirstEditor(index); } /** * 删除选中行后确认删除返回回调函数 */ remove(callback){ // 如果正在编辑先取消编辑 if (this.editIndex ! undefined) { this.$grid.datagrid(cancelEdit, this.editIndex); this.editIndex undefined; } var row this.$grid.datagrid(getSelected); if (!row) { $.messager.popover({msg:请先选择一条记录,type:info}); return ; } var index this.$grid.datagrid(getRowIndex, row); var self this; //使用闭包变量防止this混乱 // 弹出确认框 $.messager.confirm(确认, 确定要删除该记录吗, function (r) { if (!r) return; // 此时不deleteRow只记录待删除的行信息 var pendingRow self.$grid.datagrid(getRows)[index]; // 定义后台成功后的处理函数 var onBackendSuccess function(){ // 重新获取当前索引防止用户在等待期间操作了表格导致索引偏移 var currentIndex self.$grid.datagrid(getRowIndex, pendingRow); if (currentIndex 0) { self.$grid.datagrid(deleteRow, currentIndex); } self.editIndex undefined; self.isAdding false; }; // 定义后台失败后的处理函数可选 var onBackendFail function(errMsg){ return; }; // 回调将控制权交给调用方由调用方决定何时调后台 if (typeof callback function) { callback(pendingRow, onBackendSuccess, onBackendFail); } }); } /** * 完成当前编辑 */ complete(){ if (this.editIndex undefined) return false; // 结束编辑并验证 if (this.$grid.datagrid(validateRow, this.editIndex)) { this.$grid.datagrid(endEdit, this.editIndex); this.editIndex undefined; this.isAdding false; return true; } return false; } /** * 取消当前编辑 */ cancel() { if (this.editIndex ! undefined) { this.$grid.datagrid(cancelEdit, this.editIndex); this.editIndex undefined; this.isAdding false; } } //------------------------ 私有方法 ------------------------ /** * 结束当前编辑内部方法 * returns {boolean} 是否成功结束 */ _endEditing(){ if (this.editIndex undefined) return true; if (this.$grid.datagrid(validateRow, this.editIndex)) { this.$grid.datagrid(endEdit, this.editIndex); this.editIndex undefined; return true; } else { $.messager.popover({msg:请完成当前行的编辑,type:alert}); return false; } } /** * 聚焦编辑行的第一个可编辑输入框 * param {number} index - 行索引 */ _focusFirstEditor(index){ var self this; // 延迟到下一帧确保编辑器 DOM 已完全渲染 setTimeout(function(){ var fields self.$grid.datagrid(getColumnFields); for(var i 0; i fields.length; i){ var ed self.$grid.datagrid(getEditor, {index: index, field: fields[i]}); if(!ed) continue; var $target $(ed.target); // 优先尝试 EasyUI 控件自带的 focus 方法 // combobox / datebox / timespinner / numberbox 等都支持 var easyuiMethods [textbox, combobox, combotree, datebox, datetimebox, timespinner, numberspinner, numberbox, passwordbox]; var focused false; for(var m 0; m easyuiMethods.length; m){ if($target[easyuiMethods[m]]){ try { $target[easyuiMethods[m]](focus); focused true; } catch(e){} break; } } // 如果不是 EasyUI 控件或上面失败尝试原生 focus if(!focused){ // 查找真正的可见输入框处理复合控件的情况 var $realInput $target.is(:visible) ? $target : $target.closest(.textbox).find(.textbox-text); if($realInput.length){ $realInput.focus(); } else { // 最后兜底 $target.focus(); } } return; // 只聚焦第一个可编辑字段 } }, 50); // 50ms 足够等待 EasyUI 渲染完成 } } /********************************************************************* * EasyUI DataGrid 编辑器类ES5版本 * 封装新增、修改、删除三个核心功能 *********************************************************************/ /** * 构造器初始化 * param {string} selector - 数据表ID选择器如 #dg */ function DataGridEditor(selector) { this.selector selector; this.$grid $(selector); this.editIndex undefined; // 当前编辑行索引 this.isAdding false; // 控制只能新增一行 } //------------------------ 公有方法 (挂载到原型链) ------------------------ /** * 新增在首行插入编辑行 */ DataGridEditor.prototype.add function() { if (this.isAdding) { $.messager.popover({msg: 存在未保存的新增记录请先保存或删除, type: error}); return; } // 如果已有编辑行先结束编辑 if (!this._endEditing()) return; // 在首行index0插入空行 this.$grid.datagrid(insertRow, { index: 0, row: {} }); // 开启首行编辑 this.editIndex 0; this.isAdding true; this.$grid.datagrid(beginEdit, 0); this.$grid.datagrid(selectRow, 0); // 聚焦第一个编辑框 this._focusFirstEditor(0); }; /** * 修改选中行后进入编辑状态 */ DataGridEditor.prototype.edit function() { // 如果已有编辑行先结束编辑 if (!this._endEditing()) return; var row this.$grid.datagrid(getSelected); if (!row) { $.messager.popover({msg: 请先选择一条记录, type: info}); return; } var index this.$grid.datagrid(getRowIndex, row); this.editIndex index; this.$grid.datagrid(beginEdit, index); this.$grid.datagrid(selectRow, index); // 聚焦第一个编辑框 this._focusFirstEditor(index); }; /** * 删除选中行后确认删除返回回调函数 */ DataGridEditor.prototype.remove function(callback) { var self this; // 闭包保存this引用 // 如果正在编辑先取消编辑 if (this.editIndex ! undefined) { this.$grid.datagrid(cancelEdit, this.editIndex); this.editIndex undefined; } var row this.$grid.datagrid(getSelected); if (!row) { $.messager.popover({msg: 请先选择一条记录, type: info}); return; } var index this.$grid.datagrid(getRowIndex, row); // 弹出确认框 $.messager.confirm(确认, 确定要删除该记录吗, function(r) { if (!r) return; // 此时不deleteRow只记录待删除的行信息 var pendingRow self.$grid.datagrid(getRows)[index]; // 定义后台成功后的处理函数 var onBackendSuccess function() { // 重新获取当前索引防止用户在等待期间操作了表格导致索引偏移 var currentIndex self.$grid.datagrid(getRowIndex, pendingRow); if (currentIndex 0) { self.$grid.datagrid(deleteRow, currentIndex); } self.editIndex undefined; self.isAdding false; }; // 定义后台失败后的处理函数可选 var onBackendFail function(errMsg) { return; }; // 回调将控制权交给调用方 if (typeof callback function) { callback(pendingRow, onBackendSuccess, onBackendFail); } }); }; /** * 完成当前编辑 */ DataGridEditor.prototype.complete function() { if (this.editIndex undefined) return false; // 结束编辑并验证 if (this.$grid.datagrid(validateRow, this.editIndex)) { this.$grid.datagrid(endEdit, this.editIndex); this.editIndex undefined; this.isAdding false; return true; } return false; }; /** * 取消当前编辑 */ DataGridEditor.prototype.cancel function() { if (this.editIndex ! undefined) { this.$grid.datagrid(cancelEdit, this.editIndex); this.editIndex undefined; this.isAdding false; } }; //------------------------ 私有方法 (挂载到原型链以_开头约定) ------------------------ /** * 结束当前编辑内部方法 * returns {boolean} 是否成功结束 */ DataGridEditor.prototype._endEditing function() { if (this.editIndex undefined) return true; if (this.$grid.datagrid(validateRow, this.editIndex)) { this.$grid.datagrid(endEdit, this.editIndex); this.editIndex undefined; return true; } else { $.messager.popover({msg: 请完成当前行的编辑, type: alert}); return false; } }; /** * 聚焦编辑行的第一个可编辑输入框 * param {number} index - 行索引 */ DataGridEditor.prototype._focusFirstEditor function(index) { var self this; // 延迟到下一帧确保编辑器 DOM 已完全渲染 setTimeout(function() { var fields self.$grid.datagrid(getColumnFields); for (var i 0; i fields.length; i) { var ed self.$grid.datagrid(getEditor, {index: index, field: fields[i]}); if (!ed) continue; var $target $(ed.target); // 优先尝试 EasyUI 控件自带的 focus 方法 var easyuiMethods [textbox, combobox, combotree, datebox, datetimebox, timespinner, numberspinner, numberbox, passwordbox]; var focused false; for (var m 0; m easyuiMethods.length; m) { if ($target[easyuiMethods[m]]) { try { $target[easyuiMethods[m]](focus); focused true; } catch (e) {} break; } } // 如果不是 EasyUI 控件或上面失败尝试原生 focus if (!focused) { var $realInput $target.is(:visible) ? $target : $target.closest(.textbox).find(.textbox-text); if ($realInput.length) { $realInput.focus(); } else { $target.focus(); } } return; // 只聚焦第一个可编辑字段 } }, 50); }