• easyui源码翻译1.32--TreeGrid(树形表格)


    前言

    扩展自$.fn.datagrid.defaults。使用$.fn.treegrid.defaults重写默认值对象。下载该插件翻译源码

    树形表格用于显示分层数据表格。它是基于数据表格、组合树控件和可编辑表格。树形表格允许用户创建可定制的、异步展开行和显示在多列上的分层数据。

    源码

    /**
     * jQuery EasyUI 1.3.2
     * 
     *翻译:qq 1364386878 下拉树
     */
    (function ($) {
        //获取行索引
        function getObjectIndex(rows,row) {
            for (var i = 0, _2 = rows.length; i < _2; i++) {
                if (rows[i] ==row) {
                    return i;
                }
            }
            return -1;
        };
        //传递数据
        function transferData(rows,row) {
            var index = getObjectIndex(rows,row);
            if (index != -1) {
                rows.splice(index, 1);
            }
        };
        //初始化函数
        function initGrid(jq) {
            var options = $.data(jq, "treegrid").options;
            //初始化表格 具体参考datagrid属性、事件
            $(jq).datagrid($.extend({}, options, {
                url: null,
                data: null,
                loader: function () {
                    return false;
                },
                onLoadSuccess: function () {
                },
                onResizeColumn: function (field, width) {
                    _setRowHeight(jq);
                    options.onResizeColumn.call(jq, field, width);
                },
                onSortColumn: function (sortName, sortName) {
                    options.sortName = sortName;
                    options.sortOrder = sortName;
                    if (options.remoteSort) {
                        request(jq);
                    } else {
                        var data = $(jq).treegrid("getData");
                        _loadData(jq, 0, data);
                    }
                    options.onSortColumn.call(jq, sortName, sortName);
                },
    
                onBeforeEdit: function (rowIndex, rowData) {
                    if (options.onBeforeEdit.call(jq, rowData) == false) {
                        return false;
                    }
                },
                onAfterEdit: function (rowIndex, row, newValues) {
                    options.onAfterEdit.call(jq, row, newValues);
                },
                onCancelEdit: function (rowIndex, row) {
                    options.onCancelEdit.call(jq, row);
                },
                onSelect: function (parm) {
                    options.onSelect.call(jq, find(jq, parm));
                },
                onUnselect: function (parm) {
                    options.onUnselect.call(jq, find(jq, parm));
                },
                onSelectAll: function () {
                    options.onSelectAll.call(jq, $.data(jq, "treegrid").data);
                },
                onUnselectAll: function () {
                    options.onUnselectAll.call(jq, $.data(jq, "treegrid").data);
                },
                onCheck: function (parm) {
                    options.onCheck.call(jq, find(jq, parm));
                },
                onUncheck: function (parm) {
                    options.onUncheck.call(jq, find(jq, parm));
                },
                onCheckAll: function () {
                    options.onCheckAll.call(jq, $.data(jq, "treegrid").data);
                },
                onUncheckAll: function () {
                    options.onUncheckAll.call(jq, $.data(jq, "treegrid").data);
                },
                onClickRow: function (parm) {
                    options.onClickRow.call(jq, find(jq, parm));
                },
                onDblClickRow: function (parm) {
                    options.onDblClickRow.call(jq, find(jq, parm));
                },
                onClickCell: function (id, field) {
                    options.onClickCell.call(jq, field, find(jq, id));
                },
                onDblClickCell: function (id, parm) {
                    options.onDblClickCell.call(jq, parm, find(jq, id));
                },
                onRowContextMenu: function (e, id) {
                    options.onContextMenu.call(jq, e, find(jq, id));
                }
            }));
            if (options.pagination) {
                var getPager = $(jq).datagrid("getPager");
                getPager.pagination({
                    pageNumber: options.pageNumber,
                    pageSize: options.pageSize,
                    pageList: options.pageList,
                    onSelectPage: function (pageNumber, pageNumber) {
                        options.pageNumber = pageNumber;
                        options.pageSize = pageNumber;
                        request(jq);
                    }
                });
                options.pageSize = getPager.pagination("options").pageSize;
            }
        };
        //修正指定的行高
        function _setRowHeight(jq, id) {
            var options = $.data(jq, "datagrid").options;
            var dc = $.data(jq, "datagrid").dc;
            if (!dc.body1.is(":empty") && (!options.nowrap || options.autoRowHeight)) {
                if (id != undefined) {
                    var children = _getChildren(jq, id);
                    for (var i = 0; i < children.length; i++) {
                        setRowHeight(children[i][options.idField]);
                    }
                }
            }
            $(jq).datagrid("fixRowHeight", id);
    
            function setRowHeight(_28) {
                var tr1 = options.finder.getTr(jq, _28, "body", 1);
                var tr2 = options.finder.getTr(jq, _28, "body", 2);
                tr1.css("height", "");
                tr2.css("height", "");
                var maxheight = Math.max(tr1.height(), tr2.height());
                tr1.css("height", maxheight);
                tr2.css("height", maxheight);
            };
        };
        //设置行序号
        function fixRowNumbers(jq) {
            var dc = $.data(jq, "datagrid").dc;
            var options = $.data(jq, "treegrid").options;
            if (!options.rownumbers) {
                return;
            }
            dc.body1.find("div.datagrid-cell-rownumber").each(function (i) {
                $(this).html(i + 1);
            });
        };
        //绑定事件
        function bindEvents(jq) {
            var dc = $.data(jq, "datagrid").dc;
            var body = dc.body1.add(dc.body2);
            var handler = ($.data(body[0], "events") || $._data(body[0], "events")).click[0].handler;
            dc.body1.add(dc.body2).bind("mouseover", function (e) {//当鼠标移上时
                var tt = $(e.target);
                var tr = tt.closest("tr.datagrid-row");
                if (!tr.length) {
                    return;
                }
                if (tt.hasClass("tree-hit")) {
                    tt.hasClass("tree-expanded") ? tt.addClass("tree-expanded-hover") : tt.addClass("tree-collapsed-hover");
                }
                e.stopPropagation();
            }).bind("mouseout", function (e) {//dang鼠标离开时
                var tt = $(e.target);
                var tr = tt.closest("tr.datagrid-row");
                if (!tr.length) {
                    return;
                }
                if (tt.hasClass("tree-hit")) {
                    tt.hasClass("tree-expanded") ? tt.removeClass("tree-expanded-hover") : tt.removeClass("tree-collapsed-hover");
                }
                e.stopPropagation();
            }).unbind("click").bind("click", function (e) {//触发点击事件
                var tt = $(e.target);
                var tr = tt.closest("tr.datagrid-row");
                if (!tr.length) {
                    return;
                }
                if (tt.hasClass("tree-hit")) {
                    _toggle(jq, tr.attr("node-id"));
                } else {
                    handler(e);
                }
                e.stopPropagation();
            });
        };
    
        function initSubTree(jq, nodeId) {
            var options = $.data(jq, "treegrid").options;
            var tr1 = options.finder.getTr(jq, nodeId, "body", 1);
            var tr2 = options.finder.getTr(jq, nodeId, "body", 2);
            //getColumnFields返回列字段。如果设置了frozen属性为true,将返回固定列的字段名
            var colspan1 = $(jq).datagrid("getColumnFields", true).length + (options.rownumbers ? 1 : 0);
            var colspan2 = $(jq).datagrid("getColumnFields", false).length;
            createSubTree(tr1, colspan1);
            createSubTree(tr2, colspan2);
            function createSubTree(tr, colspan) {
                $("<tr class="treegrid-tr-tree">" + "<td style="border:0px" colspan="" + colspan + "">" + "<div></div>" + "</td>" + "</tr>").insertAfter(tr);
            };
        };
        //读取树形表格数据
        function _loadData(jq, nodeId, param, param) {
            var options = $.data(jq, "treegrid").options;
            var dc = $.data(jq, "datagrid").dc;
            param = options.loadFilter.call(jq, param, nodeId);
            var row = find(jq, nodeId);
            if (row) {
                var tr1 = options.finder.getTr(jq, nodeId, "body", 1);
                var tr2 = options.finder.getTr(jq, nodeId, "body", 2);
                var cc1 = tr1.next("tr.treegrid-tr-tree").children("td").children("div");
                var cc2 = tr2.next("tr.treegrid-tr-tree").children("td").children("div");
            } else {
                var cc1 = dc.body1;
                var cc2 = dc.body2;
            }
            if (!param) {
                $.data(jq, "treegrid").data = [];
                cc1.empty();
                cc2.empty();
            }
            if (options.view.onBeforeRender) {
                options.view.onBeforeRender.call(options.view, jq, nodeId, param);
            }
            options.view.render.call(options.view, jq, cc1, true);
            options.view.render.call(options.view, jq, cc2, false);
            if (options.showFooter) {
                options.view.renderFooter.call(options.view, jq, dc.footer1, true);
                options.view.renderFooter.call(options.view, jq, dc.footer2, false);
            }
            if (options.view.onAfterRender) {
                options.view.onAfterRender.call(options.view, jq);
            }
            options.onLoadSuccess.call(jq, row, param);
            if (!nodeId && options.pagination) {
                var total = $.data(jq, "treegrid").total;
                var getPager = $(jq).datagrid("getPager");
                if (getPager.pagination("options").total != total) {
                    getPager.pagination({ total: total });
                }
            }
            _setRowHeight(jq);
            fixRowNumbers(jq);
            $(jq).treegrid("autoSizeColumn");
        };
    
        function request(jq, parentId, param, isAppend, callBack) {
            var options = $.data(jq, "treegrid").options;
            var body = $(jq).datagrid("getPanel").find("div.datagrid-body");
            if (param) {
                options.queryParams = param;
            }
            var queryParams = $.extend({}, options.queryParams);
            if (options.pagination) {
                $.extend(queryParams, { page: options.pageNumber, rows: options.pageSize });
            }
            if (options.sortName) {
                $.extend(queryParams, { sort: options.sortName, order: options.sortOrder });
            }
            var row = find(jq, parentId);
            if (options.onBeforeLoad.call(jq, row, queryParams) == false) {
                return;
            }
            var folder = body.find("tr[node-id=" + parentId + "] span.tree-folder");
            folder.addClass("tree-loading");
            $(jq).treegrid("loading");
            var loaded = options.loader.call(jq, queryParams, function (parm) {
                folder.removeClass("tree-loading");
                $(jq).treegrid("loaded");
                _loadData(jq, parentId, parm, isAppend);
                if (callBack) {
                    callBack();
                }
            }, function () {
                folder.removeClass("tree-loading");
                $(jq).treegrid("loaded");
                options.onLoadError.apply(jq, arguments);
                if (callBack) {
                    callBack();
                }
            });
            if (loaded == false) {
                folder.removeClass("tree-loading");
                $(jq).treegrid("loaded");
            }
        };
        //获取根节点,返回节点对象
        function _getRoot(target) {
            var roots = _getRoots(target);
            if (roots.length) {
                return roots[0];
            } else {
                return null;
            }
        };
        //获取所有根节点,返回节点对象
        function _getRoots(target) {
            return $.data(target, "treegrid").data;
        };
        //获取父节点。
        function _getParent(jq, id) {
            var row = find(jq, id);
            if (row._parentId) {
                return find(jq, row._parentId);
            } else {
                return null;
            }
        };
        //获取子节点
        function _getChildren(jq, id) {
            var options = $.data(jq, "treegrid").options;
            var body = $(jq).datagrid("getPanel").find("div.datagrid-view2 div.datagrid-body");
            var children = [];
            if (id) {
                findChildren(id);
            } else {
                var roots = _getRoots(jq);
                for (var i = 0; i < roots.length; i++) {
                    children.push(roots[i]);
                    findChildren(roots[i][options.idField]);
                }
            }
            function findChildren(id) {
                var node = find(jq, id);
                if (node && node.children) {
                    for (var i = 0, len = node.children.length; i < len; i++) {
                        var child = node.children[i];
                        children.push(child);
                        findChildren(child[options.idField]);
                    }
                }
            };
            return children;
        };
        //获取选择的节点并返回它,如果没有节点被选中则返回null
        function _getSelected(jq) {
            var target = _getSelections(jq);
            if (target.length) {
                return target[0];
            } else {
                return null;
            }
        };
        //获取所有选择的节点。
        function _getSelections(jq) {
            var selectedRows = [];
            var panel = $(jq).datagrid("getPanel");
            panel.find("div.datagrid-view2 div.datagrid-body tr.datagrid-row-selected").each(function () {
                var id = $(this).attr("node-id");
                selectedRows.push(find(jq, id));
            });
            return selectedRows;
        };
        //获取指定节点等级。
        function _getLevel(jq, id) {
            if (!id) {
                return 0;
            }
            var options = $.data(jq, "treegrid").options;
            var gridView = $(jq).datagrid("getPanel").children("div.datagrid-view");
            var treeNode = gridView.find("div.datagrid-body tr[node-id=" + id + "]").children("td[field=" + options.treeField + "]");
            return treeNode.find("span.tree-indent,span.tree-hit").length;
        };
        //查找指定节点并返回节点数据。
        function find(jq, id) {
            var options = $.data(jq, "treegrid").options;
            var data = $.data(jq, "treegrid").data;
            var cc = [data];
            while (cc.length) {
                var c = cc.shift();
                for (var i = 0; i < c.length; i++) {
                    var rowData = c[i];
                    if (rowData[options.idField] == id) {
                        return rowData;
                    } else {
                        if (rowData["children"]) {
                            cc.push(rowData["children"]);
                        }
                    }
                }
            }
            return null;
        };
        //折叠一个节点。
        function _collapse(jq, id) {
            var options = $.data(jq, "treegrid").options;
            var row = find(jq, id);
            var tr = options.finder.getTr(jq, id);
            var hit = tr.find("span.tree-hit");
            if (hit.length == 0) {
                return;
            }
            if (hit.hasClass("tree-collapsed")) {
                return;
            }
            if (options.onBeforeCollapse.call(jq, row) == false) {
                return;
            }
            hit.removeClass("tree-expanded tree-expanded-hover").addClass("tree-collapsed");
            hit.next().removeClass("tree-folder-open");
            row.state = "closed";
            tr = tr.next("tr.treegrid-tr-tree");
            var cc = tr.children("td").children("div");
            if (options.animate) {
                cc.slideUp("normal", function () {
                    $(jq).treegrid("autoSizeColumn");
                    _setRowHeight(jq, id);
                    options.onCollapse.call(jq, row);
                });
            } else {
                cc.hide();
                $(jq).treegrid("autoSizeColumn");
                _setRowHeight(jq, id);
                options.onCollapse.call(jq, row);
            }
        };
        //展开一个节点。
        function expand(jq, id) {
            var options = $.data(jq, "treegrid").options;
            var tr = options.finder.getTr(jq, id);
            var hit = tr.find("span.tree-hit");
            var row = find(jq, id);
            if (hit.length == 0) {
                return;
            }
            if (hit.hasClass("tree-expanded")) {
                return;
            }
            if (options.onBeforeExpand.call(jq, row) == false) {
                return;
            }
            hit.removeClass("tree-collapsed tree-collapsed-hover").addClass("tree-expanded");
            hit.next().addClass("tree-folder-open");
            var subtree = tr.next("tr.treegrid-tr-tree");
            if (subtree.length) {
                var cc = subtree.children("td").children("div");
                expandSubtree(cc);
            } else {
                initSubTree(jq, row[options.idField]);
                var subtree = tr.next("tr.treegrid-tr-tree");
                var cc = subtree.children("td").children("div");
                cc.hide();
                request(jq, row[options.idField], { id: row[options.idField] }, true, function () {
                    if (cc.is(":empty")) {
                        subtree.remove();
                    } else {
                        expandSubtree(cc);
                    }
                });
            }
            function expandSubtree(cc) {
                row.state = "open";
                if (options.animate) {
                    cc.slideDown("normal", function () {
                        $(jq).treegrid("autoSizeColumn");
                        _setRowHeight(jq, id);
                        options.onExpand.call(jq, row);
                    });
                } else {
                    cc.show();
                    $(jq).treegrid("autoSizeColumn");
                    _setRowHeight(jq, id);
                    options.onExpand.call(jq, row);
                }
            };
        };
        //节点展开/折叠状态触发器
        function _toggle(jq, id) {
            var options = $.data(jq, "treegrid").options;
            var tr = options.finder.getTr(jq, id);
            var hit = tr.find("span.tree-hit");
            if (hit.hasClass("tree-expanded")) {
                _collapse(jq, id);
            } else {
                expand(jq, id);
            }
        };
        //折叠所有节点。
        function _collapseAll(jq, id) {
            var options = $.data(jq, "treegrid").options;
            var children = _getChildren(jq, id);
            if (id) {
                children.unshift(find(jq, id));
            }
            for (var i = 0; i < children.length; i++) {
                _collapse(jq, children[i][options.idField]);
            }
        };
        //展开所有节点。
        function _expandAll(jq, jq) {
            var options = $.data(jq, "treegrid").options;
            var children = _getChildren(jq, jq);
            if (jq) {
                children.unshift(find(jq, jq));
            }
            for (var i = 0; i < children.length; i++) {
                expand(jq, children[i][options.idField]);
            }
        };
        //打开从根节点到指定节点之间的所有节点。
        function _expandTo(jq, id) {
            var options = $.data(jq, "treegrid").options;
            var ids = [];
            var p = _getParent(jq, id);
            while (p) {
                var id = p[options.idField];
                ids.unshift(id);
                p = _getParent(jq, id);
            }
            for (var i = 0; i < ids.length; i++) {
                expand(jq, ids[i]);
            }
        };
        //追加节点到一个父节点,'param'参数包含如下属性:
        //parent:父节点ID,如果未指定则追加到根节点。
        //data:数组,节点数据。
        function _append(jq, param) {
            var options = $.data(jq, "treegrid").options;
            if (param.parent) {
                var tr = options.finder.getTr(jq, param.parent);
                if (tr.next("tr.treegrid-tr-tree").length == 0) {
                    initSubTree(jq, param.parent);
                }
                var cell = tr.children("td[field=" + options.treeField + "]").children("div.datagrid-cell");
                var icon = cell.children("span.tree-icon");
                if (icon.hasClass("tree-file")) {
                    icon.removeClass("tree-file").addClass("tree-folder");
                    var hit = $("<span class="tree-hit tree-expanded"></span>").insertBefore(icon);
                    if (hit.prev().length) {
                        hit.prev().remove();
                    }
                }
            }
            _loadData(jq, param.parent, param.data, true);
        };
        //插入一个新节点到指定节点。'param'参数包含一下参数:
        //before:插入指定节点ID值之前。
        //after:插入指定节点ID值之后。
        //data:新节点数据。 
        function insert(jq, param) {
            var ref = param.before || param.after;
            var options = $.data(jq, "treegrid").options;
            var parentn = _getParent(jq, ref);
            _append(jq, { parent: (parentn ? parentn[options.idField] : null), data: [param.data] });
            _insert(true);
            _insert(false);
            fixRowNumbers(jq);
            //插入数据
            function _insert(before) {
                var step = before ? 1 : 2;
                var tr = options.finder.getTr(jq, param.data[options.idField], "body", step);
                var btable = tr.closest("table.datagrid-btable");//序号列
                tr = tr.parent().children();
                var tr = options.finder.getTr(jq, ref, "body", step);
                if (param.before) {
                    tr.insertBefore(tr);
                } else {
                    var sub = tr.next("tr.treegrid-tr-tree");
                    tr.insertAfter(sub.length ? sub : tr);
                }
                btable.remove();
            };
        };
        //移除一个节点和他的所有子节点。
        function _remove(jq, nodeId) {
            var options = $.data(jq, "treegrid").options;
            var tr = options.finder.getTr(jq, nodeId);
            tr.next("tr.treegrid-tr-tree").remove();
            tr.remove();
            var parent = del(nodeId);
            if (parent) {
                if (parent.children.length == 0) {
                    tr = options.finder.getTr(jq, parent[options.idField]);
                    tr.next("tr.treegrid-tr-tree").remove();
                    var cell = tr.children("td[field=" + options.treeField + "]").children("div.datagrid-cell");
                    cell.find(".tree-icon").removeClass("tree-folder").addClass("tree-file");
                    cell.find(".tree-hit").remove();
                    $("<span class="tree-indent"></span>").prependTo(cell);
                }
            }
            fixRowNumbers(jq);
            function del(id) {
                var cc;
                var parent = _getParent(jq, nodeId);
                if (parent) {
                    cc = parent.children;
                } else {
                    cc = $(jq).treegrid("getData");
                }
                for (var i = 0; i < cc.length; i++) {
                    if (cc[i][options.idField] == id) {
                        cc.splice(i, 1);
                        break;
                    }
                }
                return parent;
            };
        };
        //实例化组建
        $.fn.treegrid = function (target, parm) {
            if (typeof target == "string") {
                var method = $.fn.treegrid.methods[target];
                if (method) {
                    return method(this, parm);
                } else {
                    return this.datagrid(target, parm);
                }
            }
            target = target || {};
            return this.each(function () {
                var treegrid = $.data(this, "treegrid");
                if (treegrid) {
                    $.extend(treegrid.options, target);
                } else {
                    treegrid = $.data(this, "treegrid", { options: $.extend({}, $.fn.treegrid.defaults, $.fn.treegrid.parseOptions(this), target), data: [] });
                }
                initGrid(this);
                if (treegrid.options.data) {
                    $(this).treegrid("loadData", treegrid.options.data);
                }
                request(this);
                bindEvents(this);
            });
        };
        //默认方法
        $.fn.treegrid.methods = {
            //返回树形表格的属性
            options: function (jq) {
                return $.data(jq[0], "treegrid").options;
            },
            //设置树形表格大小,options包含2个属性:
            //width:树形表格的新宽度。
            //height:树形表格的新高度。
            resize: function (jq, options) {
                return jq.each(function () {
                    $(this).datagrid("resize", options);
                });
            },
            //修正指定的行高
            fixRowHeight: function (jq, id) {
                return jq.each(function () {
                    _setRowHeight(this, id);
                });
            },
            //读取树形表格数据
            loadData: function (jq, data) {
                return jq.each(function () {
                    _loadData(this, null, data);
                });
            },
            //重新加载树形表格数据。如果'id'属性有值,将重新载入指定树形行,否则重新载入所有行
            reload: function (jq, id) {
                return jq.each(function () {
                    if (id) {
                        var record = $(this).treegrid("find", id);
                        if (record.children) {
                            record.children.splice(0, record.children.length);
                        }
                        var gridBody = $(this).datagrid("getPanel").find("div.datagrid-body");
                        var tr = gridBody.find("tr[node-id=" + id + "]");
                        tr.next("tr.treegrid-tr-tree").remove();
                        var hit = tr.find("span.tree-hit");
                        hit.removeClass("tree-expanded tree-expanded-hover").addClass("tree-collapsed");
                        expand(this, id);
                    } else {
                        request(this, null, {});
                    }
                });
            },
            //重新载入页脚数据
            reloadFooter: function (jq, footer) {
                return jq.each(function () {
                    var options = $.data(this, "treegrid").options;
                    var dc = $.data(this, "datagrid").dc;
                    if (footer) {
                        $.data(this, "treegrid").footer = footer;
                    }
                    if (options.showFooter) {
                        options.view.renderFooter.call(options.view, this, dc.footer1, true);
                        options.view.renderFooter.call(options.view, this, dc.footer2, false);
                        if (options.view.onAfterRender) {
                            options.view.onAfterRender.call(options.view, this);
                        }
                        $(this).treegrid("fixRowHeight");
                    }
                });
            },
            //获取载入数据
            getData: function (jq) {
                return $.data(jq[0], "treegrid").data;
            },
            //获取页脚数据
            getFooterRows: function (jq) {
                return $.data(jq[0], "treegrid").footer;
            },
            //获取根节点,返回节点对象
            getRoot: function (jq) {
                return _getRoot(jq[0]);
            },
            //获取所有根节点,返回节点数组
            getRoots: function (jq) {
                return _getRoots(jq[0]);
            },
            //获取父节点。
            getParent: function (jq, id) {
                return _getParent(jq[0], id);
            },
            //获取子节点
            getChildren: function (jq, id) {
                return _getChildren(jq[0], id);
            },
            //获取选择的节点并返回它,如果没有节点被选中则返回null。
            getSelected: function (jq) {
                return _getSelected(jq[0]);
            },
            //获取所有选择的节点。
            getSelections: function (jq) {
                return _getSelections(jq[0]);
            },
            //获取指定节点等级
            getLevel: function (jq, id) {
                return _getLevel(jq[0], id);
            },
            //查找指定节点并返回节点数据
            find: function (jq, id) {
                return find(jq[0], id);
            },
            //判断是否是子节点
            isLeaf: function (jq, id) {
                var options = $.data(jq[0], "treegrid").options;
                var tr = options.finder.getTr(jq[0], id);
                var hit = tr.find("span.tree-hit");
                return hit.length == 0;
            },
            //选择一个节点。
            select: function (jq, id) {
                return jq.each(function () {
                    $(this).datagrid("selectRow", id);
                });
            },
            //反选一个节点。
            unselect: function (jq, id) {
                return jq.each(function () {
                    $(this).datagrid("unselectRow", id);
                });
            },
            //折叠一个节点。
            collapse: function (jq, id) {
                return jq.each(function () {
                    _collapse(this, id);
                });
            },
            //展开一个节点。
            expand: function (jq, id) {
                return jq.each(function () {
                    expand(this, id);
                });
            },
            //节点展开/折叠状态触发器。
            toggle: function (jq, id) {
                return jq.each(function () {
                    _toggle(this, id);
                });
            },
            //折叠所有节点。
            collapseAll: function (jq, id) {
                return jq.each(function () {
                    _collapseAll(this, id);
                });
            },
            //展开所有节点。
            expandAll: function (jq, id) {
                return jq.each(function () {
                    _expandAll(this, id);
                });
            },
            //打开从根节点到指定节点之间的所有节点
            expandTo: function (jq, id) {
                return jq.each(function () {
                    _expandTo(this, id);
                });
            },
            //追加节点到一个父节点,'param'参数包含如下属性:
            //parent:父节点ID,如果未指定则追加到根节点。
            //data:数组,节点数据。
            append: function (jq, param) {
                return jq.each(function () {
                    _append(this, param);
                });
            },
            //插入一个新节点到指定节点。'param'参数包含一下参数:
            //before:插入指定节点ID值之前。
            //after:插入指定节点ID值之后。
            //data:新节点数据       
            insert: function (jq, param) {
                return jq.each(function () {
                    insert(this, param);
                });
            }, 
            //移除一个节点和他的所有子节点。
            remove: function (jq, id) {
                return jq.each(function () {
                    _remove(this, id);
                });
            },
            //弹出并返回节点数据以及它的子节点之后删除
            pop: function (jq, id) {
                var row = jq.treegrid("find", id);
                jq.treegrid("remove", id);
                return row;
            },
            //刷新指定节点
            refresh: function (jq, id) {
                return jq.each(function () {
                    var options = $.data(this, "treegrid").options;
                    options.view.refreshRow.call(options.view, this, id);
                });
            },
            //options更新指定节点。'param'参数包含以下属性:
            //id:要更新的节点的ID。
            //row:新的行数据
            update: function (jq, param) {
                return jq.each(function () {
                    var options = $.data(this, "treegrid").options;
                    options.view.updateRow.call(options.view, this, param.id, param.row);
                });
            },
            //开始编辑一个节点
            beginEdit: function (jq, id) {
                return jq.each(function () {
                    $(this).datagrid("beginEdit", id);
                    $(this).treegrid("fixRowHeight", id);
                });
            },
            //结束编辑一个节点
            endEdit: function (jq, id) {
                return jq.each(function () {
                    $(this).datagrid("endEdit", id);
                });
            },
            //取消编辑一个节点。
            cancelEdit: function (jq, id) {
                return jq.each(function () {
                    $(this).datagrid("cancelEdit", id);
                });
            }
        };
        //解析器配置
        $.fn.treegrid.parseOptions = function (target) {
            return $.extend({}, $.fn.datagrid.parseOptions(target),
                $.parser.parseOptions(target, ["treeField", { animate: "boolean" }]));
        };
        //定义数据表格的视图 该视图是一个对象,将告诉数据表格如何渲染行。该对象必须定义下列函
        var _view = $.extend({}, $.fn.datagrid.defaults.view, {
            //    数据加载时调用。
            //jq:DOM对象,数据表格对象。
            //container:行容器。
            //frozen:指明如何渲染冻结容器。
            render: function (jq, container, frozen) {
                var options = $.data(jq, "treegrid").options;
                var fields = $(jq).datagrid("getColumnFields", frozen);
                var rowIdPrefix = $.data(jq, "datagrid").rowIdPrefix;
                if (frozen) {
                    if (!(options.rownumbers || (options.frozenColumns && options.frozenColumns.length))) {
                        return;
                    }
                }
                var grid = this;
                var nodes = buildTreeNodes(frozen, this.treeLevel, this.treeNodes);
                $(container).append(nodes.join(""));
                //创建树节点
                function buildTreeNodes(frozen, treeLevel, rows) {
                    var html = ["<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>"];
                    for (var i = 0; i < rows.length; i++) {
                        var row = rows[i];
                        if (row.state != "open" && row.state != "closed") {
                            row.state = "open";
                        }
                        var style = options.rowStyler ? options.rowStyler.call(jq, row) : "";
                        var attr = style ? "style="" + style + """ : "";
                        var rowid = rowIdPrefix + "-" + (frozen ? 1 : 2) + "-" + row[options.idField];
                        html.push("<tr id="" + rowid + "" class="datagrid-row" node-id=" + row[options.idField] + " " + attr + ">");
                        html = html.concat(grid.renderRow.call(grid, jq, fields, frozen, treeLevel, row));
                        html.push("</tr>");
                        if (row.children && row.children.length) {
                            var tt = buildTreeNodes(frozen, treeLevel + 1, row.children);
                            var v = row.state == "closed" ? "none" : "block";
                            html.push("<tr class="treegrid-tr-tree"><td style="border:0px" colspan="
                                + (fields.length + (options.rownumbers ? 1 : 0))
                                + "><div style="display:"
                                + v + "">");
                            html = html.concat(tt);
                            html.push("</div></td></tr>");
                        }
                    }
                    html.push("</tbody></table>");
                    return html;
                };
            },
            //渲染底部
            renderFooter: function (jq, grid, frozen) {
                var options = $.data(jq, "treegrid").options;
                var footer = $.data(jq, "treegrid").footer || [];
                var fields = $(jq).datagrid("getColumnFields", frozen);
                var html = ["<table class="datagrid-ftable" cellspacing="0" cellpadding="0" border="0"><tbody>"];
                for (var i = 0; i < footer.length; i++) {
                    var row = footer[i];
                    row[options.idField] = row[options.idField] || ("foot-row-id" + i);
                    html.push("<tr class="datagrid-row" node-id=" + row[options.idField] + ">");
                    html.push(this.renderRow.call(this, jq, fields, frozen, 0, row));
                    html.push("</tr>");
                }
                html.push("</tbody></table>");
                $(grid).html(html.join(""));
            },
            //渲染行
            renderRow: function (jq, fields, frozen, deepth, row) {
                var opts = $.data(jq, "treegrid").options;
                var cc = [];
                if (frozen && opts.rownumbers) {
                    cc.push("<td class="datagrid-td-rownumber"><div class="datagrid-cell-rownumber">0</div></td>");
                }
                for (var i = 0; i < fields.length; i++) {
                    var field = fields[i];
                    var col = $(jq).datagrid("getColumnOption", field);
                    if (col) {
                        var style = col.styler ? (col.styler(row[field], row) || "") : "";
                        var style2 = col.hidden ? "style="display:none;" + style + """ : (style ? "style="" + style + """ : "");
                        cc.push("<td field="" + field + "" " + style2 + ">");
                        if (col.checkbox) {
                            var style2 = "";
                        } else {
                            var style2 = "";
                            if (col.align) {
                                style2 += "text-align:" + col.align + ";";
                            }
                            if (!opts.nowrap) {
                                style2 += "white-space:normal;height:auto;";
                            } else {
                                if (opts.autoRowHeight) {
                                    style2 += "height:auto;";
                                }
                            }
                        }
                        cc.push("<div style="" + style2 + "" ");
                        if (col.checkbox) {
                            cc.push("class="datagrid-cell-check ");
                        } else {
                            cc.push("class="datagrid-cell " + col.cellClass);
                        }
                        cc.push("">");
                        if (col.checkbox) {
                            if (row.checked) {
                                cc.push("<input type="checkbox" checked="checked"");
                            } else {
                                cc.push("<input type="checkbox"");
                            }
                            cc.push(" name="" + field + "" value="" + (row[field] != undefined ? row[field] : "") + ""/>");
                        } else {
                            var val = null;
                            if (col.formatter) {
                                val = col.formatter(row[field], row);
                            } else {
                                val = row[field];
                            }
                            if (field == opts.treeField) {
                                for (var j = 0; j < deepth; j++) {
                                    cc.push("<span class="tree-indent"></span>");
                                }
                                if (row.state == "closed") {
                                    cc.push("<span class="tree-hit tree-collapsed"></span>");
                                    cc.push("<span class="tree-icon tree-folder " + (row.iconCls ? row.iconCls : "") + ""></span>");
                                } else {
                                    if (row.children && row.children.length) {
                                        cc.push("<span class="tree-hit tree-expanded"></span>");
                                        cc.push("<span class="tree-icon tree-folder tree-folder-open " + (row.iconCls ? row.iconCls : "") + ""></span>");
                                    } else {
                                        cc.push("<span class="tree-indent"></span>");
                                        cc.push("<span class="tree-icon tree-file " + (row.iconCls ? row.iconCls : "") + ""></span>");
                                    }
                                }
                                cc.push("<span class="tree-title">" + val + "</span>");
                            } else {
                                cc.push(val);
                            }
                        }
                        cc.push("</div>");
                        cc.push("</td>");
                    }
                }
                return cc.join("");
            },
            //刷新行
            refreshRow: function (target, id) {
                this.updateRow.call(this, target, id, {});
            },
            //更新行
            updateRow: function (jq, id, row) {
                var options = $.data(jq, "treegrid").options;
                var row2 = $(jq).treegrid("find", id);
                $.extend(row2, row);
                var Level = $(jq).treegrid("getLevel", id) - 1;//获取指定节点等级。
                var style2 = options.rowStyler ? options.rowStyler.call(jq, row2) : "";
                function setFieldsCheck(frozen) { //设置字段选中
                    var _e1 = $(jq).treegrid("getColumnFields", frozen);
                    var tr = options.finder.getTr(jq, id, "body", (frozen ? 1 : 2));
                    var rownumber = tr.find("div.datagrid-cell-rownumber").html();
                    var checkb = tr.find("div.datagrid-cell-check input[type=checkbox]").is(":checked");
                    tr.html(this.renderRow(jq, _e1, frozen, Level, row2));
                    tr.attr("style", style2 || "");
                    tr.find("div.datagrid-cell-rownumber").html(rownumber);
                    if (checkb) {
                        tr.find("div.datagrid-cell-check input[type=checkbox]")._propAttr("checked", true);//设置选择
                    }
                };
                setFieldsCheck.call(this, true);
                setFieldsCheck.call(this, false);
                $(jq).treegrid("fixRowHeight", id);
            },
            //在视图被呈现之前触发
            onBeforeRender: function (jq, nodeId, nodeId) {
                if (!nodeId) {
                    return false;
                }
                var options = $.data(jq, "treegrid").options;
                if (nodeId.length == undefined) {
                    if (nodeId.footer) {
                        $.data(jq, "treegrid").footer = nodeId.footer;
                    }
                    if (nodeId.total) {
                        $.data(jq, "treegrid").total = nodeId.total;
                    }
                    nodeId = this.transfer(jq, nodeId, nodeId.rows);
                } else {
                    function setParent(param, nodeId) {
                        for (var i = 0; i < param.length; i++) {
                            var row = param[i];
                            row._parentId = nodeId;
                            if (row.children && row.children.length) {
                                setParent(row.children, row[options.idField]);
                            }
                        }
                    };
                    setParent(nodeId, nodeId);
                }
                var node = find(jq, nodeId);
                if (node) {
                    if (node.children) {
                        node.children = node.children.concat(nodeId);
                    } else {
                        node.children = nodeId;
                    }
                } else {
                    $.data(jq, "treegrid").data = $.data(jq, "treegrid").data.concat(nodeId);
                }
                if (!options.remoteSort) {
                    this.sort(jq, nodeId);
                }
                this.treeNodes = nodeId;
                this.treeLevel = $(jq).treegrid("getLevel", nodeId);
            },
            //排序
            sort: function (jq, param) {
                var options = $.data(jq, "treegrid").options;
                var opt = $(jq).treegrid("getColumnOption", options.sortName);
                if (opt) {
                    var sorter = opt.sorter || function (rows, b) {
                        return (rows > b ? 1 : -1);
                    };
                    _sorter(param);
                }
                function _sorter(param) {
                    param.sort(function (r1, r2) {
                        return sorter(r1[options.sortName], r2[options.sortName]) * (options.sortOrder == "asc" ? 1 : -1);
                    });
                    for (var i = 0; i < param.length; i++) {
                        var children = param[i].children;
                        if (children && children.length) {
                            _sorter(children);
                        }
                    }
                };
            },
    
            transfer: function (jq, nodeId, data) {
                var options = $.data(jq, "treegrid").options;
                var rows = [];
                for (var i = 0; i < data.length; i++) {
                    rows.push(data[i]);
                }
                var children = [];
                for (var i = 0; i < rows.length; i++) {
                    var row = rows[i];
                    if (!nodeId) {
                        if (!row._parentId) {
                            children.push(row);
                            transferData(rows, row);
                            i--;
                        }
                    } else {
                        if (row._parentId == nodeId) {
                            children.push(row);
                            transferData(rows, row);
                            i--;
                        }
                    }
                }
                var toDo = [];
                for (var i = 0; i < children.length; i++) {
                    toDo.push(children[i]);
                }
                while (toDo.length) {
                    var node = toDo.shift();
                    for (var i = 0; i < rows.length; i++) {
                        var row = rows[i];
                        if (row._parentId == node[options.idField]) {
                            if (node.children) {
                                node.children.push(row);
                            } else {
                                node.children = [row];
                            }
                            toDo.push(row);
                            transferData(rows, row);
                            i--;
                        }
                    }
                }
                return children;
            }
        });
        //默认属性和事件 继承datagrid
        $.fn.treegrid.defaults = $.extend({}, $.fn.datagrid.defaults, {
            treeField: null,//定义树节点字段。
            animate: false,//定义在节点展开或折叠的时候是否显示动画效果
            singleSelect: true,//单选
            view: _view,//定义数据表格的视图
            //定义以何种方式从远程服务器读取数据。返回false可以忽略该动作。该函数具有一下参数:
            //param:传递到远程服务器的参数对象。
            //success(data):当检索数据成功的时候调用的回调函数。
            //error():当检索数据失败的时候调用的回调函数。
            loader: function (param, success, error) {
                var options = $(this).treegrid("options");
                if (!options.url) {
                    return false;
                }
                $.ajax({
                    type: options.method,
                    url: options.url,
                    data: param,
                    dataType: "json",
                    success: function (data) {
                        success(data);
                    }, error: function () {
                        error.apply(this, arguments);
                    }
                });
            },
            //返回过滤后的数据进行展示
            loadFilter: function (data, parentId) {
                return data;
            },
    
            finder: {
    
                getTr: function (jq, id, type, step) {
                    type = type || "body";
                    step = step || 0;
                    var dc = $.data(jq, "datagrid").dc;
                    if (step == 0) {
                        var opts = $.data(jq, "treegrid").options;
                        var tr1 = opts.finder.getTr(jq, id, type, 1);
                        var tr2 = opts.finder.getTr(jq, id, type, 2);
                        return tr1.add(tr2);
                    } else {
                        if (type == "body") {
                            var tr = $("#" + $.data(jq, "datagrid").rowIdPrefix + "-" + step + "-" + id);
                            if (!tr.length) {
                                tr = (step == 1 ? dc.body1 : dc.body2).find("tr[node-id=" + id + "]");
                            }
                            return tr;
                        } else {
                            if (type == "footer") {
                                return (step == 1 ? dc.footer1 : dc.footer2).find("tr[node-id=" + id + "]");
                            } else {
                                if (type == "selected") {
                                    return (step == 1 ? dc.body1 : dc.body2).find("tr.datagrid-row-selected");
                                } else {
                                    if (type == "last") {
                                        return (step == 1 ? dc.body1 : dc.body2).find("tr:last[node-id]");
                                    } else {
                                        if (type == "allbody") {
                                            return (step == 1 ? dc.body1 : dc.body2).find("tr[node-id]");
                                        } else {
                                            if (type == "allfooter") {
                                                return (step == 1 ? dc.footer1 : dc.footer2).find("tr[node-id]");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                //获取行
                getRow: function (target, p) {
                    var id = (typeof p == "object") ? p.attr("node-id") : p;
                    return $(target).treegrid("find", id);
                }
            },
            //在载入请求数据数据之前触发,如果返回false可终止载入数据操作
            onBeforeLoad: function (row, param) {
            },
            //在数据加载成功的时候触发
            onLoadSuccess: function (row, data) {
            },
            //在数据加载成功的时候触发
            onLoadError: function () {
            },
            //在数据加载成功的时候触发
            onBeforeCollapse: function (row) {
            },
            //在节点被折叠的时候触发
            onCollapse: function (row) {
            },
            //在节点展开之前触发,返回false可以取消展开节点的动作
            onBeforeExpand: function (row) {
            },
            //在节点被展开的时候触发
            onExpand: function (row) {
            },
            //在用户点击节点的时候触发
            onClickRow: function (row) {
            },
            //在用户双击节点的时候触发
            onDblClickRow: function (row) {
            },
            //在用户点击一个单元格的时候触发
            onClickCell: function (field, row) {
            },
            //在用户双击一个单元格的时候触发
            onDblClickCell: function (field, row) {
            },
            //在右键点击节点的时候触发。
            onContextMenu: function (e, row) {
            },
            //在用户开始编辑节点的时候触发
            onBeforeEdit: function (row) {
            },
            //在用户完成编辑的时候触发
            onAfterEdit: function (row, changes) {
            },
            //在用户取消编辑节点的时候触发。
            onCancelEdit: function (row) {
            }
        });
    })(jQuery);
    View Code

    示例代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Basic TreeGrid - 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="../../plugins2/jquery.resizable.js"></script>
        <script src="../../plugins2/jquery.linkbutton.js"></script>
        <script src="../../plugins2/jquery.pagination.js"></script>
        <script src="../../plugins2/jquery.datagrid.js"></script>
        <script src="../../plugins2/jquery.treegrid.js"></script>
    </head>
    <body>
        <h2>Basic TreeGrid</h2>
        <div class="demo-info">
            <div class="demo-tip icon-tip"></div>
            <div>TreeGrid allows you to expand or collapse group rows.</div>
        </div>
        <div style="margin:10px 0;"></div>
        <table title="Folder Browser" class="easyui-treegrid" style="700px;height:250px"
                data-options="
                    url: '../treegrid/treegrid_data1.json',
                    rownumbers: true,
                    idField: 'id',
                    treeField: 'name'
                ">
            <thead>
                <tr>
                    <th data-options="field:'name'" width="220">Name</th>
                    <th data-options="field:'size'" width="100" align="right">Size</th>
                    <th data-options="field:'date'" width="150">Modified Date</th>
                </tr>
            </thead>
        </table>
    
    </body>
    </html>
    View Code

    插件效果

    热爱编程,热爱技术,热爱生活
  • 相关阅读:
    javascript入门教程笔记
    杭电2025
    杭电 2024
    杭电2019
    UEditor编辑器上传图片开发流程
    js操作textarea方法集合
    ueditor编辑器和at.js集成
    js分页算法
    js获取url中的参数
    第7章函数表达式笔记
  • 原文地址:https://www.cnblogs.com/DemoLee/p/3501111.html
Copyright © 2020-2023  润新知