jqueryeasyui-datagrid-扩展-支持单元格编辑

来源:互联网 发布:tv360网络电视 编辑:程序博客网 时间:2024/06/05 03:37

jqueryeasyui-datagrid 很强大,可是在包含 三五十个列的时候,datagrid 行编辑器加载就忍无可忍了(这里用的 IE 浏览器,其他的浏览器稍微好些)

因为写了一个日期&时间的编辑器的扩展,发现加载纯 text 框很快,但是加载内置编辑器就会稍有延迟,所以扩展的用了延时调用( window.setTimeout )。

但是,内置的其它编辑器(text,textarea,checkbox,numberbox,validatebox,datebox,combobox,combotree)都有问题!

所以考虑了下,如果编辑时只加载一个单元格的一定会好点儿,结果~~~ 果然不错效果很好!

先上效果图:


其中 gridEditCellHelper   里面用到的方法都是来自 easyui1.3.3-jquery.datagrid.js 中的代码。

用过的也知道这里面的代码被混淆过了,不过我自己手动把用到的代码反向过来了,如果有错误大家可以自己把响应

代码 copy 一份从 jquery.datagrid.js 中。

这里指做抛砖引玉了 ~~~~

-----------------------------------------

gridEditCellHelper 对象为编辑所需的所有代码

//131012-datagrid 单元格编辑扩展

131018-更新

