前言
扩展自$.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);
示例代码
<!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="width: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>