/** * jQuery ligerUI 1.2.4 * * http://ligerui.com * * Author daomi 2014 [ gd_star@163.com ] * */ (function ($) { $.fn.ligerTree = function (options) { return $.ligerui.run.call(this, "ligerTree", arguments); }; $.fn.ligerGetTreeManager = function () { return $.ligerui.run.call(this, "ligerGetTreeManager", arguments); }; $.ligerDefaults.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, //是否单选 needCancel: true, //已选的是否需要取消操作 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, //是否以动画的形式显示 iconFieldName: 'icon', nodeDraggable: false, //是否允许拖拽 nodeDraggingRender: null, btnClickToToggleOnly: true, //是否点击展开/收缩 按钮时才有效 ajaxType: 'post', render: null, //自定义函数 selectable: null, //可选择判断函数 /* 是否展开 1,可以是true/false 2,也可以是数字(层次)N 代表第1层到第N层都是展开的,其他收缩 3,或者是判断函数 函数参数e(data,level) 返回true/false 优先级没有节点数据的isexpand属性高,并没有delay属性高 */ isExpand: null, /* 是否延迟加载 1,可以是true/false 2,也可以是数字(层次)N 代表第N层延迟加载 3,或者是字符串(Url) 加载数据的远程地址 4,如果是数组,代表这些层都延迟加载,如[1,2]代表第1、2层延迟加载 5,再是函数(运行时动态获取延迟加载参数) 函数参数e(data,level),返回true/false或者{url:...,parms:...} 优先级没有节点数据的delay属性高 */ delay: null }; $.ligerui.controls.Tree = function (element, options) { $.ligerui.controls.Tree.base.constructor.call(this, element, options); }; $.ligerui.controls.Tree.ligerExtend($.ligerui.core.UIComponent, { _init: function () { $.ligerui.controls.Tree.base._init.call(this); var g = this, p = this.options; if (p.single) p.autoCheckboxEven = false; }, _render: function () { var g = this, p = this.options; g.set(p, true); g.tree = $(g.element); g.tree.addClass('l-tree'); g.toggleNodeCallbacks = []; g.sysAttribute = ['isexpand', 'ischecked', 'href', 'style', 'delay']; g.loading = $("
"); g.tree.after(g.loading); g.data = []; g.maxOutlineLevel = 1; g.treedataindex = 0; g._applyTree(); g._setTreeEven(); g.set(p, false); }, _setTreeLine: function (value) { if (value) this.tree.removeClass("l-tree-noline"); else this.tree.addClass("l-tree-noline"); }, _setParms: function () { var g = this, p = this.options; if ($.isFunction(p.parms)) p.parms = p.parms(); }, _setUrl: function (url) { var g = this, p = this.options; if (url) { g.clear(); g.loadData(null, url); } }, _setData: function (data) { if (data) { this.clear(); this.append(null, data); } }, setData: function (data) { this.set('data', data); }, getData: function () { return this.data; }, //是否包含子节点 hasChildren: function (treenodedata) { if (this.options.isLeaf) return !this.options.isLeaf(treenodedata); return treenodedata.children ? true : false; }, //获取父节点 数据 getParent: function (treenode, level) { var g = this; treenode = g.getNodeDom(treenode); var parentTreeNode = g.getParentTreeItem(treenode, level); if (!parentTreeNode) return null; var parentIndex = $(parentTreeNode).attr("treedataindex"); return g._getDataNodeByTreeDataIndex(parentIndex); }, //获取父节点 getParentTreeItem: function (treenode, level) { var g = this; treenode = g.getNodeDom(treenode); var treeitem = $(treenode); if (treeitem.parent().hasClass("l-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 () { var g = this, p = this.options; if (!this.options.checkbox) return null; var nodes = []; $(".l-checkbox-checked", g.tree).parent().parent("li").each(function () { var treedataindex = parseInt($(this).attr("treedataindex")); nodes.push({ target: this, data: g._getDataNodeByTreeDataIndex(g.data, treedataindex) }); }); return nodes; }, //add by superzoc 12/24/2012 refreshTree: function () { var g = this, p = this.options; $.each(this.getChecked(), function (k, v) { g._setParentCheckboxStatus($(v.target)); }); }, getSelected: function () { var g = this, p = this.options; var node = {}; node.target = $(".l-selected", g.tree).parent("li")[0]; if (node.target) { var treedataindex = parseInt($(node.target).attr("treedataindex")); node.data = g._getDataNodeByTreeDataIndex(g.data, treedataindex); return node; } return null; }, //升级为父节点级别 upgrade: function (treeNode) { var g = this, p = this.options; $(".l-note", treeNode).each(function () { $(this).removeClass("l-note").addClass("l-expandable-open"); }); $(".l-note-last", treeNode).each(function () { $(this).removeClass("l-note-last").addClass("l-expandable-open"); }); $("." + g._getChildNodeClassName(), treeNode).each(function () { $(this) .removeClass(g._getChildNodeClassName()) .addClass(g._getParentNodeClassName(true)); }); }, //降级为叶节点级别 demotion: function (treeNode) { var g = this, p = this.options; if (!treeNode && treeNode[0].tagName.toLowerCase() != 'li') return; var islast = $(treeNode).hasClass("l-last"); $(".l-expandable-open", treeNode).each(function () { $(this).removeClass("l-expandable-open") .addClass(islast ? "l-note-last" : "l-note"); }); $(".l-expandable-close", treeNode).each(function () { $(this).removeClass("l-expandable-close") .addClass(islast ? "l-note-last" : "l-note"); }); $("." + g._getParentNodeClassName(true), treeNode).each(function () { $(this) .removeClass(g._getParentNodeClassName(true)) .addClass(g._getChildNodeClassName()); }); }, collapseAll: function () { var g = this, p = this.options; $(".l-expandable-open", g.tree).click(); }, expandAll: function () { var g = this, p = this.options; $(".l-expandable-close", g.tree).click(); }, loadData: function (node, url, param, e) { var g = this, p = this.options; e = $.extend({ showLoading: function () { g.loading.show(); }, hideLoading: function () { g.loading.hide(); } }, e || {}); var ajaxtype = p.ajaxType; param = param || []; //请求服务器 $.ajax({ type: ajaxtype, url: url, data: param, dataType: 'json', cache: false, beforeSend: function () { e.showLoading(); }, success: function (data) { if (!data) return; e.hideLoading(); g.append(node, data); g.trigger('success', [data]); }, error: function (XMLHttpRequest, textStatus, errorThrown) { try { e.hideLoading(); g.trigger('error', [XMLHttpRequest, textStatus, errorThrown]); } catch (e) { } } }); }, //清空 clear: function () { var g = this, p = this.options; g.toggleNodeCallbacks = []; g.data = null; g.data = []; g.nodes = null; g.tree.html(""); }, //parm [treeNode] dom节点(li)、节点数据 或者节点 dataindex getNodeDom: function (nodeParm) { var g = this, p = this.options; if (nodeParm == null) return nodeParm; if (typeof (nodeParm) == "string" || typeof (nodeParm) == "number") { return $("li[treedataindex=" + nodeParm + "]", g.tree).get(0); } else if (typeof (nodeParm) == "object" && 'treedataindex' in nodeParm) //nodedata { return g.getNodeDom(nodeParm['treedataindex']); } return nodeParm; }, hide: function (treeNode) { var g = this, p = this.options; treeNode = g.getNodeDom(treeNode); if (treeNode) $(treeNode).hide(); }, show: function (treeNode) { var g = this, p = this.options; treeNode = g.getNodeDom(treeNode); if (treeNode) $(treeNode).show(); }, //parm [treeNode] dom节点(li)、节点数据 或者节点 dataindex remove: function (treeNode) { var g = this, p = this.options; treeNode = g.getNodeDom(treeNode); var treedataindex = parseInt($(treeNode).attr("treedataindex")); var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); if (treenodedata) g._setTreeDataStatus([treenodedata], 'delete'); var parentNode = g.getParentTreeItem(treeNode); //复选框处理 if (p.checkbox) { g._setParentCheckboxStatus($(treeNode)); } $(treeNode).remove(); g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree); }, _updateStyle: function (ul) { var g = this, p = this.options; var itmes = $(" > li", ul); var treeitemlength = itmes.length; if (!treeitemlength) return; //遍历设置子节点的样式 itmes.each(function (i, item) { if (i == 0 && !$(this).hasClass("l-first")) $(this).addClass("l-first"); if (i == treeitemlength - 1 && !$(this).hasClass("l-last")) $(this).addClass("l-last"); if (i == 0 && i == treeitemlength - 1) $(this).addClass("l-onlychild"); $("> div .l-note,> div .l-note-last", this) .removeClass("l-note l-note-last") .addClass(i == treeitemlength - 1 ? "l-note-last" : "l-note"); g._setTreeItem(this, { isLast: i == treeitemlength - 1 }); }); }, //parm [domnode] dom节点(li)、节点数据 或者节点 dataindex update: function (domnode, newnodedata) { var g = this, p = this.options; domnode = g.getNodeDom(domnode); var treedataindex = parseInt($(domnode).attr("treedataindex")); nodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); for (var attr in newnodedata) { nodedata[attr] = newnodedata[attr]; if (attr == p.textFieldName) { $("> .l-body > span", domnode).text(newnodedata[attr]); } } }, //增加节点集合 //parm [newdata] 数据集合 Array //parm [parentNode] dom节点(li)、节点数据 或者节点 dataindex //parm [nearNode] 附加到节点的上方/下方(非必填) //parm [isAfter] 附加到节点的下方(非必填) append: function (parentNode, newdata, nearNode, isAfter) { var g = this, p = this.options; parentNode = g.getNodeDom(parentNode); if (g.trigger('beforeAppend', [parentNode, newdata]) == false) return false; if (!newdata || !newdata.length) return false; if (p.idFieldName && p.parentIDFieldName) newdata = g.arrayToTree(newdata, p.idFieldName, p.parentIDFieldName); g._addTreeDataIndexToData(newdata); g._setTreeDataStatus(newdata, 'add'); if (nearNode != null) { nearNode = g.getNodeDom(nearNode); } g.trigger('append', [parentNode, newdata]) g._appendData(parentNode, newdata); if (parentNode == null)//增加到根节点 { var gridhtmlarr = g._getTreeHTMLByData(newdata, 1, [], true); gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; if (nearNode != null) { $(nearNode)[isAfter ? 'after' : 'before'](gridhtmlarr.join('')); g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree); } else { //remove last node class if ($("> li:last", g.tree).length > 0) g._setTreeItem($("> li:last", g.tree)[0], { isLast: false }); g.tree.append(gridhtmlarr.join('')); } $(".l-body", g.tree).hover(function () { $(this).addClass("l-over"); }, function () { $(this).removeClass("l-over"); }); g._upadteTreeWidth(); g.trigger('afterAppend', [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); } var isLast = []; for (var i = 1; i <= outlineLevel - 1; i++) { var currentParentTreeItem = $(g.getParentTreeItem(parentNode, i)); isLast.push(currentParentTreeItem.hasClass("l-last")); } isLast.push(treeitem.hasClass("l-last")); var gridhtmlarr = g._getTreeHTMLByData(newdata, outlineLevel + 1, isLast, true); gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; if (nearNode != null) { $(nearNode)[isAfter ? 'after' : 'before'](gridhtmlarr.join('')); g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree); } else { //remove last node class if ($("> .l-children > li:last", treeitem).length > 0) g._setTreeItem($("> .l-children > li:last", treeitem)[0], { isLast: false }); $(">.l-children", parentNode).append(gridhtmlarr.join('')); } g._upadteTreeWidth(); $(">.l-children .l-body", parentNode).hover(function () { $(this).addClass("l-over"); }, function () { $(this).removeClass("l-over"); }); g.trigger('afterAppend', [parentNode, newdata]); }, //parm [nodeParm] dom节点(li)、节点数据 或者节点 dataindex cancelSelect: function (nodeParm) { var g = this, p = this.options; var domNode = g.getNodeDom(nodeParm); var treeitem = $(domNode); var treedataindex = parseInt(treeitem.attr("treedataindex")); var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); var treeitembody = $(">div:first", treeitem); if (p.checkbox) $(".l-checkbox", treeitembody).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked"); else treeitembody.removeClass("l-selected"); g.trigger('cancelSelect', [{ data: treenodedata, target: treeitem[0]}]); }, //选择节点(参数:条件函数、Dom节点或ID值) selectNode: function (selectNodeParm) { var g = this, p = this.options; 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 = g._getDataNodeByTreeDataIndex(g.data, treedataindex); var treeitembody = $(">div:first", treeitem); if (!treeitembody.length) { treeitembody = $("li[treedataindex=" + treedataindex + "] >div:first", g.tree); } if (p.checkbox) { $(".l-checkbox", treeitembody).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked"); } else { $("div.l-selected", g.tree).removeClass("l-selected"); treeitembody.addClass("l-selected"); } g.trigger('select', [{ data: treenodedata, target: treeitembody.parent().get(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 = g._getDataNodeByTreeDataIndex(g.data, treedataindex); if (clause(treenodedata, treedataindex)) { g.selectNode(this); } else { g.cancelSelect(this); } }); }, getTextByID: function (id) { var g = this, p = this.options; var data = g.getDataByID(id); if (!data) return null; return data[p.textFieldName]; }, getDataByID: function (id) { var g = this, p = this.options; var data = null; $("li", g.tree).each(function () { if (data) return; var treeitem = $(this); var treedataindex = parseInt(treeitem.attr("treedataindex")); var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); if (treenodedata[p.idFieldName].toString() == id.toString()) { data = treenodedata; } }); return data; }, arrayToTree: function (data, id, pid) //将ID、ParentID这种数据格式转换为树格式 { if (!data || !data.length) return []; var targetData = []; //存储数据的容器(返回) var records = {}; var itemLength = data.length; //数据集合的个数 for (var i = 0; i < itemLength; i++) { var o = data[i]; records[o[id]] = o; } for (var i = 0; i < itemLength; i++) { var currentData = data[i]; var parentData = records[currentData[pid]]; if (!parentData) { targetData.push(currentData); continue; } parentData.children = parentData.children || []; parentData.children.push(currentData); } return targetData; }, //根据数据索引获取数据 _getDataNodeByTreeDataIndex: function (data, treedataindex) { var g = this, p = this.options; for (var i = 0; i < data.length; i++) { if (data[i].treedataindex == treedataindex) return data[i]; if (data[i].children) { var targetData = g._getDataNodeByTreeDataIndex(data[i].children, treedataindex); if (targetData) return targetData; } } return null; }, //设置数据状态 _setTreeDataStatus: function (data, status) { var g = this, p = this.options; $(data).each(function () { this[p.statusName] = status; if (this.children) { g._setTreeDataStatus(this.children, status); } }); }, //设置data 索引 _addTreeDataIndexToData: function (data) { var g = this, p = this.options; $(data).each(function () { if (this.treedataindex != undefined) return; this.treedataindex = g.treedataindex++; if (this.children) { g._addTreeDataIndexToData(this.children); } }); }, _addToNodes: function (data) { var g = this, p = this.options; g.nodes = g.nodes || []; g.nodes.push(data); if (!data.children) return; $(data.children).each(function (i, item) { g._addToNodes(item); }); }, //添加项到g.data _appendData: function (treeNode, data) { var g = this, p = this.options; var treedataindex = parseInt($(treeNode).attr("treedataindex")); var treenodedata = g._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] = item; else g.data[g.data.length] = item; g._addToNodes(item); }); }, _setTreeItem: function (treeNode, options) { var g = this, p = this.options; if (!options) return; treeNode = g.getNodeDom(treeNode); var treeItem = $(treeNode); var outlineLevel = parseInt(treeItem.attr("outlinelevel")); if (options.isLast != undefined) { if (options.isLast == true) { treeItem.removeClass("l-last").addClass("l-last"); $("> div .l-note", treeItem).removeClass("l-note").addClass("l-note-last"); $(".l-children li", treeItem) .find(".l-box:eq(" + (outlineLevel - 1) + ")") .removeClass("l-line"); } else if (options.isLast == false) { treeItem.removeClass("l-last"); $("> div .l-note-last", treeItem).removeClass("l-note-last").addClass("l-note"); $(".l-children li", treeItem) .find(".l-box:eq(" + (outlineLevel - 1) + ")") .removeClass("l-line") .addClass("l-line"); } } }, _upadteTreeWidth: function () { var g = this, p = this.options; 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 () { var g = this, p = this.options; return 'l-tree-icon-' + p.childIcon; }, _getParentNodeClassName: function (isOpen) { var g = this, p = this.options; var nodeclassname = 'l-tree-icon-' + p.parentIcon; if (isOpen) nodeclassname += '-open'; return nodeclassname; }, //判断节点是否展开状态,返回true/false _isExpand: function (o, level) { var g = this, p = this.options; var isExpand = o.isExpand != null ? o.isExpand : (o.isexpand != null ? o.isexpand : p.isExpand); if (isExpand == null) return true; if (typeof (isExpand) == "function") isExpand = p.isExpand({ data: o, level: level }); if (typeof (isExpand) == "boolean") return isExpand; if (typeof (isExpand) == "string") return isExpand == "true"; if (typeof (isExpand) == "number") return isExpand > level; return true; }, //获取节点的延迟加载状态,返回true/false (本地模式) 或者是object({url :'...',parms:null})(远程模式) _getDelay: function (o, level) { var g = this, p = this.options; var delay = o.delay != null ? o.delay : p.delay; if (delay == null) return false; if (typeof (delay) == "function") delay = delay({ data: o, level: level }); if (typeof (delay) == "boolean") return delay; if (typeof (delay) == "string") return { url: delay }; if (typeof (delay) == "number") delay = [delay]; if ($.isArray(delay)) return $.inArray(level, delay) != -1; if (typeof (delay) == "object" && delay.url) return delay; return false; }, //根据data生成最终完整的tree html _getTreeHTMLByData: function (data, outlineLevel, isLast, isExpand) { var g = this, p = this.options; if (g.maxOutlineLevel < outlineLevel) g.maxOutlineLevel = outlineLevel; isLast = isLast || []; outlineLevel = outlineLevel || 1; var treehtmlarr = []; if (!isExpand) treehtmlarr.push('