UU跑腿标准版

ligerTree.js 56KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  1. /**
  2. * jQuery ligerUI 1.2.4
  3. *
  4. * http://ligerui.com
  5. *
  6. * Author daomi 2014 [ gd_star@163.com ]
  7. *
  8. */
  9. (function ($) {
  10. $.fn.ligerTree = function (options) {
  11. return $.ligerui.run.call(this, "ligerTree", arguments);
  12. };
  13. $.fn.ligerGetTreeManager = function () {
  14. return $.ligerui.run.call(this, "ligerGetTreeManager", arguments);
  15. };
  16. $.ligerDefaults.Tree = {
  17. url: null,
  18. data: null,
  19. checkbox: true,
  20. autoCheckboxEven: true,
  21. parentIcon: 'folder',
  22. childIcon: 'leaf',
  23. textFieldName: 'text',
  24. attribute: ['id', 'url'],
  25. treeLine: true, //是否显示line
  26. nodeWidth: 90,
  27. statusName: '__status',
  28. isLeaf: null, //是否子节点的判断函数
  29. single: false, //是否单选
  30. needCancel: true, //已选的是否需要取消操作
  31. onBeforeExpand: function () { },
  32. onContextmenu: function () { },
  33. onExpand: function () { },
  34. onBeforeCollapse: function () { },
  35. onCollapse: function () { },
  36. onBeforeSelect: function () { },
  37. onSelect: function () { },
  38. onBeforeCancelSelect: function () { },
  39. onCancelselect: function () { },
  40. onCheck: function () { },
  41. onSuccess: function () { },
  42. onError: function () { },
  43. onClick: function () { },
  44. idFieldName: 'id',
  45. parentIDFieldName: null,
  46. topParentIDValue: 0,
  47. onBeforeAppend: function () { }, //加载数据前事件,可以通过return false取消操作
  48. onAppend: function () { }, //加载数据时事件,对数据进行预处理以后
  49. onAfterAppend: function () { }, //加载数据完事件
  50. slide: true, //是否以动画的形式显示
  51. iconFieldName: 'icon',
  52. nodeDraggable: false, //是否允许拖拽
  53. nodeDraggingRender: null,
  54. btnClickToToggleOnly: true, //是否点击展开/收缩 按钮时才有效
  55. ajaxType: 'post',
  56. render: null, //自定义函数
  57. selectable: null, //可选择判断函数
  58. /*
  59. 是否展开
  60. 1,可以是true/false
  61. 2,也可以是数字(层次)N 代表第1层到第N层都是展开的,其他收缩
  62. 3,或者是判断函数 函数参数e(data,level) 返回true/false
  63. 优先级没有节点数据的isexpand属性高,并没有delay属性高
  64. */
  65. isExpand: null,
  66. /*
  67. 是否延迟加载
  68. 1,可以是true/false
  69. 2,也可以是数字(层次)N 代表第N层延迟加载
  70. 3,或者是字符串(Url) 加载数据的远程地址
  71. 4,如果是数组,代表这些层都延迟加载,如[1,2]代表第1、2层延迟加载
  72. 5,再是函数(运行时动态获取延迟加载参数) 函数参数e(data,level),返回true/false或者{url:...,parms:...}
  73. 优先级没有节点数据的delay属性高
  74. */
  75. delay: null
  76. };
  77. $.ligerui.controls.Tree = function (element, options) {
  78. $.ligerui.controls.Tree.base.constructor.call(this, element, options);
  79. };
  80. $.ligerui.controls.Tree.ligerExtend($.ligerui.core.UIComponent, {
  81. _init: function () {
  82. $.ligerui.controls.Tree.base._init.call(this);
  83. var g = this, p = this.options;
  84. if (p.single) p.autoCheckboxEven = false;
  85. },
  86. _render: function () {
  87. var g = this, p = this.options;
  88. g.set(p, true);
  89. g.tree = $(g.element);
  90. g.tree.addClass('l-tree');
  91. g.toggleNodeCallbacks = [];
  92. g.sysAttribute = ['isexpand', 'ischecked', 'href', 'style', 'delay'];
  93. g.loading = $("<div class='l-tree-loading'></div>");
  94. g.tree.after(g.loading);
  95. g.data = [];
  96. g.maxOutlineLevel = 1;
  97. g.treedataindex = 0;
  98. g._applyTree();
  99. g._setTreeEven();
  100. g.set(p, false);
  101. },
  102. _setTreeLine: function (value) {
  103. if (value) this.tree.removeClass("l-tree-noline");
  104. else this.tree.addClass("l-tree-noline");
  105. },
  106. _setParms: function () {
  107. var g = this, p = this.options;
  108. if ($.isFunction(p.parms)) p.parms = p.parms();
  109. },
  110. _setUrl: function (url) {
  111. var g = this, p = this.options;
  112. if (url) {
  113. g.clear();
  114. g.loadData(null, url);
  115. }
  116. },
  117. _setData: function (data) {
  118. if (data) {
  119. this.clear();
  120. this.append(null, data);
  121. }
  122. },
  123. setData: function (data) {
  124. this.set('data', data);
  125. },
  126. getData: function () {
  127. return this.data;
  128. },
  129. //是否包含子节点
  130. hasChildren: function (treenodedata) {
  131. if (this.options.isLeaf) return !this.options.isLeaf(treenodedata);
  132. return treenodedata.children ? true : false;
  133. },
  134. //获取父节点 数据
  135. getParent: function (treenode, level) {
  136. var g = this;
  137. treenode = g.getNodeDom(treenode);
  138. var parentTreeNode = g.getParentTreeItem(treenode, level);
  139. if (!parentTreeNode) return null;
  140. var parentIndex = $(parentTreeNode).attr("treedataindex");
  141. return g._getDataNodeByTreeDataIndex(parentIndex);
  142. },
  143. //获取父节点
  144. getParentTreeItem: function (treenode, level) {
  145. var g = this;
  146. treenode = g.getNodeDom(treenode);
  147. var treeitem = $(treenode);
  148. if (treeitem.parent().hasClass("l-tree"))
  149. return null;
  150. if (level == undefined) {
  151. if (treeitem.parent().parent("li").length == 0)
  152. return null;
  153. return treeitem.parent().parent("li")[0];
  154. }
  155. var currentLevel = parseInt(treeitem.attr("outlinelevel"));
  156. var currenttreeitem = treeitem;
  157. for (var i = currentLevel - 1; i >= level; i--) {
  158. currenttreeitem = currenttreeitem.parent().parent("li");
  159. }
  160. return currenttreeitem[0];
  161. },
  162. getChecked: function () {
  163. var g = this, p = this.options;
  164. if (!this.options.checkbox) return null;
  165. var nodes = [];
  166. $(".l-checkbox-checked", g.tree).parent().parent("li").each(function () {
  167. var treedataindex = parseInt($(this).attr("treedataindex"));
  168. nodes.push({ target: this, data: g._getDataNodeByTreeDataIndex(g.data, treedataindex) });
  169. });
  170. return nodes;
  171. },
  172. //add by superzoc 12/24/2012
  173. refreshTree: function () {
  174. var g = this, p = this.options;
  175. $.each(this.getChecked(), function (k, v) {
  176. g._setParentCheckboxStatus($(v.target));
  177. });
  178. },
  179. getSelected: function () {
  180. var g = this, p = this.options;
  181. var node = {};
  182. node.target = $(".l-selected", g.tree).parent("li")[0];
  183. if (node.target) {
  184. var treedataindex = parseInt($(node.target).attr("treedataindex"));
  185. node.data = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  186. return node;
  187. }
  188. return null;
  189. },
  190. //升级为父节点级别
  191. upgrade: function (treeNode) {
  192. var g = this, p = this.options;
  193. $(".l-note", treeNode).each(function () {
  194. $(this).removeClass("l-note").addClass("l-expandable-open");
  195. });
  196. $(".l-note-last", treeNode).each(function () {
  197. $(this).removeClass("l-note-last").addClass("l-expandable-open");
  198. });
  199. $("." + g._getChildNodeClassName(), treeNode).each(function () {
  200. $(this)
  201. .removeClass(g._getChildNodeClassName())
  202. .addClass(g._getParentNodeClassName(true));
  203. });
  204. },
  205. //降级为叶节点级别
  206. demotion: function (treeNode) {
  207. var g = this, p = this.options;
  208. if (!treeNode && treeNode[0].tagName.toLowerCase() != 'li') return;
  209. var islast = $(treeNode).hasClass("l-last");
  210. $(".l-expandable-open", treeNode).each(function () {
  211. $(this).removeClass("l-expandable-open")
  212. .addClass(islast ? "l-note-last" : "l-note");
  213. });
  214. $(".l-expandable-close", treeNode).each(function () {
  215. $(this).removeClass("l-expandable-close")
  216. .addClass(islast ? "l-note-last" : "l-note");
  217. });
  218. $("." + g._getParentNodeClassName(true), treeNode).each(function () {
  219. $(this)
  220. .removeClass(g._getParentNodeClassName(true))
  221. .addClass(g._getChildNodeClassName());
  222. });
  223. },
  224. collapseAll: function () {
  225. var g = this, p = this.options;
  226. $(".l-expandable-open", g.tree).click();
  227. },
  228. expandAll: function () {
  229. var g = this, p = this.options;
  230. $(".l-expandable-close", g.tree).click();
  231. },
  232. loadData: function (node, url, param, e) {
  233. var g = this, p = this.options;
  234. e = $.extend({
  235. showLoading: function () {
  236. g.loading.show();
  237. },
  238. hideLoading: function () {
  239. g.loading.hide();
  240. }
  241. }, e || {});
  242. var ajaxtype = p.ajaxType;
  243. param = param || [];
  244. //请求服务器
  245. $.ajax({
  246. type: ajaxtype,
  247. url: url,
  248. data: param,
  249. dataType: 'json',
  250. cache: false,
  251. beforeSend: function () {
  252. e.showLoading();
  253. },
  254. success: function (data) {
  255. if (!data) return;
  256. e.hideLoading();
  257. g.append(node, data);
  258. g.trigger('success', [data]);
  259. },
  260. error: function (XMLHttpRequest, textStatus, errorThrown) {
  261. try {
  262. e.hideLoading();
  263. g.trigger('error', [XMLHttpRequest, textStatus, errorThrown]);
  264. }
  265. catch (e) {
  266. }
  267. }
  268. });
  269. },
  270. //清空
  271. clear: function () {
  272. var g = this, p = this.options;
  273. g.toggleNodeCallbacks = [];
  274. g.data = null;
  275. g.data = [];
  276. g.nodes = null;
  277. g.tree.html("");
  278. },
  279. //parm [treeNode] dom节点(li)、节点数据 或者节点 dataindex
  280. getNodeDom: function (nodeParm) {
  281. var g = this, p = this.options;
  282. if (nodeParm == null) return nodeParm;
  283. if (typeof (nodeParm) == "string" || typeof (nodeParm) == "number") {
  284. return $("li[treedataindex=" + nodeParm + "]", g.tree).get(0);
  285. }
  286. else if (typeof (nodeParm) == "object" && 'treedataindex' in nodeParm) //nodedata
  287. {
  288. return g.getNodeDom(nodeParm['treedataindex']);
  289. }
  290. return nodeParm;
  291. },
  292. hide: function (treeNode) {
  293. var g = this, p = this.options;
  294. treeNode = g.getNodeDom(treeNode);
  295. if (treeNode) $(treeNode).hide();
  296. },
  297. show: function (treeNode) {
  298. var g = this, p = this.options;
  299. treeNode = g.getNodeDom(treeNode);
  300. if (treeNode) $(treeNode).show();
  301. },
  302. //parm [treeNode] dom节点(li)、节点数据 或者节点 dataindex
  303. remove: function (treeNode) {
  304. var g = this, p = this.options;
  305. treeNode = g.getNodeDom(treeNode);
  306. var treedataindex = parseInt($(treeNode).attr("treedataindex"));
  307. var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  308. if (treenodedata) g._setTreeDataStatus([treenodedata], 'delete');
  309. var parentNode = g.getParentTreeItem(treeNode);
  310. //复选框处理
  311. if (p.checkbox) {
  312. g._setParentCheckboxStatus($(treeNode));
  313. }
  314. $(treeNode).remove();
  315. g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree);
  316. },
  317. _updateStyle: function (ul) {
  318. var g = this, p = this.options;
  319. var itmes = $(" > li", ul);
  320. var treeitemlength = itmes.length;
  321. if (!treeitemlength) return;
  322. //遍历设置子节点的样式
  323. itmes.each(function (i, item) {
  324. if (i == 0 && !$(this).hasClass("l-first"))
  325. $(this).addClass("l-first");
  326. if (i == treeitemlength - 1 && !$(this).hasClass("l-last"))
  327. $(this).addClass("l-last");
  328. if (i == 0 && i == treeitemlength - 1)
  329. $(this).addClass("l-onlychild");
  330. $("> div .l-note,> div .l-note-last", this)
  331. .removeClass("l-note l-note-last")
  332. .addClass(i == treeitemlength - 1 ? "l-note-last" : "l-note");
  333. g._setTreeItem(this, { isLast: i == treeitemlength - 1 });
  334. });
  335. },
  336. //parm [domnode] dom节点(li)、节点数据 或者节点 dataindex
  337. update: function (domnode, newnodedata) {
  338. var g = this, p = this.options;
  339. domnode = g.getNodeDom(domnode);
  340. var treedataindex = parseInt($(domnode).attr("treedataindex"));
  341. nodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  342. for (var attr in newnodedata) {
  343. nodedata[attr] = newnodedata[attr];
  344. if (attr == p.textFieldName) {
  345. $("> .l-body > span", domnode).text(newnodedata[attr]);
  346. }
  347. }
  348. },
  349. //增加节点集合
  350. //parm [newdata] 数据集合 Array
  351. //parm [parentNode] dom节点(li)、节点数据 或者节点 dataindex
  352. //parm [nearNode] 附加到节点的上方/下方(非必填)
  353. //parm [isAfter] 附加到节点的下方(非必填)
  354. append: function (parentNode, newdata, nearNode, isAfter) {
  355. var g = this, p = this.options;
  356. parentNode = g.getNodeDom(parentNode);
  357. if (g.trigger('beforeAppend', [parentNode, newdata]) == false) return false;
  358. if (!newdata || !newdata.length) return false;
  359. if (p.idFieldName && p.parentIDFieldName)
  360. newdata = g.arrayToTree(newdata, p.idFieldName, p.parentIDFieldName);
  361. g._addTreeDataIndexToData(newdata);
  362. g._setTreeDataStatus(newdata, 'add');
  363. if (nearNode != null) {
  364. nearNode = g.getNodeDom(nearNode);
  365. }
  366. g.trigger('append', [parentNode, newdata])
  367. g._appendData(parentNode, newdata);
  368. if (parentNode == null)//增加到根节点
  369. {
  370. var gridhtmlarr = g._getTreeHTMLByData(newdata, 1, [], true);
  371. gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = "";
  372. if (nearNode != null) {
  373. $(nearNode)[isAfter ? 'after' : 'before'](gridhtmlarr.join(''));
  374. g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree);
  375. }
  376. else {
  377. //remove last node class
  378. if ($("> li:last", g.tree).length > 0)
  379. g._setTreeItem($("> li:last", g.tree)[0], { isLast: false });
  380. g.tree.append(gridhtmlarr.join(''));
  381. }
  382. $(".l-body", g.tree).hover(function () {
  383. $(this).addClass("l-over");
  384. }, function () {
  385. $(this).removeClass("l-over");
  386. });
  387. g._upadteTreeWidth();
  388. g.trigger('afterAppend', [parentNode, newdata])
  389. return;
  390. }
  391. var treeitem = $(parentNode);
  392. var outlineLevel = parseInt(treeitem.attr("outlinelevel"));
  393. var hasChildren = $("> ul", treeitem).length > 0;
  394. if (!hasChildren) {
  395. treeitem.append("<ul class='l-children'></ul>");
  396. //设置为父节点
  397. g.upgrade(parentNode);
  398. }
  399. var isLast = [];
  400. for (var i = 1; i <= outlineLevel - 1; i++) {
  401. var currentParentTreeItem = $(g.getParentTreeItem(parentNode, i));
  402. isLast.push(currentParentTreeItem.hasClass("l-last"));
  403. }
  404. isLast.push(treeitem.hasClass("l-last"));
  405. var gridhtmlarr = g._getTreeHTMLByData(newdata, outlineLevel + 1, isLast, true);
  406. gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = "";
  407. if (nearNode != null) {
  408. $(nearNode)[isAfter ? 'after' : 'before'](gridhtmlarr.join(''));
  409. g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree);
  410. }
  411. else {
  412. //remove last node class
  413. if ($("> .l-children > li:last", treeitem).length > 0)
  414. g._setTreeItem($("> .l-children > li:last", treeitem)[0], { isLast: false });
  415. $(">.l-children", parentNode).append(gridhtmlarr.join(''));
  416. }
  417. g._upadteTreeWidth();
  418. $(">.l-children .l-body", parentNode).hover(function () {
  419. $(this).addClass("l-over");
  420. }, function () {
  421. $(this).removeClass("l-over");
  422. });
  423. g.trigger('afterAppend', [parentNode, newdata]);
  424. },
  425. //parm [nodeParm] dom节点(li)、节点数据 或者节点 dataindex
  426. cancelSelect: function (nodeParm) {
  427. var g = this, p = this.options;
  428. var domNode = g.getNodeDom(nodeParm);
  429. var treeitem = $(domNode);
  430. var treedataindex = parseInt(treeitem.attr("treedataindex"));
  431. var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  432. var treeitembody = $(">div:first", treeitem);
  433. if (p.checkbox)
  434. $(".l-checkbox", treeitembody).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");
  435. else
  436. treeitembody.removeClass("l-selected");
  437. g.trigger('cancelSelect', [{ data: treenodedata, target: treeitem[0]}]);
  438. },
  439. //选择节点(参数:条件函数、Dom节点或ID值)
  440. selectNode: function (selectNodeParm) {
  441. var g = this, p = this.options;
  442. var clause = null;
  443. if (typeof (selectNodeParm) == "function") {
  444. clause = selectNodeParm;
  445. }
  446. else if (typeof (selectNodeParm) == "object") {
  447. var treeitem = $(selectNodeParm);
  448. var treedataindex = parseInt(treeitem.attr("treedataindex"));
  449. var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  450. var treeitembody = $(">div:first", treeitem);
  451. if (!treeitembody.length) {
  452. treeitembody = $("li[treedataindex=" + treedataindex + "] >div:first", g.tree);
  453. }
  454. if (p.checkbox) {
  455. $(".l-checkbox", treeitembody).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked");
  456. }
  457. else {
  458. $("div.l-selected", g.tree).removeClass("l-selected");
  459. treeitembody.addClass("l-selected");
  460. }
  461. g.trigger('select', [{ data: treenodedata, target: treeitembody.parent().get(0)}]);
  462. return;
  463. }
  464. else {
  465. clause = function (data) {
  466. if (!data[p.idFieldName]) return false;
  467. return data[p.idFieldName].toString() == selectNodeParm.toString();
  468. };
  469. }
  470. $("li", g.tree).each(function () {
  471. var treeitem = $(this);
  472. var treedataindex = parseInt(treeitem.attr("treedataindex"));
  473. var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  474. if (clause(treenodedata, treedataindex)) {
  475. g.selectNode(this);
  476. }
  477. else {
  478. g.cancelSelect(this);
  479. }
  480. });
  481. },
  482. getTextByID: function (id) {
  483. var g = this, p = this.options;
  484. var data = g.getDataByID(id);
  485. if (!data) return null;
  486. return data[p.textFieldName];
  487. },
  488. getDataByID: function (id) {
  489. var g = this, p = this.options;
  490. var data = null;
  491. $("li", g.tree).each(function () {
  492. if (data) return;
  493. var treeitem = $(this);
  494. var treedataindex = parseInt(treeitem.attr("treedataindex"));
  495. var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  496. if (treenodedata[p.idFieldName].toString() == id.toString()) {
  497. data = treenodedata;
  498. }
  499. });
  500. return data;
  501. },
  502. arrayToTree: function (data, id, pid) //将ID、ParentID这种数据格式转换为树格式
  503. {
  504. if (!data || !data.length) return [];
  505. var targetData = []; //存储数据的容器(返回)
  506. var records = {};
  507. var itemLength = data.length; //数据集合的个数
  508. for (var i = 0; i < itemLength; i++) {
  509. var o = data[i];
  510. records[o[id]] = o;
  511. }
  512. for (var i = 0; i < itemLength; i++) {
  513. var currentData = data[i];
  514. var parentData = records[currentData[pid]];
  515. if (!parentData) {
  516. targetData.push(currentData);
  517. continue;
  518. }
  519. parentData.children = parentData.children || [];
  520. parentData.children.push(currentData);
  521. }
  522. return targetData;
  523. },
  524. //根据数据索引获取数据
  525. _getDataNodeByTreeDataIndex: function (data, treedataindex) {
  526. var g = this, p = this.options;
  527. for (var i = 0; i < data.length; i++) {
  528. if (data[i].treedataindex == treedataindex)
  529. return data[i];
  530. if (data[i].children) {
  531. var targetData = g._getDataNodeByTreeDataIndex(data[i].children, treedataindex);
  532. if (targetData) return targetData;
  533. }
  534. }
  535. return null;
  536. },
  537. //设置数据状态
  538. _setTreeDataStatus: function (data, status) {
  539. var g = this, p = this.options;
  540. $(data).each(function () {
  541. this[p.statusName] = status;
  542. if (this.children) {
  543. g._setTreeDataStatus(this.children, status);
  544. }
  545. });
  546. },
  547. //设置data 索引
  548. _addTreeDataIndexToData: function (data) {
  549. var g = this, p = this.options;
  550. $(data).each(function () {
  551. if (this.treedataindex != undefined) return;
  552. this.treedataindex = g.treedataindex++;
  553. if (this.children) {
  554. g._addTreeDataIndexToData(this.children);
  555. }
  556. });
  557. },
  558. _addToNodes: function (data) {
  559. var g = this, p = this.options;
  560. g.nodes = g.nodes || [];
  561. g.nodes.push(data);
  562. if (!data.children) return;
  563. $(data.children).each(function (i, item) {
  564. g._addToNodes(item);
  565. });
  566. },
  567. //添加项到g.data
  568. _appendData: function (treeNode, data) {
  569. var g = this, p = this.options;
  570. var treedataindex = parseInt($(treeNode).attr("treedataindex"));
  571. var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  572. if (g.treedataindex == undefined) g.treedataindex = 0;
  573. if (treenodedata && treenodedata.children == undefined) treenodedata.children = [];
  574. $(data).each(function (i, item) {
  575. if (treenodedata)
  576. treenodedata.children[treenodedata.children.length] = item;
  577. else
  578. g.data[g.data.length] = item;
  579. g._addToNodes(item);
  580. });
  581. },
  582. _setTreeItem: function (treeNode, options) {
  583. var g = this, p = this.options;
  584. if (!options) return;
  585. treeNode = g.getNodeDom(treeNode);
  586. var treeItem = $(treeNode);
  587. var outlineLevel = parseInt(treeItem.attr("outlinelevel"));
  588. if (options.isLast != undefined) {
  589. if (options.isLast == true) {
  590. treeItem.removeClass("l-last").addClass("l-last");
  591. $("> div .l-note", treeItem).removeClass("l-note").addClass("l-note-last");
  592. $(".l-children li", treeItem)
  593. .find(".l-box:eq(" + (outlineLevel - 1) + ")")
  594. .removeClass("l-line");
  595. }
  596. else if (options.isLast == false) {
  597. treeItem.removeClass("l-last");
  598. $("> div .l-note-last", treeItem).removeClass("l-note-last").addClass("l-note");
  599. $(".l-children li", treeItem)
  600. .find(".l-box:eq(" + (outlineLevel - 1) + ")")
  601. .removeClass("l-line")
  602. .addClass("l-line");
  603. }
  604. }
  605. },
  606. _upadteTreeWidth: function () {
  607. var g = this, p = this.options;
  608. var treeWidth = g.maxOutlineLevel * 22;
  609. if (p.checkbox) treeWidth += 22;
  610. if (p.parentIcon || p.childIcon) treeWidth += 22;
  611. treeWidth += p.nodeWidth;
  612. g.tree.width(treeWidth);
  613. },
  614. _getChildNodeClassName: function () {
  615. var g = this, p = this.options;
  616. return 'l-tree-icon-' + p.childIcon;
  617. },
  618. _getParentNodeClassName: function (isOpen) {
  619. var g = this, p = this.options;
  620. var nodeclassname = 'l-tree-icon-' + p.parentIcon;
  621. if (isOpen) nodeclassname += '-open';
  622. return nodeclassname;
  623. },
  624. //判断节点是否展开状态,返回true/false
  625. _isExpand: function (o, level) {
  626. var g = this, p = this.options;
  627. var isExpand = o.isExpand != null ? o.isExpand : (o.isexpand != null ? o.isexpand : p.isExpand);
  628. if (isExpand == null) return true;
  629. if (typeof (isExpand) == "function") isExpand = p.isExpand({ data: o, level: level });
  630. if (typeof (isExpand) == "boolean") return isExpand;
  631. if (typeof (isExpand) == "string") return isExpand == "true";
  632. if (typeof (isExpand) == "number") return isExpand > level;
  633. return true;
  634. },
  635. //获取节点的延迟加载状态,返回true/false (本地模式) 或者是object({url :'...',parms:null})(远程模式)
  636. _getDelay: function (o, level) {
  637. var g = this, p = this.options;
  638. var delay = o.delay != null ? o.delay : p.delay;
  639. if (delay == null) return false;
  640. if (typeof (delay) == "function") delay = delay({ data: o, level: level });
  641. if (typeof (delay) == "boolean") return delay;
  642. if (typeof (delay) == "string") return { url: delay };
  643. if (typeof (delay) == "number") delay = [delay];
  644. if ($.isArray(delay)) return $.inArray(level, delay) != -1;
  645. if (typeof (delay) == "object" && delay.url) return delay;
  646. return false;
  647. },
  648. //根据data生成最终完整的tree html
  649. _getTreeHTMLByData: function (data, outlineLevel, isLast, isExpand) {
  650. var g = this, p = this.options;
  651. if (g.maxOutlineLevel < outlineLevel)
  652. g.maxOutlineLevel = outlineLevel;
  653. isLast = isLast || [];
  654. outlineLevel = outlineLevel || 1;
  655. var treehtmlarr = [];
  656. if (!isExpand) treehtmlarr.push('<ul class="l-children" style="display:none">');
  657. else treehtmlarr.push("<ul class='l-children'>");
  658. for (var i = 0; i < data.length; i++) {
  659. var o = data[i];
  660. var isFirst = i == 0;
  661. var isLastCurrent = i == data.length - 1;
  662. var delay = g._getDelay(o, outlineLevel);
  663. var isExpandCurrent = delay ? false : g._isExpand(o, outlineLevel);
  664. treehtmlarr.push('<li ');
  665. if (o.treedataindex != undefined)
  666. treehtmlarr.push('treedataindex="' + o.treedataindex + '" ');
  667. if (isExpandCurrent)
  668. treehtmlarr.push('isexpand=' + o.isexpand + ' ');
  669. treehtmlarr.push('outlinelevel=' + outlineLevel + ' ');
  670. //增加属性支持
  671. for (var j = 0; j < g.sysAttribute.length; j++) {
  672. if ($(this).attr(g.sysAttribute[j]))
  673. data[dataindex][g.sysAttribute[j]] = $(this).attr(g.sysAttribute[j]);
  674. }
  675. for (var j = 0; j < p.attribute.length; j++) {
  676. if (o[p.attribute[j]])
  677. treehtmlarr.push(p.attribute[j] + '="' + o[p.attribute[j]] + '" ');
  678. }
  679. //css class
  680. treehtmlarr.push('class="');
  681. isFirst && treehtmlarr.push('l-first ');
  682. isLastCurrent && treehtmlarr.push('l-last ');
  683. isFirst && isLastCurrent && treehtmlarr.push('l-onlychild ');
  684. treehtmlarr.push('"');
  685. treehtmlarr.push('>');
  686. treehtmlarr.push('<div class="l-body');
  687. if (p.selectable && p.selectable(o) == false) {
  688. treehtmlarr.push(' l-unselectable');
  689. }
  690. treehtmlarr.push('">');
  691. for (var k = 0; k <= outlineLevel - 2; k++) {
  692. if (isLast[k]) treehtmlarr.push('<div class="l-box"></div>');
  693. else treehtmlarr.push('<div class="l-box l-line"></div>');
  694. }
  695. if (g.hasChildren(o)) {
  696. if (isExpandCurrent) treehtmlarr.push('<div class="l-box l-expandable-open"></div>');
  697. else treehtmlarr.push('<div class="l-box l-expandable-close"></div>');
  698. if (p.checkbox) {
  699. if (o.ischecked)
  700. treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-checked"></div>');
  701. else
  702. treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-unchecked"></div>');
  703. }
  704. if (p.parentIcon) {
  705. //node icon
  706. treehtmlarr.push('<div class="l-box l-tree-icon ');
  707. treehtmlarr.push(g._getParentNodeClassName(isExpandCurrent ? true : false) + " ");
  708. if (p.iconFieldName && o[p.iconFieldName])
  709. treehtmlarr.push('l-tree-icon-none');
  710. treehtmlarr.push('">');
  711. if (p.iconFieldName && o[p.iconFieldName])
  712. treehtmlarr.push('<img src="' + o[p.iconFieldName] + '" />');
  713. treehtmlarr.push('</div>');
  714. }
  715. }
  716. else {
  717. if (isLastCurrent) treehtmlarr.push('<div class="l-box l-note-last"></div>');
  718. else treehtmlarr.push('<div class="l-box l-note"></div>');
  719. if (p.checkbox) {
  720. if (o.ischecked)
  721. treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-checked"></div>');
  722. else
  723. treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-unchecked"></div>');
  724. }
  725. if (p.childIcon) {
  726. //node icon
  727. treehtmlarr.push('<div class="l-box l-tree-icon ');
  728. treehtmlarr.push(g._getChildNodeClassName() + " ");
  729. if (p.iconFieldName && o[p.iconFieldName])
  730. treehtmlarr.push('l-tree-icon-none');
  731. treehtmlarr.push('">');
  732. if (p.iconFieldName && o[p.iconFieldName])
  733. treehtmlarr.push('<img src="' + o[p.iconFieldName] + '" />');
  734. treehtmlarr.push('</div>');
  735. }
  736. }
  737. if (p.render) {
  738. treehtmlarr.push('<span>' + p.render(o, o[p.textFieldName]) + '</span>');
  739. } else {
  740. treehtmlarr.push('<span>' + o[p.textFieldName] + '</span>');
  741. }
  742. treehtmlarr.push('</div>');
  743. if (g.hasChildren(o)) {
  744. var isLastNew = [];
  745. for (var k = 0; k < isLast.length; k++) {
  746. isLastNew.push(isLast[k]);
  747. }
  748. isLastNew.push(isLastCurrent);
  749. if (delay) {
  750. if (delay == true) {
  751. g.toggleNodeCallbacks.push({
  752. data: o,
  753. callback: function (dom, o) {
  754. var content = g._getTreeHTMLByData(o.children, outlineLevel + 1, isLastNew, isExpandCurrent).join('');
  755. $(dom).append(content);
  756. $(">.l-children .l-body", dom).hover(function () {
  757. $(this).addClass("l-over");
  758. }, function () {
  759. $(this).removeClass("l-over");
  760. });
  761. g._removeToggleNodeCallback(o);
  762. }
  763. });
  764. }
  765. else if (delay.url) {
  766. (function (o, url, parms) {
  767. g.toggleNodeCallbacks.push({
  768. data: o,
  769. callback: function (dom, o) {
  770. g.loadData(dom, url, parms, {
  771. showLoading: function () {
  772. $("div.l-expandable-close:first", dom).addClass("l-box-loading");
  773. },
  774. hideLoading: function () {
  775. $("div.l-box-loading:first", dom).removeClass("l-box-loading");
  776. }
  777. });
  778. g._removeToggleNodeCallback(o);
  779. }
  780. });
  781. })(o, delay.url, delay.parms);
  782. }
  783. }
  784. else {
  785. treehtmlarr.push(g._getTreeHTMLByData(o.children, outlineLevel + 1, isLastNew, isExpandCurrent).join(''));
  786. }
  787. }
  788. treehtmlarr.push('</li>');
  789. }
  790. treehtmlarr.push("</ul>");
  791. return treehtmlarr;
  792. },
  793. _removeToggleNodeCallback: function (nodeData) {
  794. var g = this, p = this.options;
  795. for (var i = 0; i <= g.toggleNodeCallbacks.length; i++) {
  796. if (g.toggleNodeCallbacks[i] && g.toggleNodeCallbacks[i].data == nodeData) {
  797. g.toggleNodeCallbacks.splice(i, 1);
  798. break;
  799. }
  800. }
  801. },
  802. //根据简洁的html获取data
  803. _getDataByTreeHTML: function (treeDom) {
  804. var g = this, p = this.options;
  805. var data = [];
  806. $("> li", treeDom).each(function (i, item) {
  807. var dataindex = data.length;
  808. data[dataindex] =
  809. {
  810. treedataindex: g.treedataindex++
  811. };
  812. data[dataindex][p.textFieldName] = $("> span,> a", this).html();
  813. for (var j = 0; j < g.sysAttribute.length; j++) {
  814. if ($(this).attr(g.sysAttribute[j]))
  815. data[dataindex][g.sysAttribute[j]] = $(this).attr(g.sysAttribute[j]);
  816. }
  817. for (var j = 0; j < p.attribute.length; j++) {
  818. if ($(this).attr(p.attribute[j]))
  819. data[dataindex][p.attribute[j]] = $(this).attr(p.attribute[j]);
  820. }
  821. if ($("> ul", this).length > 0) {
  822. data[dataindex].children = g._getDataByTreeHTML($("> ul", this));
  823. }
  824. });
  825. return data;
  826. },
  827. _applyTree: function () {
  828. var g = this, p = this.options;
  829. g.data = g._getDataByTreeHTML(g.tree);
  830. var gridhtmlarr = g._getTreeHTMLByData(g.data, 1, [], true);
  831. gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = "";
  832. g.tree.html(gridhtmlarr.join(''));
  833. g._upadteTreeWidth();
  834. $(".l-body", g.tree).hover(function () {
  835. $(this).addClass("l-over");
  836. }, function () {
  837. $(this).removeClass("l-over");
  838. });
  839. },
  840. _getSrcElementByEvent: function (e) {
  841. var g = this;
  842. var obj = (e.target || e.srcElement);
  843. var tag = obj.tagName.toLowerCase();
  844. var jobjs = $(obj).parents().add(obj);
  845. var fn = function (parm) {
  846. for (var i = jobjs.length - 1; i >= 0; i--) {
  847. if ($(jobjs[i]).hasClass(parm)) return jobjs[i];
  848. }
  849. return null;
  850. };
  851. if (jobjs.index(this.element) == -1) return { out: true };
  852. var r = {
  853. tree: fn("l-tree"),
  854. node: fn("l-body"),
  855. checkbox: fn("l-checkbox"),
  856. icon: fn("l-tree-icon"),
  857. text: tag == "span"
  858. };
  859. if (r.node) {
  860. var treedataindex = parseInt($(r.node).parent().attr("treedataindex"));
  861. r.data = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  862. }
  863. return r;
  864. },
  865. _setTreeEven: function () {
  866. var g = this, p = this.options;
  867. if (g.hasBind('contextmenu')) {
  868. g.tree.bind("contextmenu", function (e) {
  869. var obj = (e.target || e.srcElement);
  870. var treeitem = null;
  871. if (obj.tagName.toLowerCase() == "a" || obj.tagName.toLowerCase() == "span" || $(obj).hasClass("l-box"))
  872. treeitem = $(obj).parent().parent();
  873. else if ($(obj).hasClass("l-body"))
  874. treeitem = $(obj).parent();
  875. else if (obj.tagName.toLowerCase() == "li")
  876. treeitem = $(obj);
  877. if (!treeitem) return;
  878. var treedataindex = parseInt(treeitem.attr("treedataindex"));
  879. var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  880. return g.trigger('contextmenu', [{ data: treenodedata, target: treeitem[0] }, e]);
  881. });
  882. }
  883. g.tree.click(function (e) {
  884. var obj = (e.target || e.srcElement);
  885. var treeitem = null;
  886. if (obj.tagName.toLowerCase() == "a" || obj.tagName.toLowerCase() == "span" || $(obj).hasClass("l-box"))
  887. treeitem = $(obj).parent().parent();
  888. else if ($(obj).hasClass("l-body"))
  889. treeitem = $(obj).parent();
  890. else
  891. treeitem = $(obj);
  892. if (!treeitem) return;
  893. var treedataindex = parseInt(treeitem.attr("treedataindex"));
  894. var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex);
  895. var treeitembtn = $("div.l-body:first", treeitem).find("div.l-expandable-open:first,div.l-expandable-close:first");
  896. var clickOnTreeItemBtn = $(obj).hasClass("l-expandable-open") || $(obj).hasClass("l-expandable-close");
  897. if (!$(obj).hasClass("l-checkbox") && !clickOnTreeItemBtn) {
  898. if (!treeitem.hasClass("l-unselectable")) {
  899. if ($(">div:first", treeitem).hasClass("l-selected") && p.needCancel) {
  900. if (g.trigger('beforeCancelSelect', [{ data: treenodedata, target: treeitem[0]}]) == false)
  901. return false;
  902. $(">div:first", treeitem).removeClass("l-selected");
  903. g.trigger('cancelSelect', [{ data: treenodedata, target: treeitem[0]}]);
  904. }
  905. else {
  906. if (g.trigger('beforeSelect', [{ data: treenodedata, target: treeitem[0]}]) == false)
  907. return false;
  908. $(".l-body", g.tree).removeClass("l-selected");
  909. $(">div:first", treeitem).addClass("l-selected");
  910. g.trigger('select', [{ data: treenodedata, target: treeitem[0]}])
  911. }
  912. }
  913. }
  914. //chekcbox even
  915. if ($(obj).hasClass("l-checkbox")) {
  916. if (p.autoCheckboxEven) {
  917. //状态:未选中
  918. if ($(obj).hasClass("l-checkbox-unchecked")) {
  919. $(obj).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked");
  920. $(".l-children .l-checkbox", treeitem)
  921. .removeClass("l-checkbox-incomplete l-checkbox-unchecked")
  922. .addClass("l-checkbox-checked");
  923. g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]);
  924. }
  925. //状态:选中
  926. else if ($(obj).hasClass("l-checkbox-checked")) {
  927. $(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");
  928. $(".l-children .l-checkbox", treeitem)
  929. .removeClass("l-checkbox-incomplete l-checkbox-checked")
  930. .addClass("l-checkbox-unchecked");
  931. g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, false]);
  932. }
  933. //状态:未完全选中
  934. else if ($(obj).hasClass("l-checkbox-incomplete")) {
  935. $(obj).removeClass("l-checkbox-incomplete").addClass("l-checkbox-checked");
  936. $(".l-children .l-checkbox", treeitem)
  937. .removeClass("l-checkbox-incomplete l-checkbox-unchecked")
  938. .addClass("l-checkbox-checked");
  939. g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]);
  940. }
  941. g._setParentCheckboxStatus(treeitem);
  942. }
  943. else {
  944. //状态:未选中
  945. if ($(obj).hasClass("l-checkbox-unchecked")) {
  946. $(obj).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked");
  947. //是否单选
  948. if (p.single) {
  949. $(".l-checkbox", g.tree).not(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");
  950. }
  951. g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]);
  952. }
  953. //状态:选中
  954. else if ($(obj).hasClass("l-checkbox-checked")) {
  955. $(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");
  956. g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, false]);
  957. }
  958. }
  959. }
  960. //状态:已经张开
  961. else if (treeitembtn.hasClass("l-expandable-open") && (!p.btnClickToToggleOnly || clickOnTreeItemBtn)) {
  962. if (g.trigger('beforeCollapse', [{ data: treenodedata, target: treeitem[0]}]) == false)
  963. return false;
  964. treeitembtn.removeClass("l-expandable-open").addClass("l-expandable-close");
  965. if (p.slide)
  966. $("> .l-children", treeitem).slideToggle('fast');
  967. else
  968. $("> .l-children", treeitem).hide();
  969. $("> div ." + g._getParentNodeClassName(true), treeitem)
  970. .removeClass(g._getParentNodeClassName(true))
  971. .addClass(g._getParentNodeClassName());
  972. g.trigger('collapse', [{ data: treenodedata, target: treeitem[0]}]);
  973. }
  974. //状态:没有张开
  975. else if (treeitembtn.hasClass("l-expandable-close") && (!p.btnClickToToggleOnly || clickOnTreeItemBtn)) {
  976. if (g.trigger('beforeExpand', [{ data: treenodedata, target: treeitem[0]}]) == false)
  977. return false;
  978. $(g.toggleNodeCallbacks).each(function () {
  979. if (this.data == treenodedata) {
  980. this.callback(treeitem[0], treenodedata);
  981. }
  982. });
  983. treeitembtn.removeClass("l-expandable-close").addClass("l-expandable-open");
  984. var callback = function () {
  985. g.trigger('expand', [{ data: treenodedata, target: treeitem[0]}]);
  986. };
  987. if (p.slide) {
  988. $("> .l-children", treeitem).slideToggle('fast', callback);
  989. }
  990. else {
  991. $("> .l-children", treeitem).show();
  992. callback();
  993. }
  994. $("> div ." + g._getParentNodeClassName(), treeitem)
  995. .removeClass(g._getParentNodeClassName())
  996. .addClass(g._getParentNodeClassName(true));
  997. }
  998. g.trigger('click', [{ data: treenodedata, target: treeitem[0]}]);
  999. });
  1000. //节点拖拽支持
  1001. if ($.fn.ligerDrag && p.nodeDraggable) {
  1002. g.nodeDroptip = $("<div class='l-drag-nodedroptip' style='display:none'></div>").appendTo('body');
  1003. g.tree.ligerDrag({
  1004. revert: true, animate: false,
  1005. proxyX: 20, proxyY: 20,
  1006. proxy: function (draggable, e) {
  1007. var src = g._getSrcElementByEvent(e);
  1008. if (src.node) {
  1009. var content = "dragging";
  1010. if (p.nodeDraggingRender) {
  1011. content = p.nodeDraggingRender(draggable.draggingNodes, draggable, g);
  1012. }
  1013. else {
  1014. content = "";
  1015. var appended = false;
  1016. for (var i in draggable.draggingNodes) {
  1017. var node = draggable.draggingNodes[i];
  1018. if (appended) content += ",";
  1019. content += node.text;
  1020. appended = true;
  1021. }
  1022. }
  1023. var proxy = $("<div class='l-drag-proxy' style='display:none'><div class='l-drop-icon l-drop-no'></div>" + content + "</div>").appendTo('body');
  1024. return proxy;
  1025. }
  1026. },
  1027. onRevert: function () { return false; },
  1028. onRendered: function () {
  1029. this.set('cursor', 'default');
  1030. g.children[this.id] = this;
  1031. },
  1032. onStartDrag: function (current, e) {
  1033. if (e.button == 2) return false;
  1034. this.set('cursor', 'default');
  1035. var src = g._getSrcElementByEvent(e);
  1036. if (src.checkbox) return false;
  1037. if (p.checkbox) {
  1038. var checked = g.getChecked();
  1039. this.draggingNodes = [];
  1040. for (var i in checked) {
  1041. this.draggingNodes.push(checked[i].data);
  1042. }
  1043. if (!this.draggingNodes || !this.draggingNodes.length) return false;
  1044. }
  1045. else {
  1046. this.draggingNodes = [src.data];
  1047. }
  1048. this.draggingNode = src.data;
  1049. this.set('cursor', 'move');
  1050. g.nodedragging = true;
  1051. this.validRange = {
  1052. top: g.tree.offset().top,
  1053. bottom: g.tree.offset().top + g.tree.height(),
  1054. left: g.tree.offset().left,
  1055. right: g.tree.offset().left + g.tree.width()
  1056. };
  1057. },
  1058. onDrag: function (current, e) {
  1059. var nodedata = this.draggingNode;
  1060. if (!nodedata) return false;
  1061. var nodes = this.draggingNodes ? this.draggingNodes : [nodedata];
  1062. if (g.nodeDropIn == null) g.nodeDropIn = -1;
  1063. var pageX = e.pageX;
  1064. var pageY = e.pageY;
  1065. var visit = false;
  1066. var validRange = this.validRange;
  1067. if (pageX < validRange.left || pageX > validRange.right
  1068. || pageY > validRange.bottom || pageY < validRange.top) {
  1069. g.nodeDropIn = -1;
  1070. g.nodeDroptip.hide();
  1071. this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes l-drop-add").addClass("l-drop-no");
  1072. return;
  1073. }
  1074. for (var i = 0, l = g.nodes.length; i < l; i++) {
  1075. var nd = g.nodes[i];
  1076. var treedataindex = nd['treedataindex'];
  1077. if (nodedata['treedataindex'] == treedataindex) visit = true;
  1078. if ($.inArray(nd, nodes) != -1) continue;
  1079. var isAfter = visit ? true : false;
  1080. if (g.nodeDropIn != -1 && g.nodeDropIn != treedataindex) continue;
  1081. var jnode = $("li[treedataindex=" + treedataindex + "] div:first", g.tree);
  1082. var offset = jnode.offset();
  1083. var range = {
  1084. top: offset.top,
  1085. bottom: offset.top + jnode.height(),
  1086. left: g.tree.offset().left,
  1087. right: g.tree.offset().left + g.tree.width()
  1088. };
  1089. if (pageX > range.left && pageX < range.right && pageY > range.top && pageY < range.bottom) {
  1090. var lineTop = offset.top;
  1091. if (isAfter) lineTop += jnode.height();
  1092. g.nodeDroptip.css({
  1093. left: range.left,
  1094. top: lineTop,
  1095. width: range.right - range.left
  1096. }).show();
  1097. g.nodeDropIn = treedataindex;
  1098. g.nodeDropDir = isAfter ? "bottom" : "top";
  1099. if (pageY > range.top + 7 && pageY < range.bottom - 7) {
  1100. this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no l-drop-yes").addClass("l-drop-add");
  1101. g.nodeDroptip.hide();
  1102. g.nodeDropInParent = true;
  1103. }
  1104. else {
  1105. this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no l-drop-add").addClass("l-drop-yes");
  1106. g.nodeDroptip.show();
  1107. g.nodeDropInParent = false;
  1108. }
  1109. break;
  1110. }
  1111. else if (g.nodeDropIn != -1) {
  1112. g.nodeDropIn = -1;
  1113. g.nodeDropInParent = false;
  1114. g.nodeDroptip.hide();
  1115. this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes l-drop-add").addClass("l-drop-no");
  1116. }
  1117. }
  1118. },
  1119. onStopDrag: function (current, e) {
  1120. var nodes = this.draggingNodes;
  1121. g.nodedragging = false;
  1122. if (g.nodeDropIn != -1) {
  1123. for (var i = 0; i < nodes.length; i++) {
  1124. var children = nodes[i].children;
  1125. if (children) {
  1126. nodes = $.grep(nodes, function (node, i) {
  1127. var isIn = $.inArray(node, children) == -1;
  1128. return isIn;
  1129. });
  1130. }
  1131. }
  1132. for (var i in nodes) {
  1133. var node = nodes[i];
  1134. if (g.nodeDropInParent) {
  1135. g.remove(node);
  1136. g.append(g.nodeDropIn, [node]);
  1137. }
  1138. else {
  1139. g.remove(node);
  1140. g.append(g.getParent(g.nodeDropIn), [node], g.nodeDropIn, g.nodeDropDir == "bottom")
  1141. }
  1142. }
  1143. g.nodeDropIn = -1;
  1144. }
  1145. g.nodeDroptip.hide();
  1146. this.set('cursor', 'default');
  1147. }
  1148. });
  1149. }
  1150. },
  1151. //递归设置父节点的状态
  1152. _setParentCheckboxStatus: function (treeitem) {
  1153. var g = this, p = this.options;
  1154. //当前同级别或低级别的节点是否都选中了
  1155. var isCheckedComplete = $(".l-checkbox-unchecked", treeitem.parent()).length == 0;
  1156. //当前同级别或低级别的节点是否都没有选中
  1157. var isCheckedNull = $(".l-checkbox-checked", treeitem.parent()).length == 0;
  1158. if (isCheckedComplete) {
  1159. treeitem.parent().prev().find(".l-checkbox")
  1160. .removeClass("l-checkbox-unchecked l-checkbox-incomplete")
  1161. .addClass("l-checkbox-checked");
  1162. }
  1163. else if (isCheckedNull) {
  1164. treeitem.parent().prev().find("> .l-checkbox")
  1165. .removeClass("l-checkbox-checked l-checkbox-incomplete")
  1166. .addClass("l-checkbox-unchecked");
  1167. }
  1168. else {
  1169. treeitem.parent().prev().find("> .l-checkbox")
  1170. .removeClass("l-checkbox-unchecked l-checkbox-checked")
  1171. .addClass("l-checkbox-incomplete");
  1172. }
  1173. if (treeitem.parent().parent("li").length > 0)
  1174. g._setParentCheckboxStatus(treeitem.parent().parent("li"));
  1175. }
  1176. });
  1177. })(jQuery);