tijian_tieying/web/dccdc/ligerUI/js/plugins/ligerTree.js
2025-02-20 12:14:39 +08:00

1580 lines
66 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* jQuery ligerUI 1.3.3
*
* http://ligerui.com
*
* Author daomi 2015 [ 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,
urlParms: null, //url带参数
data: null,
checkbox: true,
autoCheckboxEven: true,
enabledCompleteCheckbox : 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',
ajaxContentType : null,
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,
//id字段
idField: null,
//parent id字段可用于线性数据转换为tree数据
parentIDField: null,
iconClsFieldName : 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 = $("<div class='l-tree-loading'></div>");
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();
},
reload: function (callback)
{
var g = this, p = this.options;
g.clear();
g.loadData(null, p.url, null, {
success: callback
});
},
//刷新节点
reloadNode: function (node, data, callback)
{
var g = this, p = this.options;
g.clear(node);
if (typeof (data) == "string")
{
g.loadData(node, data, null, {
success: callback
});
} else
{
if (!data) return;
if (p.idField && p.parentIDField)
{
data = g.arrayToTree(data, p.idField, p.parentIDField);
}
g.append(node, data);
}
},
_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(g.data,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;
},
getCheckedData: 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(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();
},
arrayToTree: function (data, id, pid) //将ID、ParentID这种数据格式转换为树格式
{
var g = this, p = this.options;
var childrenName = "children";
if (!data || !data.length) return [];
var targetData = []; //存储数据的容器(返回)
var records = {};
var itemLength = data.length; //数据集合的个数
for (var i = 0; i < itemLength; i++)
{
var o = data[i];
var key = getKey(o[id]);
records[key] = o;
}
for (var i = 0; i < itemLength; i++)
{
var currentData = data[i];
var key = getKey(currentData[pid]);
var parentData = records[key];
if (!parentData)
{
targetData.push(currentData);
continue;
}
parentData[childrenName] = parentData[childrenName] || [];
parentData[childrenName].push(currentData);
}
return targetData;
function getKey(key)
{
if (typeof (key) == "string") key = key.replace(/[.]/g, '').toLowerCase();
return key;
}
},
loadData: function (node, url, param, e)
{
var g = this, p = this.options;
e = $.extend({
showLoading: function ()
{
g.loading.show();
},
success: function () { },
error: function () { },
hideLoading: function ()
{
g.loading.hide();
}
}, e || {});
var ajaxtype = p.ajaxType;
//解决树无法设置parms的问题
param = $.extend(($.isFunction(p.parms) ? p.parms() : p.parms), param);
if (p.ajaxContentType == "application/json" && typeof (param) != "string")
{
param = liger.toJSON(param);
}
var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms;
if (urlParms)
{
for (name in urlParms)
{
url += url.indexOf('?') == -1 ? "?" : "&";
url += name + "=" + urlParms[name];
}
}
var ajaxOp = {
type: ajaxtype,
url: url,
data: param,
dataType: 'json',
beforeSend: function ()
{
e.showLoading();
},
success: function (data)
{
if (!data) return;
if (p.idField && p.parentIDField)
{
data = g.arrayToTree(data, p.idField, p.parentIDField);
}
e.hideLoading();
g.append(node, data);
g.trigger('success', [data]);
e.success(data);
},
error: function (XMLHttpRequest, textStatus, errorThrown)
{
try
{
e.hideLoading();
g.trigger('error', [XMLHttpRequest, textStatus, errorThrown]);
e.error(XMLHttpRequest, textStatus, errorThrown);
}
catch (e)
{
}
}
};
if (p.ajaxContentType)
{
ajaxOp.contentType = p.ajaxContentType;
}
$.ajax(ajaxOp);
},
//清空
clear: function (node)
{
var g = this, p = this.options;
if (!node)
{
g.toggleNodeCallbacks = [];
g.data = null;
g.data = [];
g.nodes = null;
g.tree.html("");
} else
{
var nodeDom = g.getNodeDom(node);
var nodeData = g._getDataNodeByTreeDataIndex(g.data, $(nodeDom).attr("treedataindex"));
$(nodeDom).find("ul.l-children").remove();
if (nodeData) nodeData.children = [];
}
},
//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']);
} else if(nodeParm.target && nodeParm.data)
{
return nodeParm.target;
}
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("<ul class='l-children'></ul>");
//设置为父节点
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, isTriggerEvent)
{
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");
if (isTriggerEvent != false)
{
g.trigger('cancelSelect', [{ data: treenodedata, target: treeitem[0] }]);
}
},
//选择节点(参数条件函数、Dom节点或ID值)
selectNode: function (selectNodeParm,isTriggerEvent)
{
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");
}
if (isTriggerEvent != false)
{
g.trigger('select', [{ data: treenodedata, target: treeitembody.parent().get(0) }]);
}
return;
}
else
{
clause = function (data)
{
if (!data[p.idFieldName] && data[p.idFieldName] != 0) return false;
return strTrim(data[p.idFieldName].toString()) == strTrim(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, isTriggerEvent);
}
else
{
//修复多选checkbox为true时调用该方法会取消已经选中节点的问题
if (!g.options.checkbox)
{
g.cancelSelect(this, isTriggerEvent);
}
}
});
},
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;
if (g.data && g.data.length)
{
return find(g.data);
}
function find(items)
{
for (var i = 0; i < items.length; i++)
{
var dataItem = items[i];
if (dataItem[p.idFieldName] == id) return dataItem;
if (dataItem.children && dataItem.children.length)
{
var o = find(dataItem.children);
if (o) return o;
}
}
return 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('<ul class="l-children" style="display:none">');
else treehtmlarr.push("<ul class='l-children'>");
for (var i = 0; i < data.length; i++)
{
var o = data[i];
var isFirst = i == 0;
var isLastCurrent = i == data.length - 1;
var delay = g._getDelay(o, outlineLevel);
var isExpandCurrent = delay ? false : g._isExpand(o, outlineLevel);
treehtmlarr.push('<li ');
if (o.treedataindex != undefined)
treehtmlarr.push('treedataindex="' + o.treedataindex + '" ');
if (isExpandCurrent)
treehtmlarr.push('isexpand=' + o.isexpand + ' ');
treehtmlarr.push('outlinelevel=' + outlineLevel + ' ');
//增加属性支持
for (var j = 0; j < g.sysAttribute.length; j++)
{
if ($(this).attr(g.sysAttribute[j]))
data[dataindex][g.sysAttribute[j]] = $(this).attr(g.sysAttribute[j]);
}
for (var j = 0; j < p.attribute.length; j++)
{
if (o[p.attribute[j]])
treehtmlarr.push(p.attribute[j] + '="' + o[p.attribute[j]] + '" ');
}
//css class
treehtmlarr.push('class="');
isFirst && treehtmlarr.push('l-first ');
isLastCurrent && treehtmlarr.push('l-last ');
isFirst && isLastCurrent && treehtmlarr.push('l-onlychild ');
treehtmlarr.push('"');
treehtmlarr.push('>');
treehtmlarr.push('<div class="l-body');
if (p.selectable && p.selectable(o) == false)
{
treehtmlarr.push(' l-unselectable');
}
treehtmlarr.push('">');
for (var k = 0; k <= outlineLevel - 2; k++)
{
if (isLast[k]) treehtmlarr.push('<div class="l-box"></div>');
else treehtmlarr.push('<div class="l-box l-line"></div>');
}
if (g.hasChildren(o))
{
if (isExpandCurrent) treehtmlarr.push('<div class="l-box l-expandable-open"></div>');
else treehtmlarr.push('<div class="l-box l-expandable-close"></div>');
if (p.checkbox)
{
if (o.ischecked)
treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-checked"></div>');
else
treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-unchecked"></div>');
}
if (p.parentIcon)
{
//node icon
treehtmlarr.push('<div class="l-box l-tree-icon ');
treehtmlarr.push(g._getParentNodeClassName(isExpandCurrent ? true : false) + " ");
if (p.iconFieldName && o[p.iconFieldName])
treehtmlarr.push('l-tree-icon-none');
else if (p.iconClsFieldName && o[p.iconClsFieldName])
treehtmlarr.push('l-tree-icon-' + o[p.iconClsFieldName] + " ");
treehtmlarr.push('">');
if (p.iconFieldName && o[p.iconFieldName])
treehtmlarr.push('<img src="' + o[p.iconFieldName] + '" />');
treehtmlarr.push('</div>');
}
}
else
{
if (isLastCurrent) treehtmlarr.push('<div class="l-box l-note-last"></div>');
else treehtmlarr.push('<div class="l-box l-note"></div>');
if (p.checkbox)
{
if (o.ischecked)
treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-checked"></div>');
else
treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-unchecked"></div>');
}
if (p.childIcon)
{
//node icon
treehtmlarr.push('<div class="l-box l-tree-icon ');
treehtmlarr.push(g._getChildNodeClassName() + " ");
if (p.iconFieldName && o[p.iconFieldName])
treehtmlarr.push('l-tree-icon-none');
else if (p.iconClsFieldName && o[p.iconClsFieldName])
treehtmlarr.push('l-tree-icon-' + o[p.iconClsFieldName] + " ");
treehtmlarr.push('">');
if (p.iconFieldName && o[p.iconFieldName])
treehtmlarr.push('<img src="' + o[p.iconFieldName] + '" />');
treehtmlarr.push('</div>');
}
}
if (p.render)
{
treehtmlarr.push('<span>' + p.render(o, o[p.textFieldName]) + '</span>');
} else
{
treehtmlarr.push('<span>' + o[p.textFieldName] + '</span>');
}
treehtmlarr.push('</div>');
if (g.hasChildren(o))
{
var isLastNew = [];
for (var k = 0; k < isLast.length; k++)
{
isLastNew.push(isLast[k]);
}
isLastNew.push(isLastCurrent);
if (delay)
{
if (delay == true)
{
g.toggleNodeCallbacks.push({
data: o,
callback: function (dom, o)
{
var content = g._getTreeHTMLByData(o.children, outlineLevel + 1, isLastNew, isExpandCurrent).join('');
$(dom).append(content);
$(">.l-children .l-body", dom).hover(function ()
{
$(this).addClass("l-over");
}, function ()
{
$(this).removeClass("l-over");
});
g._removeToggleNodeCallback(o);
}
});
}
else if (delay.url)
{
(function (o, url, parms)
{
g.toggleNodeCallbacks.push({
data: o,
callback: function (dom, o)
{
g.loadData(dom, url, parms, {
showLoading: function ()
{
$("div.l-expandable-close:first", dom).addClass("l-box-loading");
},
hideLoading: function ()
{
$("div.l-box-loading:first", dom).removeClass("l-box-loading");
}
});
g._removeToggleNodeCallback(o);
}
});
})(o, delay.url, delay.parms);
}
}
else
{
treehtmlarr.push(g._getTreeHTMLByData(o.children, outlineLevel + 1, isLastNew, isExpandCurrent).join(''));
}
}
treehtmlarr.push('</li>');
}
treehtmlarr.push("</ul>");
return treehtmlarr;
},
_removeToggleNodeCallback: function (nodeData)
{
var g = this, p = this.options;
for (var i = 0; i <= g.toggleNodeCallbacks.length; i++)
{
if (g.toggleNodeCallbacks[i] && g.toggleNodeCallbacks[i].data == nodeData)
{
g.toggleNodeCallbacks.splice(i, 1);
break;
}
}
},
//根据简洁的html获取data
_getDataByTreeHTML: function (treeDom)
{
var g = this, p = this.options;
var data = [];
$("> li", treeDom).each(function (i, item)
{
var dataindex = data.length;
data[dataindex] =
{
treedataindex: g.treedataindex++
};
data[dataindex][p.textFieldName] = $("> span,> a", this).html();
for (var j = 0; j < g.sysAttribute.length; j++)
{
if ($(this).attr(g.sysAttribute[j]))
data[dataindex][g.sysAttribute[j]] = $(this).attr(g.sysAttribute[j]);
}
for (var j = 0; j < p.attribute.length; j++)
{
if ($(this).attr(p.attribute[j]))
data[dataindex][p.attribute[j]] = $(this).attr(p.attribute[j]);
}
if ($("> ul", this).length > 0)
{
data[dataindex].children = g._getDataByTreeHTML($("> ul", this));
}
});
return data;
},
_applyTree: function ()
{
var g = this, p = this.options;
g.data = g._getDataByTreeHTML(g.tree);
var gridhtmlarr = g._getTreeHTMLByData(g.data, 1, [], true);
gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = "";
g.tree.html(gridhtmlarr.join(''));
g._upadteTreeWidth();
$(".l-body", g.tree).hover(function ()
{
$(this).addClass("l-over");
}, function ()
{
$(this).removeClass("l-over");
});
},
_getSrcElementByEvent: function (e)
{
var g = this;
var obj = (e.target || e.srcElement);
var tag = obj.tagName.toLowerCase();
var jobjs = $(obj).parents().add(obj);
var fn = function (parm)
{
for (var i = jobjs.length - 1; i >= 0; i--)
{
if ($(jobjs[i]).hasClass(parm)) return jobjs[i];
}
return null;
};
if (jobjs.index(this.element) == -1) return { out: true };
var r = {
tree: fn("l-tree"),
node: fn("l-body"),
checkbox: fn("l-checkbox"),
icon: fn("l-tree-icon"),
text: tag == "span"
};
if (r.node)
{
var treedataindex = parseInt($(r.node).parent().attr("treedataindex"));
r.data = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
}
return r;
},
_setTreeEven: function ()
{
var g = this, p = this.options;
if (g.hasBind('contextmenu'))
{
g.tree.bind("contextmenu", function (e)
{
var obj = (e.target || e.srcElement);
var treeitem = null;
if (obj.tagName.toLowerCase() == "a" || obj.tagName.toLowerCase() == "span" || $(obj).hasClass("l-box"))
treeitem = $(obj).parent().parent();
else if ($(obj).hasClass("l-body"))
treeitem = $(obj).parent();
else if (obj.tagName.toLowerCase() == "li")
treeitem = $(obj);
if (!treeitem) return;
var treedataindex = parseInt(treeitem.attr("treedataindex"));
var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
return g.trigger('contextmenu', [{ data: treenodedata, target: treeitem[0] }, e]);
});
}
g.tree.click(function (e)
{
var obj = (e.target || e.srcElement);
var treeitem = null;
if (obj.tagName.toLowerCase() == "a" || obj.tagName.toLowerCase() == "span" || $(obj).hasClass("l-box"))
treeitem = $(obj).parent().parent();
else if ($(obj).hasClass("l-body"))
treeitem = $(obj).parent();
else
treeitem = $(obj);
if (!treeitem) return;
var treedataindex = parseInt(treeitem.attr("treedataindex"));
var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
var treeitembtn = $("div.l-body:first", treeitem).find("div.l-expandable-open:first,div.l-expandable-close:first");
var clickOnTreeItemBtn = $(obj).hasClass("l-expandable-open") || $(obj).hasClass("l-expandable-close");
if (!$(obj).hasClass("l-checkbox") && !clickOnTreeItemBtn)
{
if (!treeitem.hasClass("l-unselectable"))
{
if ($(">div:first", treeitem).hasClass("l-selected") && p.needCancel)
{
if (g.trigger('beforeCancelSelect', [{ data: treenodedata, target: treeitem[0] }]) == false)
return false;
$(">div:first", treeitem).removeClass("l-selected");
g.trigger('cancelSelect', [{ data: treenodedata, target: treeitem[0] }]);
}
else
{
if (g.trigger('beforeSelect', [{ data: treenodedata, target: treeitem[0] }]) == false)
return false;
$(".l-body", g.tree).removeClass("l-selected");
$(">div:first", treeitem).addClass("l-selected");
g.trigger('select', [{ data: treenodedata, target: treeitem[0] }])
}
}
}
//chekcbox even
if ($(obj).hasClass("l-checkbox"))
{
if (p.autoCheckboxEven)
{
//状态:未选中
if ($(obj).hasClass("l-checkbox-unchecked"))
{
$(obj).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked");
$(".l-children .l-checkbox", treeitem)
.removeClass("l-checkbox-incomplete l-checkbox-unchecked")
.addClass("l-checkbox-checked");
g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]);
}
//状态:选中
else if ($(obj).hasClass("l-checkbox-checked"))
{
$(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");
$(".l-children .l-checkbox", treeitem)
.removeClass("l-checkbox-incomplete l-checkbox-checked")
.addClass("l-checkbox-unchecked");
g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, false]);
}
//状态:未完全选中
else if ($(obj).hasClass("l-checkbox-incomplete"))
{
$(obj).removeClass("l-checkbox-incomplete").addClass("l-checkbox-checked");
$(".l-children .l-checkbox", treeitem)
.removeClass("l-checkbox-incomplete l-checkbox-unchecked")
.addClass("l-checkbox-checked");
g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]);
}
g._setParentCheckboxStatus(treeitem);
}
else
{
//状态:未选中
if ($(obj).hasClass("l-checkbox-unchecked"))
{
$(obj).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked");
//是否单选
if (p.single)
{
$(".l-checkbox", g.tree).not(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");
}
g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]);
}
//状态:选中
else if ($(obj).hasClass("l-checkbox-checked"))
{
$(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");
g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, false]);
}
}
}
//状态:已经张开
else if (treeitembtn.hasClass("l-expandable-open") && (!p.btnClickToToggleOnly || clickOnTreeItemBtn))
{
if (g.trigger('beforeCollapse', [{ data: treenodedata, target: treeitem[0] }]) == false)
return false;
treeitembtn.removeClass("l-expandable-open").addClass("l-expandable-close");
if (p.slide)
$("> .l-children", treeitem).slideToggle('fast');
else
$("> .l-children", treeitem).hide();
$("> div ." + g._getParentNodeClassName(true), treeitem)
.removeClass(g._getParentNodeClassName(true))
.addClass(g._getParentNodeClassName());
g.trigger('collapse', [{ data: treenodedata, target: treeitem[0] }]);
}
//状态:没有张开
else if (treeitembtn.hasClass("l-expandable-close") && (!p.btnClickToToggleOnly || clickOnTreeItemBtn))
{
if (g.trigger('beforeExpand', [{ data: treenodedata, target: treeitem[0] }]) == false)
return false;
$(g.toggleNodeCallbacks).each(function ()
{
if (this.data == treenodedata)
{
this.callback(treeitem[0], treenodedata);
}
});
treeitembtn.removeClass("l-expandable-close").addClass("l-expandable-open");
var callback = function ()
{
g.trigger('expand', [{ data: treenodedata, target: treeitem[0] }]);
};
if (p.slide)
{
$("> .l-children", treeitem).slideToggle('fast', callback);
}
else
{
$("> .l-children", treeitem).show();
callback();
}
$("> div ." + g._getParentNodeClassName(), treeitem)
.removeClass(g._getParentNodeClassName())
.addClass(g._getParentNodeClassName(true));
}
g.trigger('click', [{ data: treenodedata, target: treeitem[0] }]);
});
//节点拖拽支持
if ($.fn.ligerDrag && p.nodeDraggable)
{
g.nodeDroptip = $("<div class='l-drag-nodedroptip' style='display:none'></div>").appendTo('body');
g.tree.ligerDrag({
revert: true, animate: false,
proxyX: 20, proxyY: 20,
proxy: function (draggable, e)
{
var src = g._getSrcElementByEvent(e);
if (src.node)
{
var content = "dragging";
if (p.nodeDraggingRender)
{
content = p.nodeDraggingRender(draggable.draggingNodes, draggable, g);
}
else
{
content = "";
var appended = false;
for (var i in draggable.draggingNodes)
{
var node = draggable.draggingNodes[i];
if (appended) content += ",";
content += node.text;
appended = true;
}
}
var proxy = $("<div class='l-drag-proxy' style='display:none'><div class='l-drop-icon l-drop-no'></div>" + content + "</div>").appendTo('body');
return proxy;
}
},
onRevert: function () { return false; },
onRendered: function ()
{
this.set('cursor', 'default');
g.children[this.id] = this;
},
onStartDrag: function (current, e)
{
if (e.button == 2) return false;
this.set('cursor', 'default');
var src = g._getSrcElementByEvent(e);
if (src.checkbox) return false;
if (p.checkbox)
{
var checked = g.getChecked();
this.draggingNodes = [];
for (var i in checked)
{
this.draggingNodes.push(checked[i].data);
}
if (!this.draggingNodes || !this.draggingNodes.length) return false;
}
else
{
this.draggingNodes = [src.data];
}
this.draggingNode = src.data;
this.set('cursor', 'move');
g.nodedragging = true;
this.validRange = {
top: g.tree.offset().top,
bottom: g.tree.offset().top + g.tree.height(),
left: g.tree.offset().left,
right: g.tree.offset().left + g.tree.width()
};
},
onDrag: function (current, e)
{
var nodedata = this.draggingNode;
if (!nodedata) return false;
var nodes = this.draggingNodes ? this.draggingNodes : [nodedata];
if (g.nodeDropIn == null) g.nodeDropIn = -1;
var pageX = e.pageX;
var pageY = e.pageY;
var visit = false;
var validRange = this.validRange;
if (pageX < validRange.left || pageX > validRange.right
|| pageY > validRange.bottom || pageY < validRange.top)
{
g.nodeDropIn = -1;
g.nodeDroptip.hide();
this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes l-drop-add").addClass("l-drop-no");
return;
}
for (var i = 0, l = g.nodes.length; i < l; i++)
{
var nd = g.nodes[i];
var treedataindex = nd['treedataindex'];
if (nodedata['treedataindex'] == treedataindex) visit = true;
if ($.inArray(nd, nodes) != -1) continue;
var isAfter = visit ? true : false;
if (g.nodeDropIn != -1 && g.nodeDropIn != treedataindex) continue;
var jnode = $("li[treedataindex=" + treedataindex + "] div:first", g.tree);
var offset = jnode.offset();
var range = {
top: offset.top,
bottom: offset.top + jnode.height(),
left: g.tree.offset().left,
right: g.tree.offset().left + g.tree.width()
};
if (pageX > range.left && pageX < range.right && pageY > range.top && pageY < range.bottom)
{
var lineTop = offset.top;
if (isAfter) lineTop += jnode.height();
g.nodeDroptip.css({
left: range.left,
top: lineTop,
width: range.right - range.left
}).show();
g.nodeDropIn = treedataindex;
g.nodeDropDir = isAfter ? "bottom" : "top";
if (pageY > range.top + 7 && pageY < range.bottom - 7)
{
this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no l-drop-yes").addClass("l-drop-add");
g.nodeDroptip.hide();
g.nodeDropInParent = true;
}
else
{
this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no l-drop-add").addClass("l-drop-yes");
g.nodeDroptip.show();
g.nodeDropInParent = false;
}
break;
}
else if (g.nodeDropIn != -1)
{
g.nodeDropIn = -1;
g.nodeDropInParent = false;
g.nodeDroptip.hide();
this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes l-drop-add").addClass("l-drop-no");
}
}
},
onStopDrag: function (current, e)
{
var nodes = this.draggingNodes;
g.nodedragging = false;
if (g.nodeDropIn != -1)
{
for (var i = 0; i < nodes.length; i++)
{
var children = nodes[i].children;
if (children)
{
nodes = $.grep(nodes, function (node, i)
{
var isIn = $.inArray(node, children) == -1;
return isIn;
});
}
}
for (var i in nodes)
{
var node = nodes[i];
if (g.nodeDropInParent)
{
g.remove(node);
g.append(g.nodeDropIn, [node]);
}
else
{
g.remove(node);
g.append(g.getParent(g.nodeDropIn), [node], g.nodeDropIn, g.nodeDropDir == "bottom")
}
}
g.nodeDropIn = -1;
}
g.nodeDroptip.hide();
this.set('cursor', 'default');
}
});
}
},
//递归设置父节点的状态
_setParentCheckboxStatus: function (treeitem)
{
var g = this, p = this.options;
//当前同级别或低级别的节点是否都选中了
var isCheckedComplete = $(".l-checkbox-unchecked", treeitem.parent()).length == 0;
//当前同级别或低级别的节点是否都没有选中
var isCheckedNull = $(".l-checkbox-checked", treeitem.parent()).length == 0;
if (isCheckedNull)
{
treeitem.parent().prev().find("> .l-checkbox")
.removeClass("l-checkbox-checked l-checkbox-incomplete")
.addClass("l-checkbox-unchecked");
}
else
{
if (isCheckedComplete || !p.enabledCompleteCheckbox)
{
treeitem.parent().prev().find(".l-checkbox")
.removeClass("l-checkbox-unchecked l-checkbox-incomplete")
.addClass("l-checkbox-checked");
}
else
{
treeitem.parent().prev().find("> .l-checkbox")
.removeClass("l-checkbox-unchecked l-checkbox-checked")
.addClass("l-checkbox-incomplete");
}
}
if (treeitem.parent().parent("li").length > 0)
g._setParentCheckboxStatus(treeitem.parent().parent("li"));
}
});
function strTrim(str)
{
if (!str) return str;
return str.replace(/(^\s*)|(\s*$)/g, '');
};
})(jQuery);