[转载]Easyui1.32源码翻译--datagrid(数据表格) - Jimmy-Lee - 博客园

[转载]Easyui1.32源码翻译–datagrid(数据表格) – Jimmy-Lee – 博客园.

      此前网上有easyui1.25的源码  应该算是比较老的版本  之后又经历了1.26 、 1.3、 1.31、 1.32 、1.33、1.34  1.33开始支持css3 算是又一个转折  但是对于ie来说 1.32 个人用的比较多 赶紧更适用 源码翻译是作者利用几个夜晚时间翻译的  这个表格插件算是源码量最大的 先发布这个 之后会继续把整个easyui的插件翻译完毕:下载该插件翻译源码地址

/**
 * jQuery EasyUI 1.3.2
 * 翻译:qq:1364386878 
 *
 */
(function ($) {

    var grid_body_tr_idindex = 0;
    //获取对象下标
    function getObjectIndex(a, o) {
        for (var i = 0, _3 = a.length; i < _3; i++) {
            if (a[i] == o) {
                return i;
            }
        }
        return -1;
    };
    //根据id取消选择行
    function unSelectedRowsById(a, o, id) {
        if (typeof o == "string") {
            for (var i = 0, rows = a.length; i < rows; i++) {
                if (a[i][o] == id) {
                    a.splice(i, 1);
                    return;
                }
            }
        } else {
            var index = getObjectIndex(a, o);
            if (index != -1) {
                a.splice(index, 1);
            }
        }
    };
    //返回标识字段列
    function idFieldRows(scRows, idfield, row) {
        for (var i = 0, rlength = scRows.length; i < rlength; i++) {
            if (scRows[i][idfield] == row[idfield]) {
                return;
            }
        }
        scRows.push(row);
    };
    //做调整和布局
    function _resize(target, parm) {
        var opts = $.data(target, "datagrid").options;
        var panel = $.data(target, "datagrid").panel;
        if (parm) {
            if (parm.width) {
                opts.width = parm.width;
            }
            if (parm.height) {
                opts.height = parm.height;
            }
        }
        if (opts.fit == true) {
            var p = panel.panel("panel").parent();
            opts.width = p.width();
            opts.height = p.height();
        }
        panel.panel("resize", { width: opts.width, height: opts.height });
    };
    //适应大小
    function _fitGridSize(jq) {
        var opts = $.data(jq, "datagrid").options;
        var dc = $.data(jq, "datagrid").dc;
        var panel = $.data(jq, "datagrid").panel;
        var width = panel.width();
        var height = panel.height();
        var gridView = dc.view;
        var gridView1 = dc.view1;
        var gridView2 = dc.view2;
        var gridHeader1 = gridView1.children("div.datagrid-header");
        var gridHeader2 = gridView2.children("div.datagrid-header");
        var gridTable1 = gridHeader1.find("table");
        var gridTable2 = gridHeader2.find("table");
        gridView.width(width);
        var innerHeader = gridHeader1.children("div.datagrid-header-inner").show();
        gridView1.width(innerHeader.find("table").width());
        if (!opts.showHeader) {
            innerHeader.hide();
        }
        gridView2.width(width - gridView1._outerWidth());
        gridView1.children("div.datagrid-header,div.datagrid-body,div.datagrid-footer").width(gridView1.width());
        gridView2.children("div.datagrid-header,div.datagrid-body,div.datagrid-footer").width(gridView2.width());
        var hh;
        gridHeader1.css("height", "");
        gridHeader2.css("height", "");
        gridTable1.css("height", "");
        gridTable2.css("height", "");
        hh = Math.max(gridTable1.height(), gridTable2.height());
        gridTable1.height(hh);
        gridTable2.height(hh);
        gridHeader1.add(gridHeader2)._outerHeight(hh);
        if (opts.height != "auto") {
            var fixedHeight = height - gridView2.children("div.datagrid-header")._outerHeight() - gridView2.children("div.datagrid-footer")._outerHeight() - panel.children("div.datagrid-toolbar")._outerHeight();
            panel.children("div.datagrid-pager").each(function () {
                fixedHeight -= $(this)._outerHeight();
            });
            dc.body1.add(dc.body2).children("table.datagrid-btable-frozen").css({ position: "absolute", top: dc.header2._outerHeight() });
            var height = dc.body2.children("table.datagrid-btable-frozen")._outerHeight();
            gridView1.add(gridView2).children("div.datagrid-body").css({ marginTop: height, height: (fixedHeight - height) });
        }
        gridView.height(gridView2.height());
    };

    //固定指定列高度。如果'index'参数未配置,所有行高度都是固定的
    function _fixRowHeight(target, index, _21) {
        var rows = $.data(target, "datagrid").data.rows;
        var opts = $.data(target, "datagrid").options;
        var dc = $.data(target, "datagrid").dc;
        if (!dc.body1.is(":empty") && (!opts.nowrap || opts.autoRowHeight || _21)) {
            if (index != undefined) {
                var tr1 = opts.finder.getTr(target, index, "body", 1);
                var tr2 = opts.finder.getTr(target, index, "body", 2);
                alignRowHeight(tr1, tr2);
            } else {
                var tr1 = opts.finder.getTr(target, 0, "allbody", 1);
                var tr2 = opts.finder.getTr(target, 0, "allbody", 2);
                alignRowHeight(tr1, tr2);
                if (opts.showFooter) {
                    var tr1 = opts.finder.getTr(target, 0, "allfooter", 1);
                    var tr2 = opts.finder.getTr(target, 0, "allfooter", 2);
                    alignRowHeight(tr1, tr2);
                }
            }
        }
        _fitGridSize(target);
        if (opts.height == "auto") {
            var gridBody1 = dc.body1.parent();
            var gridBody2 = dc.body2;
            var fullHeight = 0;
            var width = 0;
            gridBody2.children().each(function () {
                var c = $(this);
                if (c.is(":visible")) {
                    fullHeight += c._outerHeight();
                    if (width < c._outerWidth()) {
                        width = c._outerWidth();
                    }
                }
            });
            if (width > gridBody2.width()) {
                fullHeight += 18;
            }
            gridBody1.height(fullHeight);
            gridBody2.height(fullHeight);
            dc.view.height(dc.view2.height());
        }
        dc.body2.triggerHandler("scroll");
        function alignRowHeight(target1, target2) {
            for (var i = 0; i < target2.length; i++) {
                var tr1 = $(target1[i]);
                var tr2 = $(target2[i]);
                tr1.css("height", "");
                tr2.css("height", "");
                var height = Math.max(tr1.height(), tr2.height());
                tr1.css("height", height);
                tr2.css("height", height);
            }
        };
    };

    //冻结指定行,当数据表格表格向下滚动的时候始终保持被冻结的行显示在顶部
    function _freezeRow(target, index) {
        var datagrid = $.data(target, "datagrid");
        var opts = datagrid.options;
        var dc = datagrid.dc;
        if (!dc.body2.children("table.datagrid-btable-frozen").length) {
            dc.body1.add(dc.body2).prepend("<table class=\"datagrid-btable datagrid-btable-frozen\" cellspacing=\"0\" cellpadding=\"0\"></table>");
        }
        getfreeze_RowCells(true);
        getfreeze_RowCells(false);
        _fitGridSize(target);
        function getfreeze_RowCells(freezeColmuns) {
            
            var step = freezeColmuns ? 1 : 2;
            var tr = opts.finder.getTr(target, index, "body", step);
            
            (freezeColmuns ? dc.body1 : dc.body2).children("table.datagrid-btable-frozen").append(tr);
        };
    };

    function wrapGrid(target, rownumber) {
        function getcolumns() {
            var frozencols = [];
            var unfrozencols = [];
            $(target).children("thead").each(function () {
                var opt = $.parser.parseOptions(this, [{ frozen: "boolean" }]);
                $(this).find("tr").each(function () {
                    var cols = [];
                    $(this).find("th").each(function () {
                        var th = $(this);
                        var col = $.extend({}, $.parser.parseOptions(this, ["field", "align", "halign", "order", { sortable: "boolean", checkbox: "boolean", resizable: "boolean" }, { rowspan: "number", colspan: "number", width: "number" }]), { title: (th.html() || undefined), hidden: (th.attr("hidden") ? true : undefined), formatter: (th.attr("formatter") ? eval(th.attr("formatter")) : undefined), styler: (th.attr("styler") ? eval(th.attr("styler")) : undefined), sorter: (th.attr("sorter") ? eval(th.attr("sorter")) : undefined) });
                        if (th.attr("editor")) {
                            var s = $.trim(th.attr("editor"));
                            if (s.substr(0, 1) == "{") {
                                col.editor = eval("(" + s + ")");
                            } else {
                                col.editor = s;
                            }
                        }
                        cols.push(col);
                    });

                    opt.frozen ? frozencols.push(cols) : unfrozencols.push(cols);
                });
            });
            return [frozencols, unfrozencols];
        };

        var gridwrap = $("<div class=\"datagrid-wrap\">" + "<div class=\"datagrid-view\">" + "<div class=\"datagrid-view1\">" + "<div class=\"datagrid-header\">" + "<div class=\"datagrid-header-inner\"></div>" + "</div>" + "<div class=\"datagrid-body\">" + "<div class=\"datagrid-body-inner\"></div>" + "</div>" + "<div class=\"datagrid-footer\">" + "<div class=\"datagrid-footer-inner\"></div>" + "</div>" + "</div>" + "<div class=\"datagrid-view2\">" + "<div class=\"datagrid-header\">" + "<div class=\"datagrid-header-inner\"></div>" + "</div>" + "<div class=\"datagrid-body\"></div>" + "<div class=\"datagrid-footer\">" + "<div class=\"datagrid-footer-inner\"></div>" + "</div>" + "</div>" + "</div>" + "</div>").insertAfter(target);
        gridwrap.panel({ doSize: false });
        gridwrap.panel("panel").addClass("datagrid").bind("_resize", function (e, param) {
            var opts = $.data(target, "datagrid").options;
            if (opts.fit == true || param) {
                _resize(target);
                setTimeout(function () {
                    if ($.data(target, "datagrid")) {
                        _fixColumnSize(target);
                    }
                }, 0);
            }
            return false;
        });
        $(target).hide().appendTo(gridwrap.children("div.datagrid-view"));
        var cc = getcolumns();
        var gridView = gridwrap.children("div.datagrid-view");
        var gridView1 = gridView.children("div.datagrid-view1");
        var gridView2 = gridView.children("div.datagrid-view2");
        return {
            panel: gridwrap,
            frozenColumns: cc[0],
            columns: cc[1],
            dc: {
                view: gridView,
                view1: gridView1,
                view2: gridView2,
                header1: gridView1.children("div.datagrid-header").children("div.datagrid-header-inner"),
                header2: gridView2.children("div.datagrid-header").children("div.datagrid-header-inner"),
                body1: gridView1.children("div.datagrid-body").children("div.datagrid-body-inner"),
                body2: gridView2.children("div.datagrid-body"),
                footer1: gridView1.children("div.datagrid-footer").children("div.datagrid-footer-inner"),
                footer2: gridView2.children("div.datagrid-footer").children("div.datagrid-footer-inner")
            }
        };
    };
    //获取表格数据
    function getGridData(jq) {
        var data = { total: 0, rows: [] };
        var fields = _getColumnFields(jq, true).concat(_getColumnFields(jq, false));

        $(jq).find("tbody tr").each(function () {
            data.total++;
            var col = {};
            for (var i = 0; i < fields.length; i++) {
                col[fields[i]] = $("td:eq(" + i + ")", this).html();
            }
            data.rows.push(col);
        });
        return data;
    };
    //初始化
    function init(jq) {
      
        var datagrid = $.data(jq, "datagrid");
        var opts = datagrid.options;
        var dc = datagrid.dc;
     
        var panel = datagrid.panel;
        panel.panel($.extend({}, opts, {
            id: null,
            doSize: false,
            onResize: function (width, height) {
                setTimeout(function () {
                    if ($.data(jq, "datagrid")) {
                        _fitGridSize(jq);
                        _fitColumns(jq);
                        opts.onResize.call(panel, width, height);
                    }
                }, 0);
            },
            onExpand: function () {
                _fixRowHeight(jq);
                opts.onExpand.call(panel);
            }
        }));
        datagrid.rowIdPrefix = "datagrid-row-r" + (++grid_body_tr_idindex);
      
        buildGridHeader(dc.header1, opts.frozenColumns, true);
        buildGridHeader(dc.header2, opts.columns, false);
        cellWidth();//设置单元格宽度
        dc.header1.add(dc.header2).css("display", opts.showHeader ? "block" : "none");
        dc.footer1.add(dc.footer2).css("display", opts.showFooter ? "block" : "none");
        if (opts.toolbar) {
            if (typeof opts.toolbar == "string") {
                $(opts.toolbar).addClass("datagrid-toolbar").prependTo(panel);
                $(opts.toolbar).show();
            } else {
                $("div.datagrid-toolbar", panel).remove();
                var tb = $("<div class=\"datagrid-toolbar\"><table cellspacing=\"0\" cellpadding=\"0\"><tr></tr></table></div>").prependTo(panel);
                var tr = tb.find("tr");
                for (var i = 0; i < opts.toolbar.length; i++) {
                    var btn = opts.toolbar[i];
                    if (btn == "-") {
                        $("<td><div class=\"datagrid-btn-separator\"></div></td>").appendTo(tr);
                    } else {
                        var td = $("<td></td>").appendTo(tr);
                        var tool = $("<a href=\"javascript:void(0)\"></a>").appendTo(td);
                        tool[0].onclick = eval(btn.handler || function () {
                        });
                        tool.linkbutton($.extend({}, btn, { plain: true }));
                    }
                }
            }
        } else {
            $("div.datagrid-toolbar", panel).remove();
        }
        $("div.datagrid-pager", panel).remove();
        if (opts.pagination) {
            var pager = $("<div class=\"datagrid-pager\"></div>");
            if (opts.pagePosition == "bottom") {
                pager.appendTo(panel);
            } else {
                if (opts.pagePosition == "top") {
                    pager.addClass("datagrid-pager-top").prependTo(panel);
                } else {
                    var pagertop = $("<div class=\"datagrid-pager datagrid-pager-top\"></div>").prependTo(panel);
                    pager.appendTo(panel);
                    pager = pager.add(pagertop);
                }
            }
            //分页
            pager.pagination({
                total: 0,
                pageNumber: opts.pageNumber,
                pageSize: opts.pageSize,
                pageList: opts.pageList,
                onSelectPage: function (pageNumber, pageSize) {
                    opts.pageNumber = pageNumber;
                    opts.pageSize = pageSize;
                    pager.pagination("refresh", { pageNumber: pageNumber, pageSize: pageSize });
                    _load(jq);
                }
            });
            opts.pageSize = pager.pagination("options").pageSize;
        }
        function buildGridHeader(headerDiv, clomuns, frozen) {
           
            if (!clomuns) {
                return;
            }
            $(headerDiv).show();
            $(headerDiv).empty();
            var t = $("<table class=\"datagrid-htable\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tbody></tbody></table>").appendTo(headerDiv);
            for (var i = 0; i < clomuns.length; i++) {
                var tr = $("<tr class=\"datagrid-header-row\"></tr>").appendTo($("tbody", t));
                var column = clomuns[i];
                for (var j = 0; j < column.length; j++) {
                    var col = column[j];
                    var tdHTML = "";
                    if (col.rowspan) {
                        tdHTML += "rowspan=\"" + col.rowspan + "\" ";
                    }
                    if (col.colspan) {
                        tdHTML += "colspan=\"" + col.colspan + "\" ";
                    }
                    var td = $("<td " + tdHTML + "></td>").appendTo(tr);
                    if (col.checkbox) {
                        td.attr("field", col.field);
                        $("<div class=\"datagrid-header-check\"></div>").html("<input type=\"checkbox\"/>").appendTo(td);
                    } else {
                        if (col.field) {
                            td.attr("field", col.field);
                            td.append("<div class=\"datagrid-cell\"><span></span><span class=\"datagrid-sort-icon\"></span></div>");
                            $("span", td).html(col.title);
                            $("span.datagrid-sort-icon", td).html("&nbsp;");
                            var cell = td.find("div.datagrid-cell");
                            if (col.resizable == false) {
                                cell.attr("resizable", "false");
                            }
                            if (col.width) {
                                cell._outerWidth(col.width);
                                col.boxWidth = parseInt(cell[0].style.width);
                            } else {
                                col.auto = true;
                            }
                            cell.css("text-align", (col.halign || col.align || ""));
                            col.cellClass = "datagrid-cell-c" + grid_body_tr_idindex + "-" + col.field.replace(/\./g, "-");
                            col.cellSelector = "div." + col.cellClass;
                        } else {
                            $("<div class=\"datagrid-cell-group\"></div>").html(col.title).appendTo(td);
                        }
                    }
                    if (col.hidden) {
                        td.hide();
                    }
                }
            }
            if (frozen && opts.rownumbers) {
                var td = $("<td rowspan=\"" + opts.frozenColumns.length + "\"><div class=\"datagrid-header-rownumber\"></div></td>");
                if ($("tr", t).length == 0) {
                    td.wrap("<tr class=\"datagrid-header-row\"></tr>").parent().appendTo($("tbody", t));
                } else {
                    td.prependTo($("tr:first", t));
                }
            }
        };
        //设置单元格宽度
        function cellWidth() {
            var ss = ["<style type=\"text/css\">"];
            var clomuns = _getColumnFields(jq, true).concat(_getColumnFields(jq));
            for (var i = 0; i < clomuns.length; i++) {
                var col = _getColumnOption(jq, clomuns[i]);
                if (col && !col.checkbox) {
                    ss.push(col.cellSelector + " {width:" + col.boxWidth + "px;}");
                }
            }
            ss.push("</style>");
            $(ss.join("\n")).prependTo(dc.view);
        };
    };
    //绑定事件
    function bingEvent(jq) {
        var datagrid = $.data(jq, "datagrid");
        var panel = datagrid.panel;
        var opts = datagrid.options;
        var dc = datagrid.dc;
        var headinner = dc.header1.add(dc.header2);
        //点击checkbox事件
        headinner.find("input[type=checkbox]").unbind(".datagrid").bind("click.datagrid", function (e) {
           
            if (opts.singleSelect && opts.selectOnCheck) {
                return false;
            }
            if ($(this).is(":checked")) {
                _checkAll(jq);
            } else {
                _clearChecked(jq);
            }
            e.stopPropagation();
        });
        var gridcell = headinner.find("div.datagrid-cell");
       //鼠标进入标题单元格事件
        gridcell.closest("td").unbind(".datagrid").bind("mouseenter.datagrid", function () {         
            if (datagrid.resizing) {
                return;
            }
            $(this).addClass("datagrid-header-over");
        }).bind("mouseleave.datagrid", function () { //鼠标离开标题事件
            $(this).removeClass("datagrid-header-over");
        }).bind("contextmenu.datagrid", function (e) {//鼠标右键标题事件
        
            var field = $(this).attr("field");
            opts.onHeaderContextMenu.call(jq, e, field);
        });
        //点击titl事件
        gridcell.unbind(".datagrid").bind("click.datagrid", function (e) {
          
            var p1 = $(this).offset().left + 5;
            var p2 = $(this).offset().left + $(this)._outerWidth() - 5;
            if (e.pageX < p2 && e.pageX > p1) {
                var field = $(this).parent().attr("field");
                var col = _getColumnOption(jq, field);////返回指定列属性
                if (!col.sortable || datagrid.resizing) {
                    return;
                }
                opts.sortName = field;
                opts.sortOrder = col.order || "asc";
                var cls = "datagrid-sort-" + opts.sortOrder;
                if ($(this).hasClass("datagrid-sort-asc")) {
                    cls = "datagrid-sort-desc";
                    opts.sortOrder = "desc";
                } else {
                    if ($(this).hasClass("datagrid-sort-desc")) {
                        cls = "datagrid-sort-asc";
                        opts.sortOrder = "asc";
                    }
                }
                gridcell.removeClass("datagrid-sort-asc datagrid-sort-desc");
                $(this).addClass(cls);
                if (opts.remoteSort) {
                    _load(jq);
                } else {
                    var data = $.data(jq, "datagrid").data;
                    _removeData(jq, data);
                }
                opts.onSortColumn.call(jq, opts.sortName, opts.sortOrder);
            }
        }).bind("dblclick.datagrid", function (e) {//双击事件
            var p1 = $(this).offset().left + 5;
            var p2 = $(this).offset().left + $(this)._outerWidth() - 5;
            var resizeHandle = opts.resizeHandle == "right" ? (e.pageX > p2) : (opts.resizeHandle == "left" ? (e.pageX < p1) : (e.pageX < p1 || e.pageX > p2));
            
            if (resizeHandle) {
                var field = $(this).parent().attr("field");
                var col = _getColumnOption(jq, field);
                if (col.resizable == false) {
                    return;
                }
                $(jq).datagrid("autoSizeColumn", field);
                col.auto = false;
            }
        });
        var resizeHandle = opts.resizeHandle == "right" ? "e" : (opts.resizeHandle == "left" ? "w" : "e,w");
        gridcell.each(function () {
            $(this).resizable({
                handles: resizeHandle,
                disabled: ($(this).attr("resizable") ? $(this).attr("resizable") == "false" : false),
                minWidth: 25,
                onStartResize: function (e) {
                    datagrid.resizing = true;
                    headinner.css("cursor", $("body").css("cursor"));
                    if (!datagrid.proxy) {
                        datagrid.proxy = $("<div class=\"datagrid-resize-proxy\"></div>").appendTo(dc.view);
                    }
                    datagrid.proxy.css({ left: e.pageX - $(panel).offset().left - 1, display: "none" });
                    setTimeout(function () {
                        if (datagrid.proxy) {
                            datagrid.proxy.show();
                        }
                    }, 500);
                },
                onResize: function (e) {
                    datagrid.proxy.css({ left: e.pageX - $(panel).offset().left - 1, display: "block" });
                    return false;
                },
                onStopResize: function (e) {
                    headinner.css("cursor", "");
                    var field = $(this).parent().attr("field");
                    var col = _getColumnOption(jq, field);
                    col.width = $(this)._outerWidth();
                    col.boxWidth = parseInt(this.style.width);
                    col.auto = undefined;
                    _fixColumnSize(jq, field);
                    datagrid.proxy.remove();
                    datagrid.proxy = null;
                    if ($(this).parents("div:first.datagrid-header").parent().hasClass("datagrid-view1")) {
                        _fitGridSize(jq);
                    }
                    _fitColumns(jq);
                    opts.onResizeColumn.call(jq, field, col.width);
                    setTimeout(function () {
                        datagrid.resizing = false;
                    }, 0);
                }
            });
        });
        //grid body 鼠标进入事件
        dc.body1.add(dc.body2).unbind().bind("mouseover", function (e) {
            
            if (datagrid.resizing) {
                return;
            }
            var tr = $(e.target).closest("tr.datagrid-row");
            if (!tr.length) {
                return;
            }
            var index = get_trIndex(tr);           
            opts.finder.getTr(jq, index).addClass("datagrid-row-over");
            e.stopPropagation();
        }).bind("mouseout", function (e) { //grid body 鼠标移出事件
            var tr = $(e.target).closest("tr.datagrid-row");
            if (!tr.length) {
                return;
            }
            var index = get_trIndex(tr);
            opts.finder.getTr(jq, index).removeClass("datagrid-row-over");
            e.stopPropagation();
        }).bind("click", function (e) { //grid body 鼠标点击事件           
            var tt = $(e.target);
            var tr = tt.closest("tr.datagrid-row");
            if (!tr.length) {
                return;
            }
            var index = get_trIndex(tr);
            if (tt.parent().hasClass("datagrid-cell-check")) {
                if (opts.singleSelect && opts.selectOnCheck) {
                    if (!opts.checkOnSelect) {
                        _clearChecked(jq, true);
                    }
                    _checkRow(jq, index);
                } else {
                    if (tt.is(":checked")) {
                        _checkRow(jq, index);
                    } else {
                        _uncheckRow(jq, index);
                    }
                }
            } else {
                var row = opts.finder.getRow(jq, index);
                var td = tt.closest("td[field]", tr);
                if (td.length) {
                    var _6f = td.attr("field");
                    opts.onClickCell.call(jq, index, _6f, row[_6f]);
                }
                if (opts.singleSelect == true) {
                    _selectRow(jq, index);
                } else {
                    if (tr.hasClass("datagrid-row-selected")) {
                        _unselectRow(jq, index);
                    } else {
                        _selectRow(jq, index);
                    }
                }
                opts.onClickRow.call(jq, index, row);
            }
            e.stopPropagation();
        }).bind("dblclick", function (e) {//grid body 鼠标双击事件 
            var tt = $(e.target);
            var tr = tt.closest("tr.datagrid-row");
            if (!tr.length) {
                return;
            }
            var index = get_trIndex(tr);
            var row = opts.finder.getRow(jq, index);
            var td = tt.closest("td[field]", tr);
            if (td.length) {
                var field = td.attr("field");
                opts.onDblClickCell.call(jq, index, field, row[field]);
            }
            opts.onDblClickRow.call(jq, index, row);
            e.stopPropagation();
        }).bind("contextmenu", function (e) {//grid body 鼠标右键事件 
            var tr = $(e.target).closest("tr.datagrid-row");
            if (!tr.length) {
                return;
            }
            var index = get_trIndex(tr);
            var row = opts.finder.getRow(jq, index);
            opts.onRowContextMenu.call(jq, e, index, row);
            e.stopPropagation();
        });
        dc.body2.bind("scroll", function () {//grid body 滚动条事件 
         
            dc.view1.children("div.datagrid-body").scrollTop($(this).scrollTop());
            dc.view2.children("div.datagrid-header,div.datagrid-footer")._scrollLeft($(this)._scrollLeft());
            dc.body2.children("table.datagrid-btable-frozen").css("left", -$(this)._scrollLeft());
        });
        //获取td index
        function get_trIndex(tr) {
            if (tr.attr("datagrid-row-index")) {
                return parseInt(tr.attr("datagrid-row-index"));
            } else {
                return tr.attr("node-id");
            }
        };
    };
    //使列自动展开/收缩到合适的数据表格宽度
    function _fitColumns(jq) {
        var opts = $.data(jq, "datagrid").options;
        var dc = $.data(jq, "datagrid").dc;
        if (!opts.fitColumns) {
            return;
        }
        var header = dc.view2.children("div.datagrid-header");
        var visableWidth = 0;
        var visableColumn;
        var fields = _getColumnFields(jq, false);
        for (var i = 0; i < fields.length; i++) {
            var col = _getColumnOption(jq, fields[i]);
            if (_7a(col)) {
                visableWidth += col.width;
                visableColumn = col;
            }
        }
        var innerHeader = header.children("div.datagrid-header-inner").show();
        var fullWidth = header.width() - header.find("table").width() - opts.scrollbarSize;
        var rate = fullWidth / visableWidth;
        if (!opts.showHeader) {
            innerHeader.hide();
        }
        for (var i = 0; i < fields.length; i++) {
            var col = _getColumnOption(jq, fields[i]);
            if (_7a(col)) {
                var width = Math.floor(col.width * rate);
                fitColumnWidth(col, width);
                fullWidth -= width;
            }
        }
        if (fullWidth && visableColumn) {
            fitColumnWidth(visableColumn, fullWidth);
        }
        _fixColumnSize(jq);
        function fitColumnWidth(col, _80) {
            col.width += _80;
            col.boxWidth += _80;
            header.find("td[field=\"" + col.field + "\"] div.datagrid-cell").width(col.boxWidth);
        };
        function _7a(col) {
            if (!col.hidden && !col.checkbox && !col.auto) {
                return true;
            }
        };
    };
    //自动调整列宽度以适应内容
    function _autoSizeColumn(jq, filed) {
        var opts = $.data(jq, "datagrid").options;
        var dc = $.data(jq, "datagrid").dc;
        if (filed) {
            _resize(filed);
            if (opts.fitColumns) {
                _fitGridSize(jq);
                _fitColumns(jq);
            }
        } else {
            var _85 = false;
            var _86 = _getColumnFields(jq, true).concat(_getColumnFields(jq, false));
            for (var i = 0; i < _86.length; i++) {
                var filed = _86[i];
                var col = _getColumnOption(jq, filed);
                if (col.auto) {
                    _resize(filed);
                    _85 = true;
                }
            }
            if (_85 && opts.fitColumns) {
                _fitGridSize(jq);
                _fitColumns(jq);
            }
        }
        function _resize(_87) {
            var _88 = dc.view.find("div.datagrid-header td[field=\"" + _87 + "\"] div.datagrid-cell");
            _88.css("width", "");
            var col = $(jq).datagrid("getColumnOption", _87);
            col.width = undefined;
            col.boxWidth = undefined;
            col.auto = true;
            $(jq).datagrid("fixColumnSize", _87);
            var _89 = Math.max(_88._outerWidth(), _8a("allbody"), _8a("allfooter"));
            _88._outerWidth(_89);
            col.width = _89;
            col.boxWidth = parseInt(_88[0].style.width);
            $(jq).datagrid("fixColumnSize", _87);
            opts.onResizeColumn.call(jq, _87, col.width);
            function _8a(_8b) {
                var _8c = 0;
                opts.finder.getTr(jq, 0, _8b).find("td[field=\"" + _87 + "\"] div.datagrid-cell").each(function () {
                    var w = $(this)._outerWidth();
                    if (_8c < w) {
                        _8c = w;
                    }
                });
                return _8c;
            };
        };
    };
    //固定列大小。如果'field'参数未配置,所有列大小将都是固定的
    function _fixColumnSize(jq, field) {
        var opts = $.data(jq, "datagrid").options;
        var dc = $.data(jq, "datagrid").dc;
        var vtable = dc.view.find("table.datagrid-btable,table.datagrid-ftable");
        vtable.css("table-layout", "fixed");
        if (field) {
            fix(field);
        } else {
            var ff = _getColumnFields(jq, true).concat(_getColumnFields(jq, false));
            for (var i = 0; i < ff.length; i++) {
                fix(ff[i]);
            }
        }
        vtable.css("table-layout", "auto");
        _91(jq);
        setTimeout(function () {
            _fixRowHeight(jq);
            fixEditorSize(jq);
        }, 0);
        function fix(field) {
            var col = _getColumnOption(jq, field);
            if (col.checkbox) {
                return;
            }
            var _93 = dc.view.children("style")[0];
            var _94 = _93.styleSheet ? _93.styleSheet : (_93.sheet || document.styleSheets[document.styleSheets.length - 1]);
            var _95 = _94.cssRules || _94.rules;
            for (var i = 0, len = _95.length; i < len; i++) {
                var _96 = _95[i];
                if (_96.selectorText.toLowerCase() == col.cellSelector.toLowerCase()) {
                    _96.style["width"] = col.boxWidth ? col.boxWidth + "px" : "auto";
                    break;
                }
            }
        };
    };
    function _91(jq) {
        var dc = $.data(jq, "datagrid").dc;
        dc.body1.add(dc.body2).find("td.datagrid-td-merged").each(function () {
            var td = $(this);
            var colspan = td.attr("colspan") || 1;
            var width = _getColumnOption(jq, td.attr("field")).width;
            for (var i = 1; i < colspan; i++) {
                td = td.next();
                width += _getColumnOption(jq, td.attr("field")).width + 1;
            }
            $(this).children("div.datagrid-cell")._outerWidth(width);
        });
    };
    function fixEditorSize(_9b) {
        var dc = $.data(_9b, "datagrid").dc;
        dc.view.find("div.datagrid-editable").each(function () {
            var _9c = $(this);
            var _9d = _9c.parent().attr("field");
            var col = $(_9b).datagrid("getColumnOption", _9d);
            _9c._outerWidth(col.width);
            var ed = $.data(this, "datagrid.editor");
            if (ed.actions.resize) {
                ed.actions.resize(ed.target, _9c.width());
            }
        });
    };
    //返回指定列属性
    function _getColumnOption(jq, filed) {
        function _a0(_a1) {
            if (_a1) {
                for (var i = 0; i < _a1.length; i++) {
                    var cc = _a1[i];
                    for (var j = 0; j < cc.length; j++) {
                        var c = cc[j];
                        if (c.field == filed) {
                            return c;
                        }
                    }
                }
            }
            return null;
        };
        var opts = $.data(jq, "datagrid").options;
        var col = _a0(opts.columns);
        if (!col) {
            col = _a0(opts.frozenColumns);
        }
        return col;
    };
    //返回列字段。如果设置了frozen属性为true,将返回固定列的字段名
    function _getColumnFields(jq, frozen) {
        var opts = $.data(jq, "datagrid").options;
        var columns = (frozen == true) ? (opts.frozenColumns || [[]]) : opts.columns;
        if (columns.length == 0) {
            return [];
        }
        var fields = [];
        function getFixedColspan(index) {
            var c = 0;
            var i = 0;
            while (true) {
                if (fields[i] == undefined) {
                    if (c == index) {
                        return i;
                    }
                    c++;
                }
                i++;
            }
        };
        function findColumnFields(r) {
            var ff = [];
            var c = 0;
            for (var i = 0; i < columns[r].length; i++) {
                var col = columns[r][i];
                if (col.field) {
                    ff.push([c, col.field]);
                }
                c += parseInt(col.colspan || "1");
            }
            for (var i = 0; i < ff.length; i++) {
                ff[i][0] = getFixedColspan(ff[i][0]);
            }
            for (var i = 0; i < ff.length; i++) {
                var f = ff[i];
                fields[f[0]] = f[1];
            }
        };
        for (var i = 0; i < columns.length; i++) {
            findColumnFields(i);
        }
        return fields;
    };
    //加载本地数据,旧的行将被移除
    function _removeData(jq, data) {
        var _ae = $.data(jq, "datagrid");
        var _af = _ae.options;
        var dc = _ae.dc;
        data = _af.loadFilter.call(jq, data);
        data.total = parseInt(data.total);
        _ae.data = data;
        if (data.footer) {
            _ae.footer = data.footer;
        }
        if (!_af.remoteSort) {
            var opt = _getColumnOption(jq, _af.sortName);
            if (opt) {
                var _b0 = opt.sorter || function (a, b) {
                    return (a > b ? 1 : -1);
                };
                data.rows.sort(function (r1, r2) {
                    return _b0(r1[_af.sortName], r2[_af.sortName]) * (_af.sortOrder == "asc" ? 1 : -1);
                });
            }
        }
        if (_af.view.onBeforeRender) {
            _af.view.onBeforeRender.call(_af.view, jq, data.rows);
        }
        _af.view.render.call(_af.view, jq, dc.body2, false);
        _af.view.render.call(_af.view, jq, dc.body1, true);
        if (_af.showFooter) {
            _af.view.renderFooter.call(_af.view, jq, dc.footer2, false);
            _af.view.renderFooter.call(_af.view, jq, dc.footer1, true);
        }
        if (_af.view.onAfterRender) {
            _af.view.onAfterRender.call(_af.view, jq);
        }
        dc.view.children("style:gt(0)").remove();
        _af.onLoadSuccess.call(jq, data);
        var _b1 = $(jq).datagrid("getPager");
        if (_b1.length) {
            if (_b1.pagination("options").total != data.total) {
                _b1.pagination("refresh", { total: data.total });
            }
        }
        _fixRowHeight(jq);
        dc.body2.triggerHandler("scroll");
        _b2();
        $(jq).datagrid("autoSizeColumn");
        function _b2() {
            if (_af.idField) {
                for (var i = 0; i < data.rows.length; i++) {
                    var row = data.rows[i];
                    if (_b3(_ae.selectedRows, row)) {
                        _selectRow(jq, i, true);
                    }
                    if (_b3(_ae.checkedRows, row)) {
                        _checkRow(jq, i, true);
                    }
                }
            }
            function _b3(a, r) {
                for (var i = 0; i < a.length; i++) {
                    if (a[i][_af.idField] == r[_af.idField]) {
                        a[i] = r;
                        return true;
                    }
                }
                return false;
            };
        };
    };
    //返回指定行的索引号,该行的参数可以是一行记录或一个ID字段值
    function _getRowIndex(jq, row) {
        var opts = $.data(jq, "datagrid").options;
        var rows = $.data(jq, "datagrid").data.rows;
        if (typeof row == "object") {
            return getObjectIndex(rows, row);
        } else {
            for (var i = 0; i < rows.length; i++) {
                if (rows[i][opts.idField] == row) {
                    return i;
                }
            }
            return -1;
        }
    };
    //返回所有被选中的行,当没有记录被选中的时候将返回一个空数组
    function _getSelected(jq) {
        var datagrid = $.data(jq, "datagrid");
        var opts = datagrid.options;
        var data = datagrid.data;
        if (opts.idField) {
            return datagrid.selectedRows;
        } else {
            var selectRows = [];
            opts.finder.getTr(jq, "", "selected", 2).each(function () {
                var _be = parseInt($(this).attr("datagrid-row-index"));
                selectRows.push(data.rows[_be]);
            });
            return selectRows;
        }
    };
    //在复选框呗选中的时候返回所有行
    function _getChecked(jq) {
        var datagrid = $.data(jq, "datagrid");
        var opts = datagrid.options;
        if (opts.idField) {
            return datagrid.checkedRows;
        } else {
            var checkRows = [];
            datagrid.dc.view.find("div.datagrid-cell-check input:checked").each(function () {
                var _c4 = $(this).closest("tr.datagrid-row").attr("datagrid-row-index");
                checkRows.push(opts.finder.getRow(jq, _c4));
            });
            return checkRows;
        }
    };
    //通过ID值参数选择一行
    function _selectRecord(jq, id) {
        var opts = $.data(jq, "datagrid").options;
        if (opts.idField) {
            var index = _getRowIndex(jq, id);
            if (index >= 0) {
                _selectRow(jq, index);
            }
        }
    };
    //选择一行,行索引从0开始
    function _selectRow(jq, index, _cd) {
        var datagrid = $.data(jq, "datagrid");
        var dc = datagrid.dc;
        var opts = datagrid.options;
        var selectRows = datagrid.selectedRows;
        if (opts.singleSelect) {
            _clearSelections(jq);
            selectRows.splice(0, selectRows.length);
        }
        if (!_cd && opts.checkOnSelect) {
            _checkRow(jq, index, true);
        }
        var row = opts.finder.getRow(jq, index);
        if (opts.idField) {
            idFieldRows(selectRows, opts.idField, row);
        }
        opts.onSelect.call(jq, index, row);
        var tr = opts.finder.getTr(jq, index).addClass("datagrid-row-selected");
        if (tr.length) {
            if (tr.closest("table").hasClass("datagrid-btable-frozen")) {
                return;
            }
            var _d3 = dc.view2.children("div.datagrid-header")._outerHeight();
            var _d4 = dc.body2;
            var _d5 = _d4.outerHeight(true) - _d4.outerHeight();
            var top = tr.position().top - _d3 - _d5;
            if (top < 0) {
                _d4.scrollTop(_d4.scrollTop() + top);
            } else {
                if (top + tr._outerHeight() > _d4.height() - 18) {
                    _d4.scrollTop(_d4.scrollTop() + top + tr._outerHeight() - _d4.height() + 18);
                }
            }
        }
    };
    function _unselectRow(_d7, _d8, _d9) {
        var _da = $.data(_d7, "datagrid");
        var dc = _da.dc;
        var _db = _da.options;
        var _dc = $.data(_d7, "datagrid").selectedRows;
        if (!_d9 && _db.checkOnSelect) {
            _uncheckRow(_d7, _d8, true);
        }
        _db.finder.getTr(_d7, _d8).removeClass("datagrid-row-selected");
        var row = _db.finder.getRow(_d7, _d8);
        if (_db.idField) {
            unSelectedRowsById(_dc, _db.idField, row[_db.idField]);
        }
        _db.onUnselect.call(_d7, _d8, row);
    };
    function _selectAll(_df, _e0) {
        var _e1 = $.data(_df, "datagrid");
        var _e2 = _e1.options;
        var _e3 = _e1.data.rows;
        var _e4 = $.data(_df, "datagrid").selectedRows;
        if (!_e0 && _e2.checkOnSelect) {
            _checkAll(_df, true);
        }
        _e2.finder.getTr(_df, "", "allbody").addClass("datagrid-row-selected");
        if (_e2.idField) {
            for (var _e6 = 0; _e6 < _e3.length; _e6++) {
                idFieldRows(_e4, _e2.idField, _e3[_e6]);
            }
        }
        _e2.onSelectAll.call(_df, _e3);
    };
    function _clearSelections(_e7, _e8) {
        var _e9 = $.data(_e7, "datagrid");
        var _ea = _e9.options;
        var _eb = _e9.data.rows;
        var _ec = $.data(_e7, "datagrid").selectedRows;
        if (!_e8 && _ea.checkOnSelect) {
            _clearChecked(_e7, true);
        }
        _ea.finder.getTr(_e7, "", "selected").removeClass("datagrid-row-selected");
        if (_ea.idField) {
            for (var _ee = 0; _ee < _eb.length; _ee++) {
                unSelectedRowsById(_ec, _ea.idField, _eb[_ee][_ea.idField]);
            }
        }
        _ea.onUnselectAll.call(_e7, _eb);
    };
    //勾选一行 
    function _checkRow(jq, index, state) {
        var datagrid = $.data(jq, "datagrid");
        var opts = datagrid.options;
        if (!state && opts.selectOnCheck) {
            _selectRow(jq, index, true);
        }
        var ck = opts.finder.getTr(jq, index).find("div.datagrid-cell-check input[type=checkbox]");
        ck._propAttr("checked", true);
        ck = opts.finder.getTr(jq, "", "allbody").find("div.datagrid-cell-check input[type=checkbox]:not(:checked)");
        if (!ck.length) {
            var dc = datagrid.dc;
            var _f4 = dc.header1.add(dc.header2);
            _f4.find("input[type=checkbox]")._propAttr("checked", true);
        }
        var row = opts.finder.getRow(jq, index);
        if (opts.idField) {
            idFieldRows(datagrid.checkedRows, opts.idField, row);
        }
        opts.onCheck.call(jq, index, row);
    };
    //取消勾选一行 
    function _uncheckRow(jq, index, state) {
        var datagrid = $.data(jq, "datagrid");
        var opts = datagrid.options;
        if (!state && opts.selectOnCheck) {
            _unselectRow(jq, index, true);
        }
        var ck = opts.finder.getTr(jq, index).find("div.datagrid-cell-check input[type=checkbox]");
        ck._propAttr("checked", false);
        var dc = datagrid.dc;
        var _fa = dc.header1.add(dc.header2);
        _fa.find("input[type=checkbox]")._propAttr("checked", false);
        var row = opts.finder.getRow(jq, index);
        if (opts.idField) {
            unSelectedRowsById(datagrid.checkedRows, opts.idField, row[opts.idField]);
        }
        opts.onUncheck.call(jq, index, row);
    };
    function _checkAll(_fb, _fc) {
        var _fd = $.data(_fb, "datagrid");
        var _fe = _fd.options;
        var _ff = _fd.data.rows;
        if (!_fc && _fe.selectOnCheck) {
            _selectAll(_fb, true);
        }
        var dc = _fd.dc;
        var hck = dc.header1.add(dc.header2).find("input[type=checkbox]");
        var bck = _fe.finder.getTr(_fb, "", "allbody").find("div.datagrid-cell-check input[type=checkbox]");
        hck.add(bck)._propAttr("checked", true);
        if (_fe.idField) {
            for (var i = 0; i < _ff.length; i++) {
                idFieldRows(_fd.checkedRows, _fe.idField, _ff[i]);
            }
        }
        _fe.onCheckAll.call(_fb, _ff);
    };
    function _clearChecked(_100, _101) {
        var _102 = $.data(_100, "datagrid");
        var opts = _102.options;
        var rows = _102.data.rows;
        if (!_101 && opts.selectOnCheck) {
            _clearSelections(_100, true);
        }
        var dc = _102.dc;
        var hck = dc.header1.add(dc.header2).find("input[type=checkbox]");
        var bck = opts.finder.getTr(_100, "", "allbody").find("div.datagrid-cell-check input[type=checkbox]");
        hck.add(bck)._propAttr("checked", false);
        if (opts.idField) {
            for (var i = 0; i < rows.length; i++) {
                unSelectedRowsById(_102.checkedRows, opts.idField, rows[i][opts.idField]);
            }
        }
        opts.onUncheckAll.call(_100, rows);
    };
    //开始编辑行
    function _beginEdit(jq, index) {
        var opts = $.data(jq, "datagrid").options;
        var tr = opts.finder.getTr(jq, index);
        var row = opts.finder.getRow(jq, index);
        if (tr.hasClass("datagrid-row-editing")) {
            return;
        }
        if (opts.onBeforeEdit.call(jq, index, row) == false) {
            return;
        }
        tr.addClass("datagrid-row-editing");
        createEditor(jq, index);
        fixEditorSize(jq);
        tr.find("div.datagrid-editable").each(function () {
            var _107 = $(this).parent().attr("field");
            var ed = $.data(this, "datagrid.editor");
            ed.actions.setValue(ed.target, row[_107]);
        });
        validateRow(jq, index);
    };
    //结束编辑行
    function _endEdit(jq, index, revert) {
        var opts = $.data(jq, "datagrid").options;
        var updatedRows = $.data(jq, "datagrid").updatedRows;
        var insertedRows = $.data(jq, "datagrid").insertedRows;
        var tr = opts.finder.getTr(jq, index);
        var row = opts.finder.getRow(jq, index);
        if (!tr.hasClass("datagrid-row-editing")) {
            return;
        }
        if (!revert) {
            if (!validateRow(jq, index)) {
                return;
            }
            var changed = false;
            var newValues = {};
            tr.find("div.datagrid-editable").each(function () {
                var field = $(this).parent().attr("field");
                var ed = $.data(this, "datagrid.editor");
                var field = ed.actions.getValue(ed.target);
                if (row[field] != field) {
                    row[field] = field;
                    changed = true;
                    newValues[field] = field;
                }
            });
            if (changed) {
                if (getObjectIndex(insertedRows, row) == -1) {
                    if (getObjectIndex(updatedRows, row) == -1) {
                        updatedRows.push(row);
                    }
                }
            }
        }
        tr.removeClass("datagrid-row-editing");
        destroyEditor(jq, index);
        $(jq).datagrid("refreshRow", index);
        if (!revert) {
            opts.onAfterEdit.call(jq, index, row, newValues);
        } else {
            opts.onCancelEdit.call(jq, index, row);
        }
    };
    //获取指定行的编辑器。每个编辑器都有以下属性:
    //actions:编辑器可以执行的动作,同编辑器定义。
    //target:目标编辑器的jQuery对象。
    //field:字段名称。
    //type:编辑器类型,比如:'text','combobox','datebox'等。
    function _getEditors(jq, index) {
        var opts = $.data(jq, "datagrid").options;
        var tr = opts.finder.getTr(jq, index);
        var editors = [];
        tr.children("td").each(function () {
            var cell = $(this).find("div.datagrid-editable");
            if (cell.length) {
                var ed = $.data(cell[0], "datagrid.editor");
                editors.push(ed);
            }
        });
        return editors;
    };
    //获取指定编辑器,options包含2个属性:
    //index:行索引。
    //field:字段名称。
    function _getEditor(jq, options) {
        var editors = _getEditors(jq, options.index);
        for (var i = 0; i < editors.length; i++) {
            if (editors[i].field == options.field) {
                return editors[i];
            }
        }
        return null;
    };
    //创建编辑器
    function createEditor(jq, index) {
        var opts = $.data(jq, "datagrid").options;
        var tr = opts.finder.getTr(jq, index);
        tr.children("td").each(function () {
            var cell = $(this).find("div.datagrid-cell");
            var field = $(this).attr("field");
            var col = _getColumnOption(jq, field);
            if (col && col.editor) {
                var type, editorOpts;
                if (typeof col.editor == "string") {
                    type = col.editor;
                } else {
                    type = col.editor.type;
                    editorOpts = col.editor.options;
                }
                var editor = opts.editors[type];
                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: type, oldHtml: html });
                }
            }
        });
        _fixRowHeight(jq, index, true);
    };
    //销毁编辑器
    function destroyEditor(jq, index) {
        var opts = $.data(jq, "datagrid").options;
        var tr = opts.finder.getTr(jq, 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", "");
            }
        });
    };
    //验证指定的行,当验证有效的时候返回true
    function validateRow(jq, index) {
        var tr = $.data(jq, "datagrid").options.finder.getTr(jq, index);
        if (!tr.hasClass("datagrid-row-editing")) {
            return true;
        }
        var vbox = tr.find(".validatebox-text");
        vbox.validatebox("validate");
        vbox.trigger("mouseleave");
        var invalid = tr.find(".validatebox-invalid");
        return invalid.length == 0;
    };
    //从上一次的提交获取改变的所有行。类型参数指明用哪些类型改变的行,可以使用的值有:inserted,deleted,updated等。当类型参数未配置的时候返回所有改变的行
    function _getChanges(jq, type) {
        var insertedRows = $.data(jq, "datagrid").insertedRows;
        var deletedRows = $.data(jq, "datagrid").deletedRows;
        var updatedRows = $.data(jq, "datagrid").updatedRows;
        if (!type) {
            var rows = [];
            rows = rows.concat(insertedRows);
            rows = rows.concat(deletedRows);
            rows = rows.concat(updatedRows);
            return rows;
        } else {
            if (type == "inserted") {
                return insertedRows;
            } else {
                if (type == "deleted") {
                    return deletedRows;
                } else {
                    if (type == "updated") {
                        return updatedRows;
                    }
                }
            }
        }
        return [];
    };
    //删除行
    function _deleteRow(jq, index) {
        var datagrid = $.data(jq, "datagrid");
        var opts = datagrid.options;
        var data = datagrid.data;
        var insertedRows = datagrid.insertedRows;
        var deletedRows = datagrid.deletedRows;
        $(jq).datagrid("cancelEdit", index);
        var row = data.rows[index];
        if (getObjectIndex(insertedRows, row) >= 0) {
            unSelectedRowsById(insertedRows, row);
        } else {
            deletedRows.push(row);
        }
        unSelectedRowsById(datagrid.selectedRows, opts.idField, data.rows[index][opts.idField]);
        unSelectedRowsById(datagrid.checkedRows, opts.idField, data.rows[index][opts.idField]);
        opts.view.deleteRow.call(opts.view, jq, index);
        if (opts.height == "auto") {
            _fixRowHeight(jq);
        }
        $(jq).datagrid("getPager").pagination("refresh", { total: data.total });
    };
    //插入一个新行,参数包括一下属性:
    //index:要插入的行索引,如果该索引值未定义,则追加新行。
    //row:行数据
    function _insertRow(jq, param) {
        var data = $.data(jq, "datagrid").data;
        var view = $.data(jq, "datagrid").options.view;
        var insertedRows = $.data(jq, "datagrid").insertedRows;
        view.insertRow.call(view, jq, param.index, param.row);
        insertedRows.push(param.row);
        $(jq).datagrid("getPager").pagination("refresh", { total: data.total });
    };
    //追加一个新行。新行将被添加到最后的位置
    function _appendRow(jq, row) {
        var data = $.data(jq, "datagrid").data;
        var view = $.data(jq, "datagrid").options.view;
        var insertedRows = $.data(jq, "datagrid").insertedRows;
        view.insertRow.call(view, jq, null, row);
        insertedRows.push(row);
        $(jq).datagrid("getPager").pagination("refresh", { total: data.total });
    };
    //加载本地数据,旧的行将被移除
    function _loadData(jq) {
        var datagrid = $.data(jq, "datagrid");
        var data = datagrid.data;
        var rows = data.rows;
        var originalRows = [];
        for (var i = 0; i < rows.length; i++) {
            originalRows.push($.extend({}, rows[i]));
        }
        datagrid.originalRows = originalRows;
        datagrid.updatedRows = [];
        datagrid.insertedRows = [];
        datagrid.deletedRows = [];
    };
    //提交所有从加载或者上一次调用acceptChanges函数后更改的数据
    function _acceptChanges(jq) {
        var data = $.data(jq, "datagrid").data;
        var ok = true;
        for (var i = 0, len = data.rows.length; i < len; i++) {
            if (validateRow(jq, i)) {
                _endEdit(jq, i, false);
            } else {
                ok = false;
            }
        }
        if (ok) {
            _loadData(jq);
        }
    };
    //回滚所有从创建或者上一次调用acceptChanges函数后更改的数据
    function _rejectChanges(jq) {
        var datagrid = $.data(jq, "datagrid");
        var opts = datagrid.options;
        var originalRows = datagrid.originalRows;
        var insertedRows = datagrid.insertedRows;
        var deletedRows = datagrid.deletedRows;
        var selectedRows = datagrid.selectedRows;
        var checkedRows = datagrid.checkedRows;
        var data = datagrid.data;
        function Rowids(a) {
            var ids = [];
            for (var i = 0; i < a.length; i++) {
                ids.push(a[i][opts.idField]);
            }
            return ids;
        };
        function selectRecord(ids, type) {
            for (var i = 0; i < ids.length; i++) {
                var index = _getRowIndex(jq, ids[i]);
                (type == "s" ? _selectRow : _checkRow)(jq, index, true);
            }
        };
        for (var i = 0; i < data.rows.length; i++) {
            _endEdit(jq, i, true);
        }
        var sids = Rowids(selectedRows);
        var cids = Rowids(checkedRows);
        selectedRows.splice(0, selectedRows.length);
        checkedRows.splice(0, checkedRows.length);
        data.total += deletedRows.length - insertedRows.length;
        data.rows = originalRows;
        _removeData(jq, data);
        selectRecord(sids, "s");
        selectRecord(cids, "c");
        _loadData(jq);
    };
    //加载和显示第一页的所有行。如果指定了'param',它将取代'queryParams'属性。通常可以通过传递一些参数执行一次查询,通过调用这个方法从服务器加载新数据
    function _load(jq, param) {
        var opts = $.data(jq, "datagrid").options;
        if (param) {
            opts.queryParams = param;
        }
        var param = $.extend({}, opts.queryParams);
        if (opts.pagination) {
            $.extend(param, { page: opts.pageNumber, rows: opts.pageSize });
        }
        if (opts.sortName) {
            $.extend(param, { sort: opts.sortName, order: opts.sortOrder });
        }
        if (opts.onBeforeLoad.call(jq, param) == false) {
            return;
        }
        $(jq).datagrid("loading");
        setTimeout(function () {
            doRequest();
        }, 0);
        function doRequest() {
            var loaded = opts.loader.call(jq, param, function (data) {
                setTimeout(function () {
                    $(jq).datagrid("loaded");
                }, 0);
                _removeData(jq, data);
                setTimeout(function () {
                    _loadData(jq);
                }, 0);
            }, function () {
                setTimeout(function () {
                    $(jq).datagrid("loaded");
                }, 0);
                opts.onLoadError.apply(jq, arguments);
            });
            if (loaded == false) {
                $(jq).datagrid("loaded");
            }
        };
    };
    //合并单元格,options包含以下属性:
    //index:行索引。
    //field:字段名称。
    //rowspan:合并的行数。
    //colspan:合并的列数。
    function _mergeCells(jq, options) {
        var opts = $.data(jq, "datagrid").options;
        options.rowspan = options.rowspan || 1;
        options.colspan = options.colspan || 1;
        if (options.rowspan == 1 && options.colspan == 1) {
            return;
        }
        var tr = opts.finder.getTr(jq, (options.index != undefined ? options.index : options.id));
        if (!tr.length) {
            return;
        }
        var row = opts.finder.getRow(jq, tr);
        var field = row[options.field];
        var td = tr.find("td[field=\"" + options.field + "\"]");
        td.attr("rowspan", options.rowspan).attr("colspan", options.colspan);
        td.addClass("datagrid-td-merged");
        for (var i = 1; i < options.colspan; i++) {
            td = td.next();
            td.hide();
            row[td.attr("field")] = field;
        }
        for (var i = 1; i < options.rowspan; i++) {
            tr = tr.next();
            if (!tr.length) {
                break;
            }
            var row = opts.finder.getRow(jq, tr);
            var td = tr.find("td[field=\"" + options.field + "\"]").hide();
            row[td.attr("field")] = field;
            for (var j = 1; j < options.colspan; j++) {
                td = td.next();
                td.hide();
                row[td.attr("field")] = field;
            }
        }
        _91(jq);
    };
    //实例化
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return $.fn.datagrid.methods[options](this, param);
        }
        options = options || {};
        return this.each(function () {
            var state = $.data(this, "datagrid");
            var opts;
            if (state) {
                opts = $.extend(state.options, options);
                state.options = opts;
            } else {
                opts = $.extend({}, $.extend({}, $.fn.datagrid.defaults, { queryParams: {} }),
                    $.fn.datagrid.parseOptions(this),
                    options);
                $(this).css("width", "").css("height", "");
                var gridWrap = wrapGrid(this, opts.rownumbers);
                if (!opts.columns) {
                    opts.columns = gridWrap.columns;
                }
                if (!opts.frozenColumns) {
                    opts.frozenColumns = gridWrap.frozenColumns;
                }
                opts.columns = $.extend(true, [], opts.columns);
                opts.frozenColumns = $.extend(true, [], opts.frozenColumns);
                opts.view = $.extend({}, opts.view);
                $.data(this, "datagrid", {
                    options: opts,
                    panel: gridWrap.panel,
                    dc: gridWrap.dc,
                    selectedRows: [],
                    checkedRows: [],
                    data: { total: 0, rows: [] },
                    originalRows: [],
                    updatedRows: [],
                    insertedRows: [],
                    deletedRows: []
                });
            }
            init(this);
            if (opts.data) {
                _removeData(this, opts.data);
                _loadData(this);
            } else {
                var data = getGridData(this);
                if (data.total > 0) {
                    _removeData(this, data);
                    _loadData(this);
                }
            }
            _resize(this);
            _load(this);
            bingEvent(this);
        });
    };
    //editors 重写默认值对象
    var editors = {
        //文本框
        text: {
            //初始化编辑器并返回目标对象
            init: function (container, options) {
                var editor = $("<input type=\"text\" class=\"datagrid-editable-input\">").appendTo(container);
                return editor;
            },
            //从编辑器中获取值
            getValue: function () {
                return $(target).val();
            },
            //向编辑器中写入值
            setValue: function (target, value) {
                $(target).val(value);
            },
            //向编辑器中写入值
            resize: function (target, width) {
                $(target)._outerWidth(width);
            }
        },
        //多行文本
        textarea: {
            //初始化编辑器并返回目标对象
            init: function (container, options) {
                var editor = $("<textarea class=\"datagrid-editable-input\"></textarea>").appendTo(container);
                return editor;
            },
            getValue: function (target) {
                return $(target).val();
            },
            setValue: function (target, value) {
                $(target).val(value);
            },
            resize: function (target, width) {
                $(target)._outerWidth(width);
            }
        },
        //选择框
        checkbox: {
            //初始化编辑器并返回目标对象
            init: function (container, options) {
                var editor = $("<input type=\"checkbox\">").appendTo(container);
                editor.val(options.on);
                editor.attr("offval", options.off);
                return editor;
            },
            getValue: function (target) {
                if ($(target).is(":checked")) {
                    return $(target).val();
                } else {
                    return $(target).attr("offval");
                }
            },
            setValue: function (target, value) {
                var checked = false;
                if ($(target).val() == value) {
                    checked = true;
                }
                $(target)._propAttr("checked", checked);
            }
        },
        //数值输入框
        numberbox: {
            //初始化编辑器并返回目标对象
            init: function (container, options) {
                var editor = $("<input type=\"text\" class=\"datagrid-editable-input\">").appendTo(container);
                editor.numberbox(options);
                return editor;
            },
            destroy: function (target) {
                $(target).numberbox("destroy");
            },
            getValue: function (target) {
                $(target).blur();
                return $(target).numberbox("getValue");
            },
            setValue: function (target, value) {
                $(target).numberbox("setValue", value);
            },
            resize: function (target, width) {
                $(target)._outerWidth(width);
            }
        },
        //验证框
        validatebox: {
            //初始化编辑器并返回目标对象
            init: function (container, options) {
                var editor = $("<input type=\"text\" class=\"datagrid-editable-input\">").appendTo(container);
                editor.validatebox(options);
                return editor;
            },
            destroy: function (target) {
                $(target).validatebox("destroy");
            },
            getValue: function (target) {
                return $(target).val();
            },
            setValue: function (target, value) {
                $(target).val(value);
            },
            resize: function (target, width) {
                $(target)._outerWidth(width);
            }
        },
        //日期框
        datebox: {
            //初始化编辑器并返回目标对象
            init: function (container, options) {
                var editor = $("<input type=\"text\">").appendTo(container);
                editor.datebox(options);
                return editor;
            },
            destroy: function (target) {
                $(target).datebox("destroy");
            },
            getValue: function (target) {
                return $(target).datebox("getValue");
            },
            setValue: function (target, value) {
                $(target).datebox("setValue", value);
            },
            resize: function (target, width) {
                $(target).datebox("resize", width);
            }
        },
        //下拉框
        combobox: {
            //初始化编辑器并返回目标对象
            init: function (container, options) {
                var editor = $("<input type=\"text\">").appendTo(container);
                editor.combobox(options || {});
                return editor;
            },
            destroy: function (target) {
                $(target).combobox("destroy");
            },
            getValue: function (target) {
                return $(target).combobox("getValue");
            },
            setValue: function (target, value) {
                $(target).combobox("setValue", value);
            },
            resize: function (target, width) {
                $(target).combobox("resize", width);
            }
        },
        //下拉树
        combotree: {
            //初始化编辑器并返回目标对象
            init: function (container, target) {
                var editor = $("<input type=\"text\">").appendTo(container);
                editor.combotree(target);
                return editor;
            },
            destroy: function (target) {
                $(target).combotree("destroy");
            },
            getValue: function (target) {
                return $(target).combotree("getValue");
            },
            setValue: function (target, value) {
                $(target).combotree("setValue", value);
            },
            resize: function (target, width) {
                $(target).combotree("resize", width);
            }
        }
    };

    //表格默认方法
    $.fn.datagrid.methods = {
        //返回属性对象
        options: function (jq) {
            var opts = $.data(jq[0], "datagrid").options;
            var panelOpts = $.data(jq[0], "datagrid").panel.panel("options");
            var opts = $.extend(opts,
                {
                    width: panelOpts.width,
                    height: panelOpts.height,
                    closed: panelOpts.closed,
                    collapsed: panelOpts.collapsed,
                    minimized: panelOpts.minimized,
                    maximized: panelOpts.maximized
                });
            return opts;
        },
        //返回面板对象
        getPanel: function (jq) {
            return $.data(jq[0], "datagrid").panel;
        },
        //返回页面对象
        getPager: function (jq) {
            return $.data(jq[0], "datagrid").panel.children("div.datagrid-pager");
        },
        //返回列字段。如果设置了frozen属性为true,将返回固定列的字段名
        getColumnFields: function (jq, frozen) {
            return _getColumnFields(jq[0], frozen);
        },
        //返回指定列属性
        getColumnOption: function (jq, field) {
            return _getColumnOption(jq[0], field);
        },
        //做调整和布局
        resize: function (jq, param) {
            return jq.each(function () {
                _resize(this, param);
            });
        },
        //加载和显示第一页的所有行。如果指定了'param',它将取代'queryParams'属性。通常可以通过传递一些参数执行一次查询,通过调用这个方法从服务器加载新数据
        load: function (jq, param) {
            return jq.each(function () {
                var opts = $(this).datagrid("options");
                opts.pageNumber = 1;
                var Pager = $(this).datagrid("getPager");
                Pager.pagination({ pageNumber: 1 });
                _load(this, param);
            });
        },
        //重载行。等同于'load'方法,但是它将保持在当前页
        reload: function (jq, param) {
            return jq.each(function () {
                _load(this, param);
            });
        },
        //重载页脚行。代码示例
        reloadFooter: function (jq, footer) {
            return jq.each(function () {
                var opts = $.data(this, "datagrid").options;
                var dc = $.data(this, "datagrid").dc;
                if (footer) {
                    $.data(this, "datagrid").footer = footer;
                }
                if (opts.showFooter) {
                    opts.view.renderFooter.call(opts.view, this, dc.footer2, false);
                    opts.view.renderFooter.call(opts.view, this, dc.footer1, true);
                    if (opts.view.onAfterRender) {
                        opts.view.onAfterRender.call(opts.view, this);
                    }
                    $(this).datagrid("fixRowHeight");
                }
            });
        },
        //显示载入状态
        loading: function (jq) {
            return jq.each(function () {
                var opts = $.data(this, "datagrid").options;
                $(this).datagrid("getPager").pagination("loading");
                if (opts.loadMsg) {
                    var Panel = $(this).datagrid("getPanel");
                    $("<div class=\"datagrid-mask\" style=\"display:block\"></div>").appendTo(Panel);
                    var msg = $("<div class=\"datagrid-mask-msg\" style=\"display:block;left:50%\"></div>").html(opts.loadMsg).appendTo(Panel);
                    msg.css("marginLeft", -msg.outerWidth() / 2);
                }
            });
        },
        //隐藏载入状态
        loaded: function (jq) {
            return jq.each(function () {
                $(this).datagrid("getPager").pagination("loaded");
                var Panel = $(this).datagrid("getPanel");
                Panel.children("div.datagrid-mask-msg").remove();
                Panel.children("div.datagrid-mask").remove();
            });
        },
        //使列自动展开/收缩到合适的数据表格宽度
        fitColumns: function (jq) {
            return jq.each(function () {
                _fitColumns(this);
            });
        },
        //固定列大小。如果'field'参数未配置,所有列大小将都是固定的
        fixColumnSize: function (jq, field) {
            return jq.each(function () {
                _fixColumnSize(this, field);
            });
        },
        //固定指定列高度。如果'index'参数未配置,所有行高度都是固定的
        fixRowHeight: function (jq, index) {
            return jq.each(function () {
                _fixRowHeight(this, index);
            });
        },
        //冻结指定行,当数据表格表格向下滚动的时候始终保持被冻结的行显示在顶部
        freezeRow: function (jq, index) {
            return jq.each(function () {
                _freezeRow(this, index);
            });
        },
        //自动调整列宽度以适应内容
        autoSizeColumn: function (jq, field) {
            return jq.each(function () {
                _autoSizeColumn(this, field);
            });
        },
        //加载本地数据,旧的行将被移除
        loadData: function (jq, data) {
            return jq.each(function () {
                _removeData(this, data);
                _loadData(this);
            });
        },
        //返回加载完毕后的数据
        getData: function (jq) {
            return $.data(jq[0], "datagrid").data;
        },
        //返回当前页的所有行
        getRows: function (jq) {
            return $.data(jq[0], "datagrid").data.rows;
        },
        //返回页脚行
        getFooterRows: function (jq) {
            return $.data(jq[0], "datagrid").footer;
        },
        //返回指定行的索引号,该行的参数可以是一行记录或一个ID字段值
        getRowIndex: function (jq, id) {
            return _getRowIndex(jq[0], id);
        },
        //在复选框呗选中的时候返回所有行
        getChecked: function (jq) {
            return _getChecked(jq[0]);
        },
        //返回第一个被选中的行或如果没有选中的行则返回null
        getSelected: function (jq) {
            var rows = _getSelected(jq[0]);
            return rows.length > 0 ? rows[0] : null;
        },
        //返回所有被选中的行,当没有记录被选中的时候将返回一个空数组
        getSelections: function (jq) {
            return _getSelected(jq[0]);
        },
        //清除所有选择的行
        clearSelections: function (jq) {
            return jq.each(function () {
                var selectedRows = $.data(this, "datagrid").selectedRows;
                selectedRows.splice(0, selectedRows.length);
                _clearSelections(this);
            });
        },
        //清楚所有勾选的行
        clearChecked: function (jq) {
            return jq.each(function () {
                var checkedRows = $.data(this, "datagrid").checkedRows;
                checkedRows.splice(0, checkedRows.length);
                _clearChecked(this);
            });
        },
        //clearChecked
        selectAll: function (jq) {
            return jq.each(function () {
                _selectAll(this);
            });
        },
        //取消选择所有当前页中所有的行
        unselectAll: function (jq) {
            return jq.each(function () {
                _clearSelections(this);
            });
        },
        //选择一行,行索引从0开始
        selectRow: function (jq, index) {
            return jq.each(function () {
                _selectRow(this, index);
            });
        },
        //通过ID值参数选择一行
        selectRecord: function (jq, id) {
            return jq.each(function () {
                _selectRecord(this, id);
            });
        },
        //取消选择一行
        unselectRow: function (jq, index) {
            return jq.each(function () {
                _unselectRow(this, index);
            });
        },
        //勾选一行,行索引从0开始
        checkRow: function (jq, index) {
            return jq.each(function () {
                _checkRow(this, index);
            });
        },

        uncheckRow: function (jq, _1b7) {
            return jq.each(function () {
                _uncheckRow(this, _1b7);
            });
        },
        //勾选当前页中的所有行
        checkAll: function (jq) {
            return jq.each(function () {
                _checkAll(this);
            });
        },
        //取消勾选当前页中的所有行
        uncheckAll: function (jq) {
            return jq.each(function () {
                _clearChecked(this);
            });
        },
        //开始编辑行
        beginEdit: function (jq, index) {
            return jq.each(function () {
                _beginEdit(this, index);
            });
        },
        //结束编辑行
        endEdit: function (jq, index) {
            return jq.each(function () {
                _endEdit(this, index, false);
            });
        },
        //取消编辑行
        cancelEdit: function (jq, index) {
            return jq.each(function () {
                _endEdit(this, index, true);
            });
        },
        //获取指定行的编辑器。每个编辑器都有以下属性:
        //actions:编辑器可以执行的动作,同编辑器定义。
        //target:目标编辑器的jQuery对象。
        //field:字段名称。
        //type:编辑器类型,比如:'text','combobox','datebox'等。
        getEditors: function (jq, index) {
            return _getEditors(jq[0], index);
        },
        //获取指定编辑器,options包含2个属性:
        //index:行索引。
        //field:字段名称。 
        getEditor: function (jq, options) {
            return _getEditor(jq[0], options);
        },
        //刷新行。
        refreshRow: function (jq, index) {
            return jq.each(function () {
                var opts = $.data(this, "datagrid").options;
                opts.view.refreshRow.call(opts.view, this, index);
            });
        },
        //验证指定的行,当验证有效的时候返回true
        validateRow: function (jq, index) {
            return validateRow(jq[0], index);
        },
        //更新指定行,参数包含下列属性:
        //index:执行更新操作的行索引。
        //row:更新行的新数据
        updateRow: function (jq, param) {
            return jq.each(function () {
                var opts = $.data(this, "datagrid").options;
                opts.view.updateRow.call(opts.view, this, param.index, param.row);
            });
        },
        //追加一个新行。新行将被添加到最后的位置
        appendRow: function (jq, row) {
            return jq.each(function () {
                _appendRow(this, row);
            });
        },
        //插入一个新行,参数包括一下属性:
        //index:要插入的行索引,如果该索引值未定义,则追加新行。
        //row:行数据
        insertRow: function (jq, param) {
            return jq.each(function () {
                _insertRow(this, param);
            });
        },
        //删除行
        deleteRow: function (jq, index) {
            return jq.each(function () {
                _deleteRow(this, index);
            });
        },
        //从上一次的提交获取改变的所有行。类型参数指明用哪些类型改变的行,可以使用的值有:inserted,deleted,updated等。当类型参数未配置的时候返回所有改变的行
        getChanges: function (jq, type) {
            return _getChanges(jq[0], type);
        },
        //提交所有从加载或者上一次调用acceptChanges函数后更改的数据
        acceptChanges: function (jq) {
            return jq.each(function () {
                _acceptChanges(this);
            });
        },
        //回滚所有从创建或者上一次调用acceptChanges函数后更改的数据
        rejectChanges: function (jq) {
            return jq.each(function () {
                _rejectChanges(this);
            });
        },
        //合并单元格,options包含以下属性:
        //index:行索引。
        //field:字段名称。
        //rowspan:合并的行数。
        //colspan:合并的列数。
        mergeCells: function (jq, options) {
            return jq.each(function () {
                _mergeCells(this, options);
            });
        },
        //显示指定的列
        showColumn: function (jq, field) {
            return jq.each(function () {
                var Panel = $(this).datagrid("getPanel");
                Panel.find("td[field=\"" + field + "\"]").show();
                $(this).datagrid("getColumnOption", field).hidden = false;
                $(this).datagrid("fitColumns");
            });
        },
        //隐藏指定的列
        hideColumn: function (jq, field) {
            return jq.each(function () {
                var Panel = $(this).datagrid("getPanel");
                Panel.find("td[field=\"" + field + "\"]").hide();
                $(this).datagrid("getColumnOption", field).hidden = true;
                $(this).datagrid("fitColumns");
            });
        }
    };

    $.fn.datagrid.parseOptions = function (_1c8) {
        var t = $(_1c8);
        return $.extend({},
            $.fn.panel.parseOptions(_1c8),
            $.parser.parseOptions(_1c8, ["url", "toolbar", "idField", "sortName", "sortOrder", "pagePosition", "resizeHandle",
                { fitColumns: "boolean", autoRowHeight: "boolean", striped: "boolean", nowrap: "boolean" },
                { rownumbers: "boolean", singleSelect: "boolean", checkOnSelect: "boolean", selectOnCheck: "boolean" },
                { pagination: "boolean", pageSize: "number", pageNumber: "number" },
                { remoteSort: "boolean", showHeader: "boolean", showFooter: "boolean" },
                { scrollbarSize: "number" }]), {
                    pageList: (t.attr("pageList") ? eval(t.attr("pageList")) : undefined),
                    loadMsg: (t.attr("loadMsg") != undefined ? t.attr("loadMsg") : undefined),
                    rowStyler: (t.attr("rowStyler") ? eval(t.attr("rowStyler")) : undefined)
                });
    };
    //定义数据表格的视图 该视图是一个对象,将告诉数据表格如何渲染行。该对象必须定义下列函
    var view = {
        //    数据加载时调用。
        //target:DOM对象,数据表格对象。
        //container:行容器。
        //frozen:指明如何渲染冻结容器。
        render: function (target, container, frozen) {
            var datagrid = $.data(target, "datagrid");
            var opts = datagrid.options;
            var rows = datagrid.data.rows;
            var fields = $(target).datagrid("getColumnFields", frozen);
            if (frozen) {
                if (!(opts.rownumbers || (opts.frozenColumns && opts.frozenColumns.length))) {
                    return;
                }
            }
            var html = ["<table class=\"datagrid-btable\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody>"];
            for (var i = 0; i < rows.length; i++) {
                var cls = (i % 2 && opts.striped) ? "class=\"datagrid-row datagrid-row-alt\"" : "class=\"datagrid-row\"";
                var style = opts.rowStyler ? opts.rowStyler.call(target, i, rows[i]) : "";
                var style = style ? "style=\"" + style + "\"" : "";
                var _1d2 = datagrid.rowIdPrefix + "-" + (frozen ? 1 : 2) + "-" + i;
                html.push("<tr id=\"" + _1d2 + "\" datagrid-row-index=\"" + i + "\" " + cls + " " + style + ">");
                html.push(this.renderRow.call(this, target, fields, frozen, i, rows[i]));
                html.push("</tr>");
            }
            html.push("</tbody></table>");
            $(container).html(html.join(""));
        },
        //这是一个选择函数来渲染行页脚
        renderFooter: function (target, container, frozen) {
            var opts = $.data(target, "datagrid").options;
            var rows = $.data(target, "datagrid").footer || [];
            var fields = $(target).datagrid("getColumnFields", frozen);
            var html = ["<table class=\"datagrid-ftable\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody>"];
            for (var i = 0; i < rows.length; i++) {
                html.push("<tr class=\"datagrid-row\" datagrid-row-index=\"" + i + "\">");
                html.push(this.renderRow.call(this, target, fields, frozen, i, rows[i]));
                html.push("</tr>");
            }
            html.push("</tbody></table>");
            $(container).html(html.join(""));
        },
        //这是一个属性功能,将调用render函数
        renderRow: function (target, fields, frozen, rowIndex, rowData) {
            var opts = $.data(target, "datagrid").options;
            var cc = [];
            if (frozen && opts.rownumbers) {
                var rowIndex = rowIndex + 1;
                if (opts.pagination) {
                    rowIndex += (opts.pageNumber - 1) * opts.pageSize;
                }
                cc.push("<td class=\"datagrid-td-rownumber\"><div class=\"datagrid-cell-rownumber\">" + rowIndex + "</div></td>");
            }
            for (var i = 0; i < fields.length; i++) {
                var field = fields[i];
                var col = $(target).datagrid("getColumnOption", field);
                if (col) {
                    var _1df = rowData[field];
                    var style = col.styler ? (col.styler(_1df, rowData, rowIndex) || "") : "";
                    var style = col.hidden ? "style=\"display:none;" + style + "\"" : (style ? "style=\"" + style + "\"" : "");
                    cc.push("<td field=\"" + field + "\" " + style + ">");
                    if (col.checkbox) {
                        var style = "";
                    } else {
                        var style = "";
                        if (col.align) {
                            style += "text-align:" + col.align + ";";
                        }
                        if (!opts.nowrap) {
                            style += "white-space:normal;height:auto;";
                        } else {
                            if (opts.autoRowHeight) {
                                style += "height:auto;";
                            }
                        }
                    }
                    cc.push("<div style=\"" + style + "\" ");
                    if (col.checkbox) {
                        cc.push("class=\"datagrid-cell-check ");
                    } else {
                        cc.push("class=\"datagrid-cell " + col.cellClass);
                    }
                    cc.push("\">");
                    if (col.checkbox) {
                        cc.push("<input type=\"checkbox\" name=\"" + field + "\" value=\"" + (_1df != undefined ? _1df : "") + "\"/>");
                    } else {
                        if (col.formatter) {
                            cc.push(col.formatter(_1df, rowData, rowIndex));
                        } else {
                            cc.push(_1df);
                        }
                    }
                    cc.push("</div>");
                    cc.push("</td>");
                }
            }
            return cc.join("");
        },
        //定义如何刷新指定的行
        refreshRow: function (target, rowIndex) {
            this.updateRow.call(this, target, rowIndex, {});
        },
        //更新行
        updateRow: function (target, rowIndex, row) {
            var opts = $.data(target, "datagrid").options;
            var rows = $(target).datagrid("getRows");
            $.extend(rows[rowIndex], row);
            var style = opts.rowStyler ? opts.rowStyler.call(target, rowIndex, rows[rowIndex]) : "";
            function _1e7(_1e8) {
                var _1e9 = $(target).datagrid("getColumnFields", _1e8);
                var tr = opts.finder.getTr(target, rowIndex, "body", (_1e8 ? 1 : 2));
                var _1ea = tr.find("div.datagrid-cell-check input[type=checkbox]").is(":checked");
                tr.html(this.renderRow.call(this, target, _1e9, _1e8, rowIndex, rows[rowIndex]));
                tr.attr("style", style || "");
                if (_1ea) {
                    tr.find("div.datagrid-cell-check input[type=checkbox]")._propAttr("checked", true);
                }
            };
            _1e7.call(this, true);
            _1e7.call(this, false);
            $(target).datagrid("fixRowHeight", rowIndex);
        },
        //插入行
        insertRow: function (target, rowIndex, row) {
            var datagrid = $.data(target, "datagrid");
            var opts = datagrid.options;
            var dc = datagrid.dc;
            var data = datagrid.data;
            if (rowIndex == undefined || rowIndex == null) {
                rowIndex = data.rows.length;
            }
            if (rowIndex > data.rows.length) {
                rowIndex = data.rows.length;
            }
            function _1ee(_1ef) {
                var _1f0 = _1ef ? 1 : 2;
                for (var i = data.rows.length - 1; i >= rowIndex; i--) {
                    var tr = opts.finder.getTr(target, i, "body", _1f0);
                    tr.attr("datagrid-row-index", i + 1);
                    tr.attr("id", datagrid.rowIdPrefix + "-" + _1f0 + "-" + (i + 1));
                    if (_1ef && opts.rownumbers) {
                        var _1f1 = i + 2;
                        if (opts.pagination) {
                            _1f1 += (opts.pageNumber - 1) * opts.pageSize;
                        }
                        tr.find("div.datagrid-cell-rownumber").html(_1f1);
                    }
                }
            };
            function _1f2(_1f3) {
                var _1f4 = _1f3 ? 1 : 2;
                var _1f5 = $(target).datagrid("getColumnFields", _1f3);
                var _1f6 = datagrid.rowIdPrefix + "-" + _1f4 + "-" + rowIndex;
                var tr = "<tr id=\"" + _1f6 + "\" class=\"datagrid-row\" datagrid-row-index=\"" + rowIndex + "\"></tr>";
                if (rowIndex >= data.rows.length) {
                    if (data.rows.length) {
                        opts.finder.getTr(target, "", "last", _1f4).after(tr);
                    } else {
                        var cc = _1f3 ? dc.body1 : dc.body2;
                        cc.html("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody>" + tr + "</tbody></table>");
                    }
                } else {
                    opts.finder.getTr(target, rowIndex + 1, "body", _1f4).before(tr);
                }
            };
            _1ee.call(this, true);
            _1ee.call(this, false);
            _1f2.call(this, true);
            _1f2.call(this, false);
            data.total += 1;
            data.rows.splice(rowIndex, 0, row);
            this.refreshRow.call(this, target, rowIndex);
        },
        //删除行
        deleteRow: function (target, rowIndex) {
            var datagrid = $.data(target, "datagrid");
            var opts = datagrid.options;
            var data = datagrid.data;
            function _1fa(_1fb) {
                var _1fc = _1fb ? 1 : 2;
                for (var i = rowIndex + 1; i < data.rows.length; i++) {
                    var tr = opts.finder.getTr(target, i, "body", _1fc);
                    tr.attr("datagrid-row-index", i - 1);
                    tr.attr("id", datagrid.rowIdPrefix + "-" + _1fc + "-" + (i - 1));
                    if (_1fb && opts.rownumbers) {
                        var _1fd = i;
                        if (opts.pagination) {
                            _1fd += (opts.pageNumber - 1) * opts.pageSize;
                        }
                        tr.find("div.datagrid-cell-rownumber").html(_1fd);
                    }
                }
            };
            opts.finder.getTr(target, rowIndex).remove();
            _1fa.call(this, true);
            _1fa.call(this, false);
            data.total -= 1;
            data.rows.splice(rowIndex, 1);
        },
        //在视图被呈现之前触发
        onBeforeRender: function (target, rows) {
        },
        //在视图呗呈现之后触发
        onAfterRender: function (target) {
            var opts = $.data(target, "datagrid").options;
            if (opts.showFooter) {
                var footer = $(target).datagrid("getPanel").find("div.datagrid-footer");
                footer.find("div.datagrid-cell-rownumber,div.datagrid-cell-check").css("visibility", "hidden");
            }
        }
    };
    //表格默认属性 以及事件(集成panel的属性和事件)
    $.fn.datagrid.defaults = $.extend({}, $.fn.panel.defaults, {
        frozenColumns: undefined,//同列属性,但是这些列将会被冻结在左侧
        columns: undefined,//数据表格列配置对象,详见列属性说明中更多的细节
        fitColumns: false,//真正的自动展开/收缩列的大小,以适应网格的宽度,防止水平滚动
        resizeHandle: "right",//调整列的位置,可用的值有:'left','right','both'。在使用'right'的时候用户可以通过拖动右侧边缘的列标题调整列
        autoRowHeight: true,//定义设置行的高度,根据该行的内容。设置为false可以提高负载性能
        toolbar: null,//顶部工具栏的数据表格面板。可能的值:1) 一个数组,每个工具属性都和linkbutton一样。 2) 选择器指定的工具栏
        striped: false,//是否显示斑马线效果
        method: "post",//该方法类型请求远程数据
        nowrap: true,//如果为true,则在同一行中显示数据。设置为true可以提高加载性能
        idField: null,//指明哪一个字段是标识字段
        url: null,//指明哪一个字段是标识字段
        data: null,//数据加载
        loadMsg: "Processing, please wait ...",//在从远程站点加载数据的时候显示提示消息
        rownumbers: false,//如果为true,则显示一个行号列
        singleSelect: false,//如果为true,则只允许选择一行
        selectOnCheck: true,//如果为true,单击复选框将永远选择行。        如果为false,选择行将不选中复选框
        checkOnSelect: true,//如果为true,当用户点击行的时候该复选框就会被选中或取消选中。   如果为false,当用户仅在点击该复选框的时候才会呗选中或取消
        pagination: false,//如果为true,则在数据表格控件底部显示分页工具栏
        pagePosition: "bottom",//定义分页工具栏的位置。可用的值有:'top','bottom','both'。
        pageNumber: 1,//在设置分页属性的时候初始化页码
        pageSize: 10,//在设置分页属性的时候初始化页面大小
        pageList: [10, 20, 30, 40, 50],//在设置分页属性的时候初始化页面大小
        queryParams: {},//在请求远程数据的时候发送额外的参数
        sortName: null,//定义哪些列可以进行排序
        sortOrder: "asc",//定义列的排序顺序,只能是'asc'或'desc'
        remoteSort: true,//定义从服务器对数据进行排序
        showHeader: true,//定义是否显示行头
        showFooter: false,//定义是否显示行脚
        scrollbarSize: 18,//滚动条的宽度(当滚动条是垂直的时候)或高度(当滚动条是水平的时候)。
        //返回样式如'background:red'。带2个参数的函数: rowIndex:该行索引从0开始  rowData:与此相对应的记录行
        rowStyler: function (rowIndex, rowData) {
        },
        //定义如何从远程服务器加载数据。返回false可以放弃本次请求动作。该函数接受以下参数:
        //param:参数对象传递给远程服务器。
        //success(data):当检索数据成功的时候会调用该回调函数。
        //error():当检索数据失败的时候会调用该回调函数
        loader: function (param, success, error) {
            var opts = $(this).datagrid("options");
            if (!opts.url) {
                return false;
            }
            $.ajax({
                type: opts.method, url: opts.url, data: param, dataType: "json", success: function (data) {
                    success(data);
                }, error: function () {
                    error.apply(this, arguments);
                }
            });
        },
        //返回过滤数据显示。该函数带一个参数'data'用来指向源数据(即:获取的数据源,比如Json对象)。您可以改变源数据的标准数据格式。这个函数必须返回包含'total'和'rows'属性的标准数据对象
        loadFilter: function (data) {
            if (typeof data.length == "number" && typeof data.splice == "function") {
                return { total: data.length, rows: data };
            } else {
                return data;
            }
        },
        //定义在编辑行的时候使用的编辑器
        editors: editors,

        finder: {
            getTr: function (target, rowIndex, type, step) {
                type = type || "body";
                step = step || 0;
                var _209 = $.data(target, "datagrid");
                var dc = _209.dc;
                var opts = _209.options;
                if (step == 0) {
                    var tr1 = opts.finder.getTr(target, rowIndex, type, 1);
                    var tr2 = opts.finder.getTr(target, rowIndex, type, 2);
                    return tr1.add(tr2);
                } else {
                    if (type == "body") {
                        var tr = $("#" + _209.rowIdPrefix + "-" + step + "-" + rowIndex);
                        if (!tr.length) {
                            tr = (step == 1 ? dc.body1 : dc.body2).find(">table>tbody>tr[datagrid-row-index=" + rowIndex + "]");
                        }
                        return tr;
                    } else {
                        if (type == "footer") {
                            return (step == 1 ? dc.footer1 : dc.footer2).find(">table>tbody>tr[datagrid-row-index=" + rowIndex + "]");
                        } else {
                            if (type == "selected") {
                                return (step == 1 ? dc.body1 : dc.body2).find(">table>tbody>tr.datagrid-row-selected");
                            } else {
                                if (type == "last") {
                                    return (step == 1 ? dc.body1 : dc.body2).find(">table>tbody>tr[datagrid-row-index]:last");
                                } else {
                                    if (type == "allbody") {
                                        return (step == 1 ? dc.body1 : dc.body2).find(">table>tbody>tr[datagrid-row-index]");
                                    } else {
                                        if (type == "allfooter") {
                                            return (step == 1 ? dc.footer1 : dc.footer2).find(">table>tbody>tr[datagrid-row-index]");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            getRow: function (_20a, p) {
                var _20b = (typeof p == "object") ? p.attr("datagrid-row-index") : p;
                return $.data(_20a, "datagrid").data.rows[parseInt(_20b)];
            }
        },
        //定义数据表格的视图
        view: view,
        //在载入请求数据数据之前触发,如果返回false可终止载入数据操作
        onBeforeLoad: function (param) {
        },
        //在数据加载成功的时候触发
        onLoadSuccess: function () {
        },
        //在数据加载成功的时候触发
        onLoadError: function () {
        },
        //在用户点击一行的时候触发,参数包括:
        //rowIndex:点击的行的索引值,该索引值从0开始。
        //rowData:对应于点击行的记录
        onClickRow: function (rowIndex, rowData) {
        },
        //在用户双击一行的时候触发,参数包括:
        //rowIndex:点击的行的索引值,该索引值从0开始。
        //rowData:对应于点击行的记录
        onDblClickRow: function (rowIndex, onDblClickRow) {
        },
        //在用户点击一个单元格的时候触发
        onClickCell: function (rowIndex, field, value) {
        },
        //在用户双击一个单元格的时候触发
        onDblClickCell: function (rowIndex, field, value) {
        },
        //在用户排序一列的时候触发,参数包括:
        //sort:排序列字段名称。
        //order:排序列的顺序(ASC或DESC)
        onSortColumn: function (sort, order) {
        },
        //在用户调整列大小的时候触发
        onResizeColumn: function (field, width) {
        },
        //在用户选择一行的时候触发,参数包括:
        //rowIndex:选择的行的索引值,索引从0开始。
        //rowData:对应于所选行的记录
        onSelect: function (rowIndex, rowData) {
        },
        //        在用户选择一行的时候触发,参数包括:
        //rowIndex:选择的行的索引值,索引从0开始。
        //rowData:对应于所选行的记录
        onUnselect: function (rowIndex, rowData) {
        },
        //在用户选择所有行的时候触发
        onSelectAll: function (rows) {
        },
        //在用户取消选择所有行的时候触发
        onUnselectAll: function (rows) {
        },
        //        在用户勾选一行的时候触发,参数包括:
        //rowIndex:选中的行索引,索引从0开始。
        //rowData:对应于所选行的记录
        onCheck: function (rowIndex, rowData) {
        },
        //        在用户取消勾选一行的时候触发,参数包括:
        //rowIndex:选中的行索引,索引从0开始。
        //rowData:对应于取消勾选行的记录
        onUncheck: function (rowIndex, rowData) {
        },
        //在用户勾选所有行的时候触发
        onCheckAll: function (rows) {
        },
        //在用户取消勾选所有行的时候触发
        onUncheckAll: function (rows) {
        },
        //        在用户开始编辑一行的时候触发,参数包括:
        //rowIndex:编辑行的索引,索引从0开始。
        //rowData:对应于编辑行的记录
        onBeforeEdit: function (rowIndex, rowData) {
        },
        //        在用户完成编辑一行的时候触发,参数包括:
        //rowIndex:编辑行的索引,索引从0开始。
        //rowData:对应于完成编辑的行的记录。
        //changes:更改后的字段(键)/值对
        onAfterEdit: function (rowIndex, rowData, changes) {
        },
        //        在用户取消编辑一行的时候触发,参数包括:
        //rowIndex:编辑行的索引,索引从0开始。
        //rowData:对应于编辑行的记录
        onCancelEdit: function (rowIndex, rowData) {
        },
        //在鼠标右击数据表格表格头的时候触发
        onHeaderContextMenu: function (e, field) {
        },
        //在鼠标右击一行记录的时候触发
        onRowContextMenu: function (e, rowIndex, rowData) {
        }
    });
})(jQuery);

实例代码:

这里只是对grid进行的单个插件引入的例子进行简单的说明
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Frozen Columns in DataGrid - jQuery EasyUI Demo</title>
    <link rel="stylesheet" type="text/css" href="../../themes/default/easyui.css">
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">
    <link rel="stylesheet" type="text/css" href="../demo.css">
    
    <script type="text/javascript" src="../../jquery-1.8.0.min.js"></script>
    <script src="../../plugins2/jquery.parser.js"></script>
   
    <script src="../../plugins2/jquery.panel.js"></script>
     <script src="../../plugins/jquery.resizable.js"></script>
    <script src="../../plugins2/jquery.linkbutton.js"></script>
    <script src="../../plugins/jquery.pagination.js"></script>
    <script src="../../plugins2/jquery.datagrid.js"></script>
</head>
<body>
    <h2>Frozen Columns in DataGrid</h2>
    <div class="demo-info">
        <div class="demo-tip icon-tip"></div>
        <div>You can freeze some columns that can't scroll out of view.</div>
    </div>
    <div style="margin:10px 0;"></div>
    <table class="easyui-datagrid" title="Frozen Columns in DataGrid" style="width:700px;height:250px"
            data-options="rownumbers:true,singleSelect:true,url:'datagrid_data1.aspx'">
        <thead data-options="frozen:true">
            <tr>
                <th data-options="field:'itemid',width:100">Item ID</th>
                <th data-options="field:'productid',width:120">Product</th>
            </tr>
        </thead>
        <thead>
            <tr>
                <th data-options="field:'listprice',width:90,align:'right'">List Price</th>
                <th data-options="field:'unitcost',width:90,align:'right'">Unit Cost</th>
                <th data-options="field:'attr1',width:250">Attribute</th>
                <th data-options="field:'status',width:60,align:'center'">Status</th>
            </tr>
        </thead>
    </table>

</body>
</html>
赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