var gridEditCellHelper = {
  traget:null,
  //editIndex:0,
  //开始单元格编辑
  beginCellEdit: function (_traget, _index, _fieldName) {
    gridEditCellHelper.traget = _traget;
    //gridEditCellHelper.editIndex = _index;
    var opts = $.data(_traget, "datagrid").options;
    var tr = opts.finder.getTr(_traget, _index);
    var row = opts.finder.getRow(_traget, _index);
    gridEditCellHelper.endCellEdit(_traget, _index, false);//结束编辑单元格
    if (!tr.hasClass("datagrid-row-editing")) {
      tr.addClass("datagrid-row-editing");
    }
    if (opts.onBeforeEdit.call(_traget, _index, row) == false) {
      return;
    }//alert('begin')
    gridEditCellHelper.bindCellEditEvent(_traget, _index,true);//点击空白结束编辑
    gridEditCellHelper._initCellEditor(_traget, _index, _fieldName);//初始化编辑器
    gridEditCellHelper._resizeEditors(_traget);//调整编辑器大小
    tr.find("div.datagrid-editable").each(function () {
      var _field = $(this).parent().attr("field");
      if (_field != _fieldName) return true;
      var ed = $.data(this, "datagrid.editor");
      ed.actions.setValue(ed.target, row[_field]);//编辑器赋值
    });
    gridEditCellHelper.validateEditingRow(_traget, _index); //编辑行输入值验证
  },
  //点击空白区域结束grid编辑(_isBind:true=注册事件,false=卸载事件)
  bindCellEditEvent: function(_target,_index,_isBind) {
    if (_isBind) {
      $(document).on("click.datagrid", function(e) { //点击datagrid空白区域,结束编辑
        if (_index >= 0) {
          $(document).off("click.datagrid");
          $(_target).datagrid('endCellEditExt', _index); //结束编辑单元格
        }
      });
    } else {
      $(document).off("click.datagrid");
    }
  },
  //结束单元格编辑
  endCellEdit:function(_traget, _index, _isCancelEdit) {//this, _index, false
    var opts = $.data(_traget, "datagrid").options;
    var _updatedRows = $.data(_traget, "datagrid").updatedRows;
    var _insertedRows = $.data(_traget, "datagrid").insertedRows;
    var tr = opts.finder.getTr(_traget, _index);
    var row = opts.finder.getRow(_traget, _index);
    gridEditCellHelper.bindCellEditEvent(_traget, _index,false);//移除事件
    if (!tr.hasClass("datagrid-row-editing")) {
      return;
    }//alert('end')
    var idField = opts.idField;//主键
    var idValue = row[idField];//主键值
    //非取消编辑,更新数据(需要:行的主键字段)
    if (!_isCancelEdit) {
      if (!gridEditCellHelper.validateEditingRow(_traget, _index)) {
        return;
      }
      var _isUpdate = false;
      var _changes = {};
      var _field;
      tr.find("div.datagrid-editable").each(function () {
        _field = $(this).parent().attr("field");
        var ed = $.data(this, "datagrid.editor");
        var _value = ed.actions.getValue(ed.target);
        if (row[_field] != _value) {
          row[_field] = _value;
          _isUpdate = true;
          _changes[idField] = idValue;//记录主键字段及值
          _changes[_field] = _value;//记录修改字段及值
          return false;
        }
      });
      if (_isUpdate && idValue) {
        //使用 idField 、idValue 找到 updaterow
        var updateRow = null;
        for(var i=0;i<_updatedRows.length;i++) {
          var item = _updatedRows[i];
          if (item[idField] == idValue) {
            updateRow = item;
            break;
          }
        }
        if (updateRow==null) {
          _updatedRows.push(_changes);
        } else {
          updateRow[_field] = _changes[_field];//修改或更新
        }
        //miniTip(JsGlobals.jsonStr(_updatedRows))
      }
    }
    tr.removeClass("datagrid-row-editing");
    gridEditCellHelper._rowEditDestroy(_traget, _index);
    $(_traget).datagrid("refreshRow", _index);
    if (!_isCancelEdit) {
      opts.onAfterEdit.call(_traget, _index, row, _changes);
    } else {
      opts.onCancelEdit.call(_traget, _index, row);
    }
  },
  //验证编行
  validateEditingRow:function(_traget, _index) {//_traget, _index
    var tr = $.data(_traget, "datagrid").options.finder.getTr(_traget, _index);
    if (!tr.hasClass("datagrid-row-editing")) {
      return true;
    }
    var vbox = tr.find(".validatebox-text");
    vbox.validatebox("validate");
    vbox.trigger("mouseleave");
    var _vInvalid = tr.find(".validatebox-invalid");
    return _vInvalid.length == 0;
  },
  //初始化单元格编辑器
  _initCellEditor: function (_traget, _index, _fieldName) {
    var opts = $.data(_traget, "datagrid").options;
    var tr = opts.finder.getTr(_traget, _index);
    tr.children("td").each(function () {
      var cell = $(this).find("div.datagrid-cell");
      var _field = $(this).attr("field");
      if (_field != _fieldName) return true;
      var col = gridEditCellHelper._findField(_traget, _field);
      if (col && col.editor) {
        var _editorType, _editorOpts;
        if (typeof col.editor == "string") {
          _editorType = col.editor;
        } else {
          _editorType = col.editor.type;
          _editorOpts = col.editor.options;
        }
        var _editor = opts.editors[_editorType];
        if (_editor) {
          var _html = cell.html();
          var _width = cell.outerWidth();
          cell.addClass("datagrid-editable");
          cell.outerWidth(_width);
          cell.html("<table border=\"0\" cellspacing=\"0\" cellpadding=\"1\"><tr><td></td></tr></table>");
          cell.children("table").bind("click dblclick contextmenu", function (e) {
            e.stopPropagation();
          });
          $.data(cell[0], "datagrid.editor", { actions: _editor, target: _editor.init(cell.find("td"), _editorOpts), field: _field, type: _editorType, oldHtml: _html });
          window.setTimeout(function () {
            cell.children("table").find("input").select();
      }, 100);
        }
      }
    });
    gridEditCellHelper._setRowHeight(_traget, _index, true);//设置行高度
  },
  //查找字段
  _findField:function(_traget, _field) {
    function _getCol(_columns) {
      if (_columns) {
        for (var i = 0; i < _columns.length; i++) {
          var cc = _columns[i];
          for (var j = 0; j < cc.length; j++) {
            var c = cc[j];
            if (c.field == _field) {
              return c;
            }
          }
        }
      }
      return null;
    };
    var _opts = $.data(_traget, "datagrid").options;
    var col = _getCol(_opts.columns);
    if (!col) {
      col = _getCol(_opts.frozenColumns);
    }
    return col;
  },
  //调整编辑器大小
  _resizeEditors:function (_traget) {
    var dc = $.data(_traget, "datagrid").dc;
    dc.view.find("div.datagrid-editable").each(function () {
      var _ad = $(this);
      var _field = _ad.parent().attr("field");
      var colOpts = $(_traget).datagrid("getColumnOption", _field);
      _ad.outerWidth(colOpts.width);
      var ed = $.data(this, "datagrid.editor");
      if (ed.actions.resize) {
        ed.actions.resize(ed.target, _ad.width());
      }
    });
  },
  //调整行高
  _setRowHeight:function(_traget, _index, _isSet) {//_traget, _index, true
    var _rows = $.data(_traget, "datagrid").data.rows;
    var _opts = $.data(_traget, "datagrid").options;
    var dc = $.data(_traget, "datagrid").dc;
    if (!dc.body1.is(":empty") && (!_opts.nowrap || _opts.autoRowHeight || _isSet)) {
      if (_index != undefined) {
        var tr1 = _opts.finder.getTr(_traget, _index, "body", 1);
        var tr2 = _opts.finder.getTr(_traget, _index, "body", 2);
        _setTrHeight(tr1, tr2);
      } else {
        var tr1 = _opts.finder.getTr(_traget, 0, "allbody", 1);
        var tr2 = _opts.finder.getTr(_traget, 0, "allbody", 2);
        _setTrHeight(tr1, tr2);
        if (_opts.showFooter) {
          var tr1 = _opts.finder.getTr(_traget, 0, "allfooter", 1);
          var tr2 = _opts.finder.getTr(_traget, 0, "allfooter", 2);
          _setTrHeight(tr1, tr2);
        }
      }
    }
    _resizeView(_traget);
    if (_opts.height == "auto") {
      var _body1Parent = dc.body1.parent();
      var _body2 = dc.body2;
      var _bodySize = _getBodySize(_body2);
      var _bodyHeight = _bodySize.height;
      if (_bodySize.width > _body2.width()) {
        _bodyHeight += 18;
      }
      _body1Parent.height(_bodyHeight);
      _body2.height(_bodyHeight);
      dc.view.height(dc.view2.height());
    }
    dc.body2.triggerHandler("scroll");
    function _setTrHeight(_tr1, _tr2) {//tr1, tr2
      for (var i = 0; i < _tr2.length; i++) {
        var tr1 = $(_tr1[i]);
        var tr2 = $(_tr2[i]);
        tr1.css("height", "");
        tr2.css("height", "");
        var _maxHeight = Math.max(tr1.height(), tr2.height());
        tr1.css("height", _maxHeight);
        tr2.css("height", _maxHeight);
      }
    };
    function _getBodySize(cc) {
      var _3d = 0;
      var _3e = 0;
      $(cc).children().each(function () {
        var c = $(this);
        if (c.is(":visible")) {
          _3e += c.outerHeight();
          if (_3d < c.outerWidth()) {
            _3d = c.outerWidth();
          }
        }
      });
      return { width: _3d, height: _3e };
    };
    function _resizeView(_traget) {
      var _opts = $.data(_traget, "datagrid").options;
      var dc = $.data(_traget, "datagrid").dc;
      var _panel = $.data(_traget, "datagrid").panel;
      var _width = _panel.width();
      var _height = _panel.height();
      var _view = dc.view;
      var _view1 = dc.view1;
      var _view2 = dc.view2;
      var _header1 = _view1.children("div.datagrid-header");
      var _header2 = _view2.children("div.datagrid-header");
      var _table1 = _header1.find("table");
      var _table2 = _header2.find("table");
      _view.width(_width);
      var _2b = _header1.children("div.datagrid-header-inner").show();
      _view1.width(_2b.find("table").width());
      if (!_opts.showHeader) {
        _2b.hide();
      }
      _view2.width(_width - _view1.outerWidth());
      _view1.children("div.datagrid-header,div.datagrid-body,div.datagrid-footer").width(_view1.width());
      _view2.children("div.datagrid-header,div.datagrid-body,div.datagrid-footer").width(_view2.width());
      var hh;
      _header1.css("height", "");
      _header2.css("height", "");
      _table1.css("height", "");
      _table2.css("height", "");
      hh = Math.max(_table1.height(), _table2.height());
      _table1.height(hh);
      _table2.height(hh);
      _header1.add(_header2).outerHeight(hh);
      if (_opts.height != "auto") {
        var _2c = _height - _view2.children("div.datagrid-header").outerHeight() - _view2.children("div.datagrid-footer").outerHeight() - _panel.children("div.datagrid-toolbar").outerHeight();
        _panel.children("div.datagrid-pager").each(function () {
          _2c -= $(this).outerHeight();
        });
        dc.body1.add(dc.body2).children("table.datagrid-btable-frozen").css({ position: "absolute", top: dc.header2.outerHeight() });
        var _2d = dc.body2.children("table.datagrid-btable-frozen").outerHeight();
        _view1.add(_view2).children("div.datagrid-body").css({ marginTop: _2d, height: (_2c - _2d) });
      }
      _view.height(_view2.height());
    }
  },
  //销毁单元格编辑器
  _rowEditDestroy:function(_traget, _index) {//_traget, _index
    var opts = $.data(_traget, "datagrid").options;
    var tr = opts.finder.getTr(_traget, _index);
    tr.children("td").each(function () {
      var cell = $(this).find("div.datagrid-editable");
      if (cell.length) {
        var ed = $.data(cell[0], "datagrid.editor");
        if (ed.actions.destroy) {
          ed.actions.destroy(ed.target);
        }
        cell.html(ed.oldHtml);
        $.removeData(cell[0], "datagrid.editor");
        cell.removeClass("datagrid-editable");
        cell.css("width", "");
      }
    });
  },
};

--------------------------------------