/** * jQuery webUI 1.1.0 * */ if(typeof (WebUIManagers) == "undefined") WebUIManagers = {}; (function($) { /// $.fn.webGetTreeManager = function() { return WebUIManagers[this[0].id + "_Tree"]; }; $.webDefaults = $.webDefaults || {}; $.webDefaults.Tree = { url: null, data: null, checkbox: true, autoCheckboxEven: true, parentIcon: 'folder', childIcon: 'leaf', textFieldName: 'text', attribute: ['id', 'url'], treeLine: true, //是否显示line nodeWidth: 90, statusName: '__status', isLeaf: null, //是否子节点的判断函数 single: false, //是否单选 onBeforeExpand: function() { }, onContextmenu: function() { }, onExpand: function() { }, onBeforeCollapse: function() { }, onCollapse: function() { }, onBeforeSelect: function() { }, onSelect: function() { }, onBeforeCancelSelect: function() { }, onCancelselect: function() { }, onCheck: function() { }, onSuccess: function() { }, onError: function() { }, onClick: function() { }, idFieldName: 'id', parentIDFieldName: null, topParentIDValue: 0, onBeforeAppend: function() { }, //加载数据前事件,可以通过return false取消操作 onAppend: function() { }, //加载数据时事件,对数据进行预处理以后 onAfterAppend: function() { }, //加载数据完事件 slide: true //是否以动画的形式显示 }; $.fn.webTree = function(p) { if (p.single) p.autoCheckboxEven = false; this.each(function() { p = $.extend({}, $.webDefaults.Tree, p || {}); if (this.usedTree) return; if ($(this).hasClass('n-hidden')) { return; } //public Object var g = { getData: function() { return g.data; }, //是否包含子节点 hasChildren: function(treenodedata) { if (p.isLeaf) return p.isLeaf(treenodedata); return treenodedata.children ? true : false; }, //获取父节点 getParentTreeItem: function(treenode, level) { var treeitem = $(treenode); if (treeitem.parent().hasClass("n-tree")) return null; if (level == undefined) { if (treeitem.parent().parent("li").length == 0) return null; return treeitem.parent().parent("li")[0]; } var currentLevel = parseInt(treeitem.attr("outlinelevel")); var currenttreeitem = treeitem; for (var i = currentLevel - 1; i >= level; i--) { currenttreeitem = currenttreeitem.parent().parent("li"); } return currenttreeitem[0]; }, getChecked: function() { if (!p.checkbox) return null; var nodes = []; $(".n-checkbox-checked", g.tree).parent().parent("li").each(function() { var treedataindex = parseInt($(this).attr("treedataindex")); nodes.push({ target: this, data: po.getDataNodeByTreeDataIndex(g.data, treedataindex) }); }); return nodes; }, getSelected: function() { var node = {}; node.target = $(".n-selected", g.tree).parent("li")[0]; if (node.target) { var treedataindex = parseInt($(node.target).attr("treedataindex")); node.data = po.getDataNodeByTreeDataIndex(g.data, treedataindex); return node; } return null; }, //升级为父节点级别 upgrade: function(treeNode) { $(".n-note", treeNode).each(function() { $(this).removeClass("n-note").addClass("n-expandable-open"); }); $(".n-note-last", treeNode).each(function() { $(this).removeClass("n-note-last").addClass("n-expandable-open"); }); $("." + po.getChildNodeClassName(), treeNode).each(function() { $(this) .removeClass(po.getChildNodeClassName()) .addClass(po.getParentNodeClassName(true)); }); }, //降级为叶节点级别 demotion: function(treeNode) { if (!treeNode && treeNode[0].tagName.toLowerCase() != 'li') return; var islast = $(treeNode).hasClass("n-last"); $(".n-expandable-open", treeNode).each(function() { $(this).removeClass("n-expandable-open") .addClass(islast ? "n-note-last" : "n-note"); }); $(".n-expandable-close", treeNode).each(function() { $(this).removeClass("n-expandable-close") .addClass(islast ? "n-note-last" : "n-note"); }); $("." + po.getParentNodeClassName(true), treeNode).each(function() { $(this) .removeClass(po.getParentNodeClassName(true)) .addClass(po.getChildNodeClassName()); }); }, collapseAll: function() { $(".n-expandable-open", g.tree).click(); }, expandAll: function() { $(".n-expandable-close", g.tree).click(); }, loadData: function(node, url, param) { g.loading.show(); var ajaxtype = param ? "post" : "get"; param = param || []; //请求服务器 $.ajax({ type: ajaxtype , url: url, data: param, dataType: 'json', success: function(data) { if (!data) return; g.loading.hide(); g.append(node, data); if (p.onSuccess) p.onSuccess(data); }, error: function(XMLHttpRequest, textStatus, errorThrown) { try { g.loading.hide(); if (p.onError) p.onError(XMLHttpRequest, textStatus, errorThrown); } catch (e) { } } }); }, //清空 clear: function() { //g.tree.html(""); $("> li", g.tree).each(function() { g.remove(this); }); }, remove: function(treeNode) { var treedataindex = parseInt($(treeNode).attr("treedataindex")); var treenodedata = po.getDataNodeByTreeDataIndex(g.data, treedataindex); if (treenodedata) po.setTreeDataStatus([treenodedata], 'delete'); var parentNode = g.getParentTreeItem(treeNode); //复选框处理 if (p.checkbox) { $(".n-checkbox", treeNode).remove(); po.setParentCheckboxStatus($(treeNode)); } $(treeNode).remove(); if (parentNode == null) //代表顶级节点 { parentNode = g.tree.parent(); } //set parent var treeitemlength = $("> ul > li", parentNode).length; if (treeitemlength > 0) { //遍历设置子节点 $("> ul > li", parentNode).each(function(i, item) { if (i == 0 && !$(this).hasClass("n-first")) $(this).addClass("n-first"); if (i == treeitemlength - 1 && !$(this).hasClass("n-last")) $(this).addClass("n-last"); if (i == 0 && i == treeitemlength - 1 && !$(this).hasClass("n-onlychild")) $(this).addClass("n-onlychild"); $("> div .n-note,> div .n-note-last", this) .removeClass("n-note n-note-last") .addClass(i == treeitemlength - 1 ? "n-note-last" : "n-note"); po.setTreeItem(this, { isLast: i == treeitemlength - 1 }); }); } }, update: function(domnode, newnodedata) { var treedataindex = parseInt($(domnode).attr("treedataindex")); nodedata = po.getDataNodeByTreeDataIndex(g.data, treedataindex); for (var attr in newnodedata) { nodedata[attr] = newnodedata[attr]; if (attr == p.textFieldName) { $("> .n-body > span", domnode).text(newnodedata[attr]); } } }, //增加节点集合 append: function(parentNode, newdata) { if (p.onBeforeAppend && p.onBeforeAppend(parentNode, newdata) == false) return false; if (!newdata || !newdata.length) return false; if (p.idFieldName && p.parentIDFieldName) newdata = po.convertData(newdata); po.addTreeDataIndexToData(newdata); po.setTreeDataStatus(newdata, 'add'); p.onAppend && p.onAppend(parentNode, newdata); po.appendData(parentNode, newdata); if (!parentNode)//增加到根节点 { //remove last node class if ($("> li:last", g.tree).length > 0) po.setTreeItem($("> li:last", g.tree)[0], { isLast: false }); var gridhtmlarr = po.getTreeHTMLByData(newdata, 1, [], true); gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; g.tree.append(gridhtmlarr.join('')); $(".n-body", g.tree).hover(function() { $(this).addClass("n-over"); }, function() { $(this).removeClass("n-over"); }); // po.upadteTreeWidth(); p.onAfterAppend && p.onAfterAppend(parentNode, newdata); return; } var treeitem = $(parentNode); var outlineLevel = parseInt(treeitem.attr("outlinelevel")); var hasChildren = $("> ul", treeitem).length > 0; if (!hasChildren) { treeitem.append(""); //设置为父节点 g.upgrade(parentNode); } //remove last node class if ($("> .n-children > li:last", treeitem).length > 0) po.setTreeItem($("> .n-children > li:last", treeitem)[0], { isLast: false }); var isLast = []; for (var i = 1; i <= outlineLevel - 1; i++) { var currentParentTreeItem = $(g.getParentTreeItem(parentNode, i)); isLast.push(currentParentTreeItem.hasClass("n-last")); } isLast.push(treeitem.hasClass("n-last")); var gridhtmlarr = po.getTreeHTMLByData(newdata, outlineLevel + 1, isLast, true); gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; $(">.n-children", parentNode).append(gridhtmlarr.join('')); // po.upadteTreeWidth(); $(">.n-children .n-body", parentNode).hover(function() { $(this).addClass("n-over"); }, function() { $(this).removeClass("n-over"); }); p.onAfterAppend && p.onAfterAppend(parentNode, newdata); }, //增加节点集合2 append2: function(parentNode, newdata) { if (p.onBeforeAppend && p.onBeforeAppend(parentNode, newdata) == false) return false; if (!newdata || !newdata.length) return false; // if (p.idFieldName && p.parentIDFieldName) // newdata = po.convertData(newdata); po.addTreeDataIndexToData(newdata); po.setTreeDataStatus(newdata, 'add'); p.onAppend && p.onAppend(parentNode, newdata); po.appendData(parentNode, newdata); if (!parentNode)//增加到根节点 { //remove last node class if ($("> li:last", g.tree).length > 0) po.setTreeItem($("> li:last", g.tree)[0], { isLast: false }); var gridhtmlarr = po.getTreeHTMLByData(newdata, 1, [], true); gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; g.tree.append(gridhtmlarr.join('')); $(".n-body", g.tree).hover(function() { $(this).addClass("n-over"); }, function() { $(this).removeClass("n-over"); }); // po.upadteTreeWidth(); p.onAfterAppend && p.onAfterAppend(parentNode, newdata); return; } var treeitem = $(parentNode); var outlineLevel = parseInt(treeitem.attr("outlinelevel")); var hasChildren = $("> ul", treeitem).length > 0; if (!hasChildren) { treeitem.append(""); //设置为父节点 g.upgrade(parentNode); } //remove last node class if ($("> .n-children > li:last", treeitem).length > 0) po.setTreeItem($("> .n-children > li:last", treeitem)[0], { isLast: false }); var isLast = []; for (var i = 1; i <= outlineLevel - 1; i++) { var currentParentTreeItem = $(g.getParentTreeItem(parentNode, i)); isLast.push(currentParentTreeItem.hasClass("n-last")); } isLast.push(treeitem.hasClass("n-last")); var gridhtmlarr = po.getTreeHTMLByData(newdata, outlineLevel + 1, isLast, true); gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; $(">.n-children", parentNode).append(gridhtmlarr.join('')); // po.upadteTreeWidth(); $(">.n-children .n-body", parentNode).hover(function() { $(this).addClass("n-over"); }, function() { $(this).removeClass("n-over"); }); p.onAfterAppend && p.onAfterAppend(parentNode, newdata); }, cancelSelect: function(domNode) { var treeitem = $(domNode); var treedataindex = parseInt(treeitem.attr("treedataindex")); var treenodedata = po.getDataNodeByTreeDataIndex(g.data, treedataindex); var treeitembody = $(">div:first", treeitem); if (p.checkbox) $(".n-checkbox", treeitembody).removeClass("n-checkbox-checked").addClass("n-checkbox-unchecked"); else treeitembody.removeClass("n-selected"); p.onCancelSelect && p.onCancelSelect({ data: treenodedata, target: treeitem[0] }); }, //选择节点(参数:条件函数、Dom节点或ID值) selectNode: function(selectNodeParm) { var clause = null; if (typeof (selectNodeParm) == "function") { clause = selectNodeParm; } else if (typeof (selectNodeParm) == "object") { var treeitem = $(selectNodeParm); var treedataindex = parseInt(treeitem.attr("treedataindex")); var treenodedata = po.getDataNodeByTreeDataIndex(g.data, treedataindex); var treeitembody = $(">div:first", treeitem); if (p.checkbox) $(".n-checkbox", treeitembody).removeClass("n-checkbox-unchecked").addClass("n-checkbox-checked"); else treeitembody.addClass("n-selected"); if(typeof(p.onSelect) == "string"){ eval(p.onSelect + "({ data: treenodedata, target: treeitem[0] })"); }else p.onSelect && p.onSelect({ data: treenodedata, target: treeitem[0] }); return; } else { clause = function(data) { if (!data[p.idFieldName]) return false; return data[p.idFieldName].toString() == selectNodeParm.toString(); }; } $("li", g.tree).each(function() { var treeitem = $(this); var treedataindex = parseInt(treeitem.attr("treedataindex")); var treenodedata = po.getDataNodeByTreeDataIndex(g.data, treedataindex); if (clause(treenodedata, treedataindex)) { g.selectNode(this); } else { g.cancelSelect(this); } }); }, getTextByID: function(id) { var data = g.getDataByID(id); if (!data) return null; return data[p.textFieldName]; }, getDataByID: function(id) { var data = null; $("li", g.tree).each(function() { if (data) return; var treeitem = $(this); var treedataindex = parseInt(treeitem.attr("treedataindex")); var treenodedata = po.getDataNodeByTreeDataIndex(g.data, treedataindex); if (treenodedata[p.idFieldName].toString() == id.toString()) { data = treenodedata; } }); return data; } }; //private Object var po = { //根据数据索引获取数据 getDataNodeByTreeDataIndex: function(data, treedataindex) { for (var i = 0; i < data.length; i++) { if (data[i].treedataindex == treedataindex) return data[i]; if (data[i].children) { var targetData = po.getDataNodeByTreeDataIndex(data[i].children, treedataindex); if (targetData) return targetData; } } return null; }, //设置数据状态 setTreeDataStatus: function(data, status) { $(data).each(function() { this[p.statusName] = status; if (this.children) { po.setTreeDataStatus(this.children, status); } }); }, //设置data 索引 addTreeDataIndexToData: function(data) { $(data).each(function() { if (this.treedataindex != undefined) return; this.treedataindex = g.treedataindex++; if (this.children) { po.addTreeDataIndexToData(this.children); } }); }, //添加项到g.data appendData: function(treeNode, data) { var treedataindex = parseInt($(treeNode).attr("treedataindex")); var treenodedata = po.getDataNodeByTreeDataIndex(g.data, treedataindex); if (g.treedataindex == undefined) g.treedataindex = 0; if (treenodedata && treenodedata.children == undefined) treenodedata.children = []; $(data).each(function(i, item) { if (treenodedata) treenodedata.children[treenodedata.children.length] = $.extend({}, item); else g.data[g.data.length] = $.extend({}, item); }); }, setTreeItem: function(treeNode, options) { if (!options) return; var treeItem = $(treeNode); var outlineLevel = parseInt(treeItem.attr("outlinelevel")); if (options.isLast != undefined) { if (options.isLast == true) { treeItem.removeClass("n-last").addClass("n-last"); $("> div .n-note", treeItem).removeClass("n-note").addClass("n-note-last"); $(".n-children li", treeItem) .find(".n-box:eq(" + (outlineLevel - 1) + ")") .removeClass("n-line"); } else if (options.isLast == false) { treeItem.removeClass("n-last"); $("> div .n-note-last", treeItem).removeClass("n-note-last").addClass("n-note"); $(".n-children li", treeItem) .find(".n-box:eq(" + (outlineLevel - 1) + ")") .removeClass("n-line") .addClass("n-line"); } } }, // upadteTreeWidth: function() // { // var treeWidth = g.maxOutlineLevel * 22; // if (p.checkbox) treeWidth += 22; // if (p.parentIcon || p.childIcon) treeWidth += 22; // treeWidth += p.nodeWidth; // g.tree.width(treeWidth); // }, getChildNodeClassName: function() { return 'n-tree-icon-' + p.childIcon; }, getParentNodeClassName: function(isOpen) { var nodeclassname = 'n-tree-icon-' + p.parentIcon; if (isOpen) nodeclassname += '-open'; return nodeclassname; }, //根据data生成最终完整的tree html getTreeHTMLByData: function(data, outlineLevel, isLast, isExpand) { if (g.maxOutlineLevel < outlineLevel) g.maxOutlineLevel = outlineLevel; isLast = isLast || []; outlineLevel = outlineLevel || 1; var treehtmlarr = []; if (!isExpand) treehtmlarr.push('