customTree.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * JavaScript Object: customTree
  3. * @created by llh 2015.11.9
  4. *
  5. *
  6. */
  7. (function (window, $, undefined) {
  8. var data, dom, pid, childrenNode, thirdNode;
  9. var toTreeData; //目标树要添加节点的实际data(带有特殊标志)
  10. var treePrototype = $.ligerui.controls.Tree.prototype;
  11. /**
  12. * 扩展方法1:
  13. * f_onQueryNode(说明:查询节点)
  14. * @param fromTree 目标树对象
  15. * @param queryNm 要查询的条件值
  16. */
  17. treePrototype.f_onQueryNode = function (fromTree, queryNm) {
  18. if (!isStrEmpty(queryNm)) {
  19. fromTree.hide($(fromTree.element).find("li"));//除根节点外,先隐藏所有节点
  20. var liArr = $('span[title*="' + queryNm + '"]').closest('li');//查询出符合条件的结果集
  21. for (var i = 0; i < liArr.length; i++) {
  22. var outlinelevel = $(liArr[i]).attr("outlinelevel");
  23. if (outlinelevel == "3") {//查询结果集为三级节点,则二级节点也要显示
  24. $(liArr[i]).parent().parent().parent().parent().show();//显示根节点
  25. $(liArr[i]).parent().parent().show();//显示二级节点
  26. } else if (outlinelevel == "2") {//查询结果集为二级节点,则子节点也要显示
  27. $(liArr[i]).parent().parent().show();//显示根节点
  28. $(liArr[i]).find("li").show();//显示三级节点
  29. }else if (outlinelevel == "1"){//根节点
  30. $(liArr[i]).find("li").show();//显示二级节点
  31. $(liArr[i]).find("li").find("li").show();//显示二级节点
  32. }
  33. $(liArr[i]).show();//显示子节点
  34. }
  35. } else {//查询条件为空,则显示所有节点
  36. fromTree.show($(fromTree.element).find("li"));
  37. }
  38. }
  39. /**
  40. * 扩展方法1:
  41. * f_onQueryNode(说明:查询节点)
  42. * @param fromTree 目标树对象
  43. * @param queryNm 要查询的条件值
  44. */
  45. treePrototype.f_onSimQueryNode = function (fromTree, queryNm) {
  46. if (!isStrEmpty(queryNm)) {
  47. fromTree.hide($(fromTree.element).find("li").not('.l-onlychild'));//除根节点外,先隐藏所有节点
  48. var liArr = $('span[title*="' + queryNm + '"]').closest('li');//查询出符合条件的结果集
  49. for (var i = 0; i < liArr.length; i++) {
  50. var outlinelevel = $(liArr[i]).attr("outlinelevel");
  51. if (outlinelevel == "3") {//查询结果集为三级节点,则二级节点也要显示
  52. $(liArr[i]).parent().parent().parent().parent().show();//显示一级节点
  53. $(liArr[i]).parent().parent().show();//显示二级节点
  54. } else if (outlinelevel == "2") {//查询结果集为二级节点,则子节点也要显示
  55. $(liArr[i]).find("li").show();//显示三级节点
  56. $(liArr[i]).parent().parent().show();//显示一级节点
  57. }
  58. $(liArr[i]).show();//显示自己
  59. }
  60. } else {//查询条件为空,则显示所有节点
  61. fromTree.show($(fromTree.element).find("li"));
  62. }
  63. }
  64. /**
  65. * 扩展方法2:
  66. * f_onTreeNodeChecked(说明:获取树节点有复选框的数据)
  67. * @param node 有勾选的节点集合
  68. * @returns {Array}
  69. */
  70. treePrototype.f_onNodeCheckedData = function (nodes) {
  71. var toTreeData;
  72. var toCheckedArr = [];
  73. for (var i = 0; i < nodes.length; i++) {
  74. var data = nodes[i].data;
  75. toTreeData = [{id: data.id, pid: data.pid, text: data.text}]; //父节点要添加的实际data
  76. toCheckedArr.push(toTreeData);
  77. }
  78. return toCheckedArr;
  79. }
  80. /**
  81. * 扩展方法3:
  82. * f_onTreeNodeNoChecked(说明:获取树节点没有复选框的数据)
  83. * @param node
  84. * @returns {*}
  85. */
  86. treePrototype.f_onTreeNodeNoChecked = function (nodes) {
  87. var toNoCheckedArr = [];
  88. getDataNotes(nodes, toNoCheckedArr);
  89. return toNoCheckedArr.length == 1 ? "" : toNoCheckedArr;
  90. }
  91. /**
  92. * 递归获取树的数据,status(add,delete)有两种,但是这边只取状态为add的数据
  93. * @param data 勾选的数据
  94. * @param toNoCheckedArr 递归结束后返回的数组对象
  95. */
  96. function getDataNotes(data, toNoCheckedArr) {
  97. for (var i = 0; i < data.length; i++) {
  98. if (data[i].__status == "add") {//界面显示的树信息
  99. var toTreeData = {id: data[i].id.replace("adapter", ""), pid: data[i].pid.replace("adapter", ""), text: data[i].text};
  100. toNoCheckedArr.push(toTreeData);
  101. if (data[i].children && data[i].children.length) {
  102. getDataNotes(data[i].children, toNoCheckedArr);//获取下一级节点的数据
  103. }
  104. }
  105. }
  106. }
  107. /**
  108. * 扩展方法4:
  109. * f_onFromTreeCheck(说明:来源树复选框点击事件)
  110. * @param options
  111. * @returns {boolean}
  112. */
  113. treePrototype.f_onFromTreeCheck = function (options) {
  114. var fromTree = options.fromTree; //来源树对象(ligerTree对象)
  115. var toTree = options.toTree; //目标树对象
  116. var fromFlag = options.fromFlag; //来源树特殊标志 如:(id="std987",fromFlag="std")
  117. var toFlag = options.toFlag; //目标树特殊标志
  118. var from = $(options.checkNodeItem); //来源树勾选的内容
  119. var toTarget = options.toTarget; //目标节点id
  120. var checked = options.checked;
  121. var fromFlagReg = new RegExp(fromFlag,"g");
  122. //来源树到目标树节点生成
  123. for (var i = 0; i < from.length; i++) {
  124. data = from[i].data;
  125. //是否父节点,即全选情况
  126. if (fromTree.hasChildren(data)) {
  127. childrenNode = data.children == null ? "" : data.children;//获取子节点的数据
  128. if (data.pid == "-1") {//根节点
  129. if (!checked) {//全选未选中
  130. if (fromTree.getData().length > 0) {//删除右树所有节点,包含根节点
  131. var firstId = fromTree.getData()[0].id.replace(fromFlagReg, toFlag);
  132. var liArr = $("#" + firstId).find("li");
  133. toTree.remove($("#" + firstId));//删除所有节点
  134. }
  135. return false;
  136. }
  137. dom = $('#' + data.id.replace(fromFlagReg, toFlag), toTarget)[0];//根节点
  138. if(dom==undefined){
  139. dom = $("#mCSB_2_container")[0];
  140. toTreeData = [{id: data.id.replace(fromFlagReg, toFlag), pid: "-1", text: $($("#"+data.id).find(".l-body")[0]).find("span").text(),ischecked:checked}]; //添加树节点的实际data
  141. toTree.append(dom, toTreeData); //添加树节点
  142. dom = $('#' + data.id.replace(fromFlagReg, toFlag), toTarget)[0];//父节点的父节点dom
  143. }
  144. else
  145. toTree.clear(dom);
  146. var fromData = fromTree.getData()[0].children;
  147. var toData = [];
  148. function replaceFlag(data){
  149. var d;
  150. for(var o=0; o<data.length; o++){
  151. d = data[o];
  152. toData.push({
  153. id: d.id.replace(fromFlagReg, toFlag),
  154. ischecked: checked,
  155. pid: d.pid.replace(fromFlagReg, toFlag),
  156. text: d.text});
  157. if(d.children)
  158. replaceFlag(d.children);
  159. }
  160. }
  161. replaceFlag(fromData);
  162. toTree.append(dom, toData); //添加树节点
  163. } else {//不是根节点,但是该节点下可能有子节点
  164. if (checked) {
  165. if ($('#' + data.id.replace(fromFlagReg, toFlag)).length == 0) {//说明元素不存在,则新增
  166. dom = $('#' + data.pid.replace(fromFlagReg, toFlag), toTarget)[0];//父节点的父节点dom
  167. if(dom==undefined){
  168. dom = $("#mCSB_2_container")[0];
  169. toTreeData = [{id: data.pid.replace(fromFlagReg, toFlag), pid: "-1", text: $($("#"+data.pid).find(".l-body")[0]).find("span").text(),ischecked:checked}]; //添加树节点的实际data
  170. toTree.append(dom, toTreeData); //添加树节点
  171. dom = $('#' + data.pid.replace(fromFlagReg, toFlag), toTarget)[0];//父节点的父节点dom
  172. }
  173. toTreeData = [{id: data.id.replace(fromFlagReg, toFlag), pid: data.pid.replace(fromFlagReg, toFlag), text: data.text,ischecked:checked}]; //添加树节点的实际data
  174. for (var k = 0; k < childrenNode.length; k++) {
  175. toTreeData.push({id: childrenNode[k].id.replace(fromFlagReg, toFlag), pid: childrenNode[k].pid.replace(fromFlagReg, toFlag), text: childrenNode[k].text,ischecked:checked});
  176. }
  177. //toTree.append(dom, toTreeData); //添加树节点
  178. }else if(childrenNode && childrenNode.length>0){
  179. dom = $('#' + data.id.replace(fromFlagReg, toFlag))[0];
  180. toTreeData = [];
  181. for (var k = 0; k < childrenNode.length; k++) {
  182. if( $('#' + childrenNode[k].id.replace(fromFlagReg, toFlag)).length==0)
  183. toTreeData.push({id: childrenNode[k].id.replace(fromFlagReg, toFlag), pid: childrenNode[k].pid.replace(fromFlagReg, toFlag), text: childrenNode[k].text,ischecked:checked});
  184. }
  185. }
  186. toTree.append(dom, toTreeData); //添加树节点
  187. } else {
  188. toTree.remove($('#' + data.id.replace(fromFlagReg, toFlag)));//删除节点
  189. if($($('#' + data.pid.replace(fromFlagReg, toFlag)).find(".l-children")[0]).find("li").length==0){
  190. toTree.remove($('#' + data.pid.replace(fromFlagReg, toFlag)))//删除根节点
  191. }
  192. }
  193. }
  194. } else {//单个节点
  195. pid = data.pid;
  196. if(pid=="-1"){
  197. return false;
  198. }
  199. dom = $('#' + pid.replace(fromFlagReg, toFlag), toTarget)[0]; //父节点dom
  200. //父节点是否存在,不存在要创建
  201. if (dom == null) {
  202. var parentData = fromTree.getDataByID(pid); //父节点的data
  203. if ($('#' + parentData.id.replace(fromFlagReg, toFlag)).length == 0 && checked) {//说明元素不存在,且选中节点,则新增
  204. var parentDom = $('#' + parentData.pid.replace(fromFlagReg, toFlag), toTarget)[0]; //父节点的父节点dom
  205. if(parentDom==undefined){
  206. parentDom = $("#mCSB_2_container")[0];
  207. toTreeData = [{id: $("#"+data.pid).parent().parent().attr("id").replace(fromFlagReg, toFlag), pid: -1, text: $($("#"+$("#"+data.pid).parent().parent().attr("id")).find(".l-body")[0]).find("span").text(),ischecked:checked}]; //添加根节点
  208. toTree.append(parentDom, toTreeData); //添加树节点
  209. parentDom = $('#' + $("#"+data.pid).parent().parent().attr("id").replace(fromFlagReg, toFlag), toTarget)[0];//根节点dom
  210. }
  211. toTreeData = [{id: parentData.id.replace(fromFlagReg, toFlag), pid: parentData.pid.replace(fromFlagReg, toFlag), text: parentData.text,ischecked:checked}]; //父节点要添加的实际data
  212. toTree.append(parentDom, toTreeData); //添加父节点
  213. dom = $('#' + pid.replace(fromFlagReg, toFlag), toTarget)[0]; //提供父节点的dom
  214. } else {//不选中,则移除节点
  215. toTree.remove($('#' + parentData.id.replace(fromFlagReg, toFlag)));//删除节点
  216. }
  217. }
  218. if ($('#' + data.id.replace(fromFlagReg, toFlag)).length == 0 && checked) {//说明元素不存在,则新增
  219. toTreeData = [{id: data.id.replace(fromFlagReg, toFlag), pid: pid.replace(fromFlagReg, toFlag), text: data.text,ischecked:checked}]; //添加树节点的实际data
  220. toTree.append(dom, toTreeData); //添加树节点
  221. } else {//不选中,则移除节点
  222. if ($('#' + data.pid.replace(fromFlagReg, toFlag)).find(".l-children").find("li").length <= 1) {//父节点下只有一个子节点,则删除父节点和子节点
  223. toTree.remove($('#' + data.pid.replace(fromFlagReg, toFlag)));//删除父节点
  224. toTree.remove($('#' + data.id.replace(fromFlagReg, toFlag)));//删除子节点
  225. } else {
  226. toTree.remove($('#' + data.id.replace(fromFlagReg, toFlag)));//删除子节点
  227. }
  228. if ($("#" + fromTree.getData()[0].id.replace(fromFlagReg, toFlag)).find(".l-children").find("li").length == 0) {
  229. $($('#' + fromTree.getData()[0].id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[1]).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");//不选中根节点复选框
  230. }
  231. }
  232. }
  233. }
  234. }
  235. /**
  236. * 扩展方法5:
  237. * f_onToTreeCheck(说明:目标树复选框点击事件)
  238. * @param options
  239. */
  240. treePrototype.f_onToTreeCheck = function (options) {
  241. var fromTree = options.fromTree; //来源树对象(ligerTree对象)
  242. var toTree = options.toTree; //目标树对象toTree
  243. var fromFlag = options.fromFlag; //来源树特殊标志 如:(id="std987",fromFlag="std")
  244. var toFlag = options.toFlag; //目标树特殊标志
  245. var toNode = $(options.checkNodeItem); //来源树勾选的内容
  246. var node = options.checkNodeItem;
  247. var checked = options.checked;
  248. var fromFlagReg = new RegExp(fromFlag,"g");
  249. if (!checked) {
  250. if (toNode.length > 0) {
  251. var data = toNode[0].data;
  252. if (data.pid == "-1") {//根节点
  253. childrenNode = data.children;//获取根节点的下一级节点
  254. for (var k = 0; k < childrenNode.length; k++) {
  255. $($('#' + childrenNode[k].id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[2]).removeClass("l-checkbox-checked l-checkbox-incomplete").addClass("l-checkbox-unchecked");//不选中根节点复选框
  256. //toTree.remove($('#' + childrenNode[k].id));//删除节点
  257. thirdNode = childrenNode[k].children == null ? "" : childrenNode[k].children;//获取下级节点的子节点
  258. for (var j = 0; j < thirdNode.length; j++) {
  259. $($('#' + thirdNode[j].id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[3]).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");//不选中根节点复选框
  260. //toTree.remove($('#' + thirdNode[j].id));//删除节点
  261. }
  262. }
  263. toTree.remove($("#" + data.id));//删除目标树根节点
  264. $($("#" + data.id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[1]).removeClass("l-checkbox-checked l-checkbox-incomplete").addClass("l-checkbox-unchecked");//去除来源树根节点的复选框
  265. } else {//子节点
  266. if ($(node.target).attr("outlinelevel") == "2" && $("#" + data.id.replace(fromFlagReg, toFlag)).find(".l-children").find("li").length == 0) {//根节点下的子节点,没有子节点
  267. $($('#' + data.id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[2]).removeClass("l-checkbox-checked l-checkbox-incomplete").addClass("l-checkbox-unchecked");
  268. toTree.remove(node.target);
  269. } else {//根节点下的子节点,再有子节点
  270. var toTreeRoot = toTree.getParentTreeItem(node, 1);
  271. toTree.remove(node.target);
  272. if (data.children == null) {//单个节点
  273. $($('#' + data.id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[3]).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");//移除来源选择状态
  274. if ($("#" + data.pid).find(".l-children").find("li").length == 0) {//目标树下只有一个节点是,父节点也要删除掉
  275. $($("#"+data.pid.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[2]).removeClass("l-checkbox-incomplete").addClass("l-checkbox-unchecked");//移除来源树该节点的半选择状态
  276. if($("#"+data.pid).parent().parent().find("li").length == 1){
  277. toTree.remove($("#"+$("#"+data.pid).parent().parent().attr("id")));//删除根节点
  278. }
  279. toTree.remove($('#' + data.pid));
  280. }else{
  281. $($('#' + data.pid).find(".l-body").find("div")[2]).removeClass("l-checkbox-incomplete").addClass("l-checkbox-checked");//移除父节点半选状态
  282. $($('#' + data.pid.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[2]).removeClass("l-checkbox-checked").addClass("l-checkbox-incomplete");//添加来源父节点半选状态
  283. }
  284. } else {
  285. $($('#' + data.id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[2]).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");
  286. if ($(".l-checkbox-checked", $($('#' + data.id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[2])).length == 0) {
  287. $($('#' + data.id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[2]).removeClass("l-checkbox-incomplete");;//移除来源树该节点的半选择状态
  288. }
  289. childrenNode = data.children == null ? "" : data.children;//获取子节点数据
  290. for (var k = 0; k < childrenNode.length; k++) {
  291. $($('#' + childrenNode[k].id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[3]).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked");//不选中根节点复选框
  292. }
  293. if($($('#' + data.pid).find(".l-children")[0]).find("li").length==0){
  294. toTree.remove($('#' + data.pid));
  295. }
  296. $($('#' + data.id.replace(fromFlagReg, toFlag)).find(".l-body").find("div")[1]).removeClass("l-checkbox-incomplete");;//移除来源树该节点的半选择状态
  297. }
  298. $( $(toTreeRoot).find(".l-body:eq(0)").find("div:eq(1)")).removeClass("l-checkbox-incomplete").addClass("l-checkbox-checked");//移除根节点半选状态
  299. var fromTreeToot = $("#" + toTreeRoot.id.replace(fromFlagReg, toFlag));
  300. var fromTreeRootCheckBox = $($(fromTreeToot).find(".l-body:eq(0)").find("div:eq(1)"));
  301. if($(".l-checkbox-checked", fromTreeToot).length>0){//确认半选状态
  302. fromTreeRootCheckBox.removeClass("l-checkbox-checked").addClass("l-checkbox-incomplete");
  303. }else{
  304. fromTreeRootCheckBox.removeClass("l-checkbox-incomplete l-checkbox-checked").addClass("l-checkbox-unchecked");
  305. }
  306. }
  307. }
  308. }
  309. }
  310. }
  311. //判断字符串是否为空
  312. function isStrEmpty(str) {
  313. return str == null || !str || typeof str == undefined || str == '';
  314. }
  315. function isJson(obj){
  316. return typeof(obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length;
  317. }
  318. })(window, jQuery);