layui-xtree.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. //**********************************
  2. //** 本插件依赖 贤心 layui form模块
  3. //** 由 小巷 制作 QQ:151446298
  4. //** 版本3.0 时间 2018-01-10 20:48
  5. //**********************************
  6. //构造
  7. function layuiXtree(options) {
  8. var _this = this;
  9. _this._containerid = options.elem;
  10. _this._container = document.getElementById(options.elem); //容器
  11. _this._container.style.minHeight = "100px";
  12. _this._options = options;
  13. _this.Loading(options);
  14. }
  15. //封装IE8 Class选择
  16. layuiXtree.prototype.getByClassName = function (cn) {
  17. if (document.getElementsByClassName) return this._container.getElementsByClassName(cn);
  18. var _xlist = this._container.childNodes;
  19. var _xtemp = new Array();
  20. for (var i = 0; i < _xlist.length; i++) {
  21. var _xchild = _xlist[i];
  22. var _xclassNames = _xchild.getAttribute('class').split(' ');
  23. for (var j = 0; j < _xclassNames.length; j++) {
  24. if (_xclassNames[j] == cn) {
  25. _xtemp.push(_xchild);
  26. break;
  27. }
  28. }
  29. }
  30. return _xtemp;
  31. }
  32. //在一个对象下面找子级
  33. layuiXtree.prototype.getChildByClassName = function (obj, cn) {
  34. var _xlist = obj.childNodes;
  35. var _xtemp = new Array();
  36. for (var i = 0; i < _xlist.length; i++) {
  37. var _xchild = _xlist[i];
  38. var _xclassNames = _xchild.getAttribute('class').split(' ');
  39. for (var j = 0; j < _xclassNames.length; j++) {
  40. if (_xclassNames[j] == cn) {
  41. _xtemp.push(_xchild);
  42. break;
  43. }
  44. }
  45. }
  46. return _xtemp;
  47. }
  48. //加载特效,且获取数据
  49. layuiXtree.prototype.Loading = function (options) {
  50. var _this = this;
  51. _this.xloading = document.createElement("span"); //创建加载对象
  52. _this.xloading.setAttribute('class', 'layui-icon layui-anim layui-anim-rotate layui-anim-loop');
  53. _this.xloading.innerHTML = '&#xe63e;';
  54. _this.xloading.style.fontSize = "50px";
  55. _this.xloading.style.color = "#009688";
  56. _this.xloading.style.fontWeight = "bold";
  57. _this.xloading.style.marginLeft = _this._container.offsetWidth / 2 - 25 + 'px';
  58. _this.xloading.style.marginTop = _this._container.offsetHeight / 2 - 50 + 'px';
  59. _this._container.innerHTML = '';
  60. _this._container.appendChild(_this.xloading); //加载显示
  61. if (typeof (options.data) == 'object') {
  62. _this._dataJson = options.data;
  63. _this.Initial(options);
  64. return;
  65. }
  66. //如果是字符串url,进行异步加载
  67. var obj = new XMLHttpRequest();
  68. obj.open('get', options.data, true);
  69. obj.onreadystatechange = function () {
  70. if (obj.readyState == 4 && obj.status == 200 || obj.status == 304) { //回调成功
  71. _this._dataJson = eval('(' + obj.responseText + ')'); //将返回的数据转为json
  72. _this.Initial(options);
  73. }
  74. };
  75. obj.send();
  76. }
  77. //data验证后的数据初始化
  78. layuiXtree.prototype.Initial = function (o) {
  79. var _this = this;
  80. _this._form = o.form; //layui from对象
  81. _this._domStr = ""; //结构字符串
  82. _this._isopen = o.isopen != null ? o.isopen : true;
  83. if (o.color == null) o.color = {open: '#2F4056', close: '#2F4056', end: '#2F4056'};//图标颜色
  84. _this._iconOpenColor = o.color.open != null ? o.color.open : "#2F4056";
  85. _this._iconCloseColor = o.color.close != null ? o.color.close : "#2F4056";
  86. _this._iconEndColor = o.color.end != null ? o.color.end : "#2F4056";
  87. if (o.icon == null) o.icon = {open: '&#xe625;', close: '&#xe623;', end: '&#xe621;'};//图标样式
  88. _this._iconOpen = o.icon.open != null ? o.icon.open : '&#xe625;';
  89. _this._iconClose = o.icon.close != null ? o.icon.close : '&#xe623;';
  90. _this._iconEnd = o.icon.end != null ? o.icon.end : '&#xe621;';
  91. _this._click = o.click != null ? o.click : function () {
  92. };
  93. _this._ckall = o.ckall != null ? o.ckall : false; //全选是否启用
  94. _this._ckallSuccess = o.ckallback != null ? o.ckallback : function () {
  95. };//全选回调
  96. _this.CreateCkAll();
  97. _this.dataBind(_this._dataJson);
  98. _this.Rendering();
  99. }
  100. //全选框
  101. layuiXtree.prototype.CreateCkAll = function () {
  102. var _this = this;
  103. if (_this._ckall) {
  104. _this._domStr += '<div class="layui-xtree-item">';
  105. _this._domStr += '<input type="checkbox" class="layui-xtree-checkbox layui-xtree-ckall" title="全选" lay-skin="primary" lay-filter="xtreeckall' + _this._containerid + '">';
  106. _this._domStr += '</div>';
  107. }
  108. }
  109. //生产结构
  110. layuiXtree.prototype.dataBind = function (d, level=0) {
  111. var _this = this;
  112. if (d.length > 0) {
  113. level++;
  114. for (i in d) {
  115. var xtree_isend = '';
  116. var xtree_ischecked = '';
  117. var xtree_isdisabled = d[i].disabled ? ' disabled="disabled" ' : '';
  118. var xtree_child = 0;
  119. if (d[i].data.length > 0) {
  120. xtree_child = d[i].data.length
  121. }
  122. // _this._domStr += '<i class="layui-icon layui-xtree-icon" data-xtree="' + (_this._isopen ? '1' : '0') + '">' + (_this._isopen ? _this._iconOpen : _this._iconClose) + '</i>';
  123. else {
  124. // _this._domStr += '<i class="layui-icon layui-xtree-icon-null">' + _this._iconEnd + '</i>';
  125. xtree_isend = 'data-xend="1"';
  126. xtree_ischecked = d[i].checked ? ' checked ' : '';
  127. xtree_isdisabled = d[i].disabled ? ' disabled="disabled" ' : '';
  128. }
  129. _this._domStr += '<div class="layui-xtree-item" data-tag="iem" data-level="' + level + '" data-child="'+xtree_child+'">';
  130. _this._domStr += '<input type="checkbox" class="layui-xtree-checkbox" ' + xtree_isend + xtree_ischecked + xtree_isdisabled + ' value="' + d[i].value + '" title="' + d[i].title + '" lay-skin="primary" lay-filter="xtreeck' + _this._containerid + '" data-input-level="' + level + '" data-child="'+xtree_child+'">';
  131. _this.dataBind(d[i].data, level);
  132. _this._domStr += '</div>';
  133. }
  134. }
  135. }
  136. //渲染呈现
  137. layuiXtree.prototype.Rendering = function () {
  138. var _this = this;
  139. _this._container.innerHTML = _this._domStr;
  140. _this._domStr = "";
  141. //检查选中状态
  142. var xtree_ckitems = _this.getByClassName('layui-xtree-checkbox');
  143. for (var i = 0; i < xtree_ckitems.length; i++) {
  144. if (xtree_ckitems[i].getAttribute('data-xend') == '1' && xtree_ckitems[i].checked) {
  145. _this.ParentCheckboxChecked(xtree_ckitems[i]);
  146. }
  147. }
  148. _this._form.render('checkbox'); //layui渲染
  149. var xtree_items = _this.getByClassName('layui-xtree-item');
  150. var xtree_icons = _this.getByClassName('layui-xtree-icon');
  151. var xtree_nullicons = _this.getByClassName('layui-xtree-icon-null');
  152. for (var i = 0; i < xtree_items.length; i++) {
  153. if (xtree_items[i].parentNode == _this._container){
  154. xtree_items[i].style.padding = '0px 0 8px 10px';
  155. }
  156. else {
  157. var item_length = 0;
  158. if (xtree_items[i].childNodes.length > 0) {
  159. for(ii in xtree_items[i].childNodes){
  160. var dom = xtree_items[i].childNodes[ii];
  161. if(typeof(dom) == 'object') {
  162. if(dom.getAttribute("data-child") > 0){
  163. for(t in dom.parentNode.childNodes){
  164. var childDom = dom.parentNode.childNodes[t];
  165. if(typeof (childDom) == 'object'){
  166. if(childDom instanceof HTMLElement){
  167. if(childDom.getAttribute("class") == "layui-xtree-item" && childDom.getAttribute("data-child") == 0){
  168. childDom.style.display = 'inline-block';
  169. childDom.setAttribute('is_three','1');
  170. }
  171. if (childDom.getAttribute("class") == "layui-unselect layui-form-checkbox" ){
  172. childDom.style.display = 'table';
  173. }
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. }
  181. if(xtree_items[i].getAttribute("data-child") > 0){
  182. for(t in xtree_items[i].childNodes){
  183. var childDom = xtree_items[i].childNodes[t];
  184. if (typeof (childDom) == 'object') {
  185. if (childDom instanceof HTMLElement) {
  186. if (childDom.getAttribute("class") == "layui-xtree-item" && childDom.getAttribute("data-child") == 0) {
  187. childDom.style.display = 'inline-block';
  188. childDom.setAttribute('is_three', '1');
  189. }
  190. if (childDom.getAttribute("class") == "layui-unselect layui-form-checkbox" || childDom.getAttribute("class") == "layui-unselect layui-form-checkbox layui-form-checked") {
  191. childDom.style.display = 'table';
  192. }
  193. }
  194. }
  195. }
  196. }else{
  197. //二级分类块排序
  198. if (xtree_items[i].getAttribute("data-level") == "2" && xtree_items[i].getAttribute("data-child") == 0) {
  199. for(t in xtree_items[i].parentNode.childNodes){
  200. var childDom = xtree_items[i].parentNode.childNodes[t];
  201. if (typeof (childDom) == 'object') {
  202. if (childDom instanceof HTMLElement) {
  203. if (childDom.getAttribute("class") == "layui-xtree-item" && childDom.getAttribute("data-child") == 0) {
  204. childDom.style.display = 'inline-block';
  205. childDom.setAttribute('is_three', '1');
  206. }
  207. if (childDom.getAttribute("class") == "layui-unselect layui-form-checkbox") {
  208. childDom.style.display = 'table';
  209. }
  210. }
  211. }
  212. }
  213. }
  214. }
  215. xtree_items[i].style.margin = '5px 0 0 45px';
  216. if (!_this._isopen) xtree_items[i].style.display = 'none';
  217. }
  218. }
  219. for (var i = 0; i < xtree_icons.length; i++) {
  220. xtree_icons[i].style.position = "relative";
  221. xtree_icons[i].style.top = "3px";
  222. xtree_icons[i].style.margin = "0 5px 0 0";
  223. xtree_icons[i].style.fontSize = "18px";
  224. xtree_icons[i].style.color = _this._isopen ? _this._iconOpenColor : _this._iconCloseColor;
  225. xtree_icons[i].style.cursor = "pointer";
  226. xtree_icons[i].onclick = function () {
  227. var xtree_chi = this.parentNode.childNodes;
  228. if (this.getAttribute('data-xtree') == 1) {
  229. for (var j = 0; j < xtree_chi.length; j++) {
  230. if (xtree_chi[j].getAttribute('class') == 'layui-xtree-item')
  231. xtree_chi[j].style.display = 'none';
  232. }
  233. this.setAttribute('data-xtree', '0')
  234. this.innerHTML = _this._iconClose;
  235. this.style.color = _this._iconCloseColor;
  236. } else {
  237. for (var j = 0; j < xtree_chi.length; j++) {
  238. if (xtree_chi[j].getAttribute('class') == 'layui-xtree-item')
  239. xtree_chi[j].style.display = 'block';
  240. }
  241. this.setAttribute('data-xtree', '1')
  242. this.innerHTML = _this._iconOpen;
  243. this.style.color = _this._iconOpenColor;
  244. }
  245. }
  246. }
  247. for (var i = 0; i < xtree_nullicons.length; i++) {
  248. xtree_nullicons[i].style.position = "relative";
  249. xtree_nullicons[i].style.top = "3px";
  250. xtree_nullicons[i].style.margin = "0 5px 0 0";
  251. xtree_nullicons[i].style.fontSize = "18px";
  252. xtree_nullicons[i].style.color = _this._iconEndColor;
  253. }
  254. _this._form.on('checkbox(xtreeck' + _this._containerid + ')', function (da) {
  255. //获取当前点击复选框的容器下面的所有子级容器
  256. var xtree_chis = da.elem.parentNode.getElementsByClassName('layui-xtree-item');
  257. //遍历它们,选中状态与它们的父级一致(类似全选功能)
  258. for (var i = 0; i < xtree_chis.length; i++) {
  259. if (!_this.getChildByClassName(xtree_chis[i], 'layui-xtree-checkbox')[0].disabled) {
  260. _this.getChildByClassName(xtree_chis[i], 'layui-xtree-checkbox')[0].checked = da.elem.checked;
  261. if (da.elem.checked) _this.getChildByClassName(xtree_chis[i], 'layui-xtree-checkbox')[0].nextSibling.classList.add('layui-form-checked');
  262. else _this.getChildByClassName(xtree_chis[i], 'layui-xtree-checkbox')[0].nextSibling.classList.remove('layui-form-checked');
  263. }
  264. }
  265. _this.ParendCheck(da.elem);
  266. _this._click(da);
  267. });
  268. var _xtree_disableds = _this.getByClassName('layui-disabled');
  269. for (var i = 0; i < _xtree_disableds.length; i++) {
  270. _xtree_disableds[i].getElementsByTagName('span')[0].style.color = "#B5B5B5";
  271. }
  272. //全选按钮
  273. if (_this._ckall) {
  274. _this._form.on('checkbox(xtreeckall' + _this._containerid + ')', function (data) {
  275. var xtree_allck = data.elem.parentNode.parentNode.getElementsByClassName('layui-form-checkbox');
  276. for (var i = 0; i < xtree_allck.length; i++) {
  277. if (xtree_allck[i].getAttribute('class').indexOf('layui-checkbox-disbaled') == -1) {
  278. if (data.elem.checked) {
  279. xtree_allck[i].classList.add('layui-form-checked');
  280. }
  281. else {
  282. xtree_allck[i].classList.remove('layui-form-checked');
  283. }
  284. xtree_allck[i].parentNode.getElementsByClassName('layui-xtree-checkbox')[0].checked = data.elem.checked;
  285. }
  286. }
  287. _this._ckallSuccess();
  288. });
  289. }
  290. }
  291. //更新渲染
  292. layuiXtree.prototype.render = function () {
  293. var _this = this;
  294. _this.Loading(_this._options);
  295. }
  296. //子节点选中改变,父节点更改自身状态
  297. layuiXtree.prototype.ParendCheck = function (ckelem) {
  298. var _this = this;
  299. var xtree_p = ckelem.parentNode.parentNode;
  300. if (xtree_p.getAttribute('class') == 'layui-xtree-item') {
  301. var xtree_all = _this.getChildByClassName(xtree_p, 'layui-xtree-item');
  302. var xtree_count = 0;
  303. for (var i = 0; i < xtree_all.length; i++) {
  304. if (_this.getChildByClassName(xtree_all[i], 'layui-xtree-checkbox')[0].checked) {
  305. xtree_count++;
  306. }
  307. }
  308. if (xtree_count <= 0) {
  309. _this.getChildByClassName(xtree_p, 'layui-xtree-checkbox')[0].checked = false;
  310. _this.getChildByClassName(xtree_p, 'layui-xtree-checkbox')[0].nextSibling.classList.remove('layui-form-checked');
  311. } else {
  312. _this.getChildByClassName(xtree_p, 'layui-xtree-checkbox')[0].checked = true;
  313. _this.getChildByClassName(xtree_p, 'layui-xtree-checkbox')[0].nextSibling.classList.add('layui-form-checked');
  314. }
  315. this.ParendCheck(_this.getChildByClassName(xtree_p, 'layui-xtree-checkbox')[0]);
  316. }
  317. }
  318. //渲染之前按照选中的末级去改变父级选中状态
  319. layuiXtree.prototype.ParentCheckboxChecked = function (e) {
  320. var _this = this;
  321. if (e.parentNode.parentNode.getAttribute('class') == 'layui-xtree-item') {
  322. var _pe = _this.getChildByClassName(e.parentNode.parentNode, 'layui-xtree-checkbox')[0];
  323. _pe.checked = true;
  324. _this.ParentCheckboxChecked(_pe);
  325. }
  326. }
  327. //获取全部选中的末级checkbox对象
  328. layuiXtree.prototype.GetChecked = function () {
  329. var _this = this;
  330. var arr = new Array();
  331. var arrIndex = 0;
  332. var cks = _this.getByClassName('layui-xtree-checkbox');
  333. for (var i = 0; i < cks.length; i++) {
  334. if (cks[i].checked && cks[i].getAttribute('data-xend') == '1') {
  335. arr[arrIndex] = cks[i];
  336. arrIndex++;
  337. }
  338. }
  339. return arr;
  340. }
  341. //获取全部的原始checkbox对象
  342. layuiXtree.prototype.GetAllCheckBox = function () {
  343. var _this = this;
  344. var arr = new Array();
  345. var arrIndex = 0;
  346. var cks = _this.getByClassName('layui-xtree-checkbox');
  347. for (var i = 0; i < cks.length; i++) {
  348. arr[arrIndex] = cks[i];
  349. arrIndex++;
  350. }
  351. return arr;
  352. }
  353. //根据值来获取其父级的checkbox原dom对象
  354. layuiXtree.prototype.GetParent = function (a) {
  355. var _this = this;
  356. var cks = _this.getByClassName('layui-xtree-checkbox');
  357. for (var i = 0; i < cks.length; i++) {
  358. if (cks[i].value == a) {
  359. if (cks[i].parentNode.parentNode.getAttribute('id') == _this._container.getAttribute('id')) return null;
  360. return _this.getChildByClassName(cks[i].parentNode.parentNode, 'layui-xtree-checkbox')[0];
  361. }
  362. }
  363. return null;
  364. }