authtree.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. /*
  2. * @Author: Jeffrey Wang
  3. * @Date: 2018-03-16 18:24:47
  4. * @Last Modified by: 94468
  5. * @Last Modified time: 2018-11-10 15:28:58
  6. */
  7. // 节点树
  8. layui.define(['jquery', 'form'], function (exports) {
  9. $ = layui.jquery;
  10. form = layui.form;
  11. var MOD_NANE = 'authtree';
  12. obj = {
  13. // 渲染 + 绑定事件
  14. openIconContent: '',
  15. closeIconContent: '',
  16. // 表单类型 checkbox: 多选,radio:单选
  17. checkType: 'checkbox',
  18. // 选中、半选中、未选中
  19. checkedIconContent: '',
  20. halfCheckedIconContent: '',
  21. notCheckedIconContent: '',
  22. // 保存节点数据
  23. checkedNode: {},
  24. notCheckedNode: {},
  25. // 临时保存最新操作影响的节点
  26. lastCheckedNode: {},
  27. lastNotCheckedNode: {},
  28. // 已经渲染过的树,可用来获取配置,{ dst: {trees: '树的节点数据', opt: '配置'} }
  29. renderedTrees: {},
  30. // 使用 layui 的监听事件
  31. on: function (events, callback) {
  32. return layui.onevent.call(this, MOD_NANE, events, callback);
  33. },
  34. /**
  35. * 渲染DOM并绑定事件
  36. * @param {[type]} dst [目标ID,如:#test1]
  37. * @param {[type]} trees [数据,格式:{}]
  38. * @param {[type]} inputname [上传表单名]
  39. * @param {[type]} layfilter [lay-filter的值]
  40. * @param {[type]} openall [是否展开全部]
  41. * @return {[type]} [description]
  42. */
  43. render: function (dst, trees, opt) {
  44. var inputname = opt.inputname ? opt.inputname : 'menuids[]';
  45. opt.inputname = inputname;
  46. var layfilter = opt.layfilter ? opt.layfilter : 'checkauth';
  47. opt.layfilter = layfilter;
  48. var openall = opt.openall ? opt.openall : false;
  49. opt.openall = openall;
  50. var dblshow = opt.dblshow ? opt.dblshow : false;
  51. opt.dblshow = dblshow;
  52. var dbltimeout = opt.dbltimeout ? opt.dbltimeout : 180;
  53. opt.dbltimeout = dbltimeout;
  54. var openchecked = typeof opt.openchecked !== 'undefined' ? opt.openchecked : true;
  55. opt.openchecked = openchecked;
  56. var autoclose = typeof opt.autoclose !== 'undefined' ? opt.autoclose : true;
  57. opt.autoclose = autoclose;
  58. var autochecked = typeof opt.autochecked !== 'undefined' ? opt.autochecked : true;
  59. opt.autochecked = autochecked;
  60. // 有子节点的前显字符配置
  61. opt.prefixChildStr = opt.prefixChildStr ? opt.prefixChildStr : '├─';
  62. // 单选、多选配置
  63. opt.checkType = opt.checkType ? opt.checkType : 'checkbox';
  64. this.checkType = opt.checkType;
  65. // 展开、折叠节点的前显字符配置
  66. opt.openIconContent = opt.openIconContent ? opt.openIconContent : '';
  67. this.openIconContent = opt.openIconContent;
  68. opt.closeIconContent = opt.closeIconContent ? opt.closeIconContent : '';
  69. this.closeIconContent = opt.closeIconContent;
  70. // 选中、半选中、未选中节点的图标配置
  71. opt.checkedIconContent = opt.checkedIconContent ? opt.checkedIconContent : '';
  72. this.checkedIconContent = opt.checkedIconContent;
  73. opt.halfCheckedIconContent = opt.halfCheckedIconContent ? opt.halfCheckedIconContent : '';
  74. this.halfCheckedIconContent = opt.halfCheckedIconContent;
  75. opt.notCheckedIconContent = opt.notCheckedIconContent ? opt.notCheckedIconContent : '';
  76. this.notCheckedIconContent = opt.notCheckedIconContent;
  77. // 不启用双击展开,单击不用延迟
  78. if (!dblshow) {
  79. dbltimeout = 0;
  80. }
  81. // 记录渲染过的树
  82. obj.renderedTrees[dst] = {trees: trees, opt: opt};
  83. $(dst).html(obj.renderAuth(trees, 0, {
  84. inputname: inputname,
  85. layfilter: layfilter,
  86. openall: openall,
  87. openchecked: openchecked,
  88. checkType: this.checkType,
  89. prefixChildStr: opt.prefixChildStr,
  90. }));
  91. form.render();
  92. // 变动则存一下临时状态
  93. obj._saveNodeStatus(dst);
  94. // 开启自动宽度优化
  95. obj.autoWidth(dst);
  96. // 备注:如果使用form.on('checkbox()'),外部就无法使用form.on()监听同样的元素了(LAYUI不支持重复监听了)。
  97. // form.on('checkbox('+layfilter+')', function(data){
  98. // /*属下所有权限状态跟随,如果选中,往上走全部选中*/
  99. // var childs = $(data.elem).parent().next().find('input[type="checkbox"]').prop('checked', data.elem.checked);
  100. // if(data.elem.checked){
  101. // /*查找child的前边一个元素,并将里边的checkbox选中状态改为true。*/
  102. // $(data.elem).parents('.auth-child').prev().find('input[type="checkbox"]').prop('checked', true);
  103. // }
  104. // /*console.log(childs);*/
  105. // form.render('checkbox');
  106. // });
  107. // 解决单击和双击冲突问题的 timer 变量
  108. var timer = 0;
  109. $(dst).find('.auth-single:first').unbind('click').on('click', '.layui-form-checkbox', function () {
  110. var that = this;
  111. clearTimeout(timer);
  112. // 双击判断需要的延迟处理
  113. timer = setTimeout(function () {
  114. var elem = $(that).prev();
  115. var checked = elem.is(':checked');
  116. if (autochecked) {
  117. if (checked) {
  118. /*查找child的前边一个元素,并将里边的checkbox选中状态改为true。*/
  119. elem.parents('.auth-child').prev().find('input[type="checkbox"]').prop('checked', true);
  120. }
  121. var childs = elem.parent().next().find('input[type="checkbox"]').prop('checked', checked);
  122. }
  123. if (autoclose) {
  124. if (checked) {
  125. // pass
  126. } else {
  127. // 自动关闭父级选中节点
  128. obj._autoclose($(that).parent());
  129. }
  130. }
  131. /*console.log(childs);*/
  132. form.render('checkbox');
  133. // 变动则存一下临时状态
  134. obj._saveNodeStatus(dst);
  135. // 触发 change 事件
  136. obj._triggerEvent(dst, 'change', {othis: $(that)});
  137. obj.autoWidth(dst);
  138. }, dbltimeout);
  139. });
  140. /*动态绑定展开事件*/
  141. $(dst).unbind('click').on('click', '.auth-icon', function () {
  142. obj.iconToggle(dst, this);
  143. });
  144. /*双击展开*/
  145. if (dblshow) {
  146. $(dst).find('.auth-single:first').unbind('dblclick').on('dblclick', '.layui-form-checkbox', function (e) {
  147. clearTimeout(timer);
  148. obj.iconToggle(dst, $(this).prevAll('.auth-icon:first'));
  149. }).on('selectstart', function () {
  150. // 屏蔽双击选中文字
  151. return false;
  152. });
  153. }
  154. },
  155. // 自动关闭 - 如果兄弟节点均没选中,递归取消上级元素选中状态,传入的是 .auth-status 节点,递归 .auth-status 上级节点
  156. _autoclose: function (obj) {
  157. var single = $(obj).parent().parent();
  158. var authStatus = single.parent().prev();
  159. if (!authStatus.hasClass('auth-status')) {
  160. return false;
  161. }
  162. // 仅一层
  163. if (single.find('div>.auth-status>input[type="checkbox"]:checked').length === 0) {
  164. authStatus.find('input[type="checkbox"]').prop('checked', false);
  165. this._autoclose(authStatus);
  166. }
  167. },
  168. // 以 icon 的维度,切换显示下级空间
  169. iconToggle: function (dst, iconobj) {
  170. var origin = $(iconobj);
  171. var child = origin.parent().parent().find('.auth-child:first');
  172. if (origin.is('.active')) {
  173. /*收起*/
  174. origin.removeClass('active').html(obj.closeIconContent);
  175. child.slideUp('fast');
  176. } else {
  177. /*展开*/
  178. origin.addClass('active').html(obj.openIconContent);
  179. child.slideDown('fast');
  180. }
  181. obj._triggerEvent(dst, 'deptChange');
  182. return false;
  183. },
  184. // 递归创建格式
  185. renderAuth: function (tree, dept, opt) {
  186. var inputname = opt.inputname;
  187. var layfilter = opt.layfilter;
  188. var openall = opt.openall;
  189. var str = '<div class="auth-single">';
  190. layui.each(tree, function (index, item) {
  191. var hasChild = item.list ? 1 : 0;
  192. // 注意:递归调用时,this的环境会改变!
  193. var append = hasChild ? obj.renderAuth(item.list, dept + 1, opt) : '';
  194. var openstatus = openall || (opt.openchecked && item.checked);
  195. // '+new Array(dept * 4).join('&nbsp;')+'
  196. str += '<div><div class="auth-status" style="display: flex;flex-direction: row;align-items: flex-end;"> ' +
  197. (hasChild ? '<i class="layui-icon auth-icon ' + (openstatus ? 'active' : '') + '" style="cursor:pointer;">' + (openstatus ? obj.openIconContent : obj.closeIconContent) + '</i>' : '<i class="layui-icon auth-leaf" style="opacity:0;color: transparent;">&#xe626;</i>') +
  198. (dept > 0 ? ('<span>' + opt.prefixChildStr + ' </span>') : '') +
  199. '<input type="' + opt.checkType + '" name="' + inputname + '" title="' + item.name + '" value="' + item.value + '" lay-skin="primary" lay-filter="' + layfilter + '" ' +
  200. (item.checked ? 'checked="checked"' : '') + '> </div>' +
  201. ' <div class="auth-child" style="' + (openstatus ? '' : 'display:none;') + 'padding-left:40px;"> ' + append + '</div></div>'
  202. });
  203. str += '</div>';
  204. return str;
  205. },
  206. /**
  207. * 将普通列表无限递归转换为树
  208. * @param {[type]} list [普通的列表,必须包括 opt.primaryKey 指定的键和 opt.parentKey 指定的键]
  209. * @param {[type]} opt [配置参数,支持 primaryKey(主键 默认id) parentKey(父级id对应键 默认pid) nameKey(节点标题对应的key 默认name) valueKey(节点值对应的key 默认id) checkedKey(节点是否选中的字段 默认checked,传入数组则判断主键是否在此数组中) startPid(第一层扫描的PID 默认0) currentDept(当前层 默认0) maxDept(最大递归层 默认100) childKey(递归完成后子节点对应键 默认list) deptPrefix(根据层级重复的前缀 默认'')]
  210. * @return {[type]} [description]
  211. */
  212. listConvert: function (list, opt) {
  213. opt.primaryKey = opt.primaryKey ? opt.primaryKey : 'id';
  214. opt.parentKey = opt.parentKey ? opt.parentKey : 'pid';
  215. opt.startPid = opt.startPid ? opt.startPid : 0;
  216. opt.currentDept = opt.currentDept ? opt.currentDept : 0;
  217. opt.maxDept = opt.maxDept ? opt.maxDept : 100;
  218. opt.childKey = opt.childKey ? opt.childKey : 'list';
  219. opt.nameKey = opt.nameKey ? opt.nameKey : 'name';
  220. opt.valueKey = opt.valueKey ? opt.valueKey : 'id';
  221. return this._listToTree(list, opt.startPid, opt.currentDept, opt);
  222. },
  223. // 实际的递归函数,将会变化的参数抽取出来
  224. _listToTree: function (list, startPid, currentDept, opt) {
  225. if (opt.maxDept < currentDept) {
  226. return [];
  227. }
  228. var child = [];
  229. for (index in list) {
  230. // 筛查符合条件的数据(主键 = startPid)
  231. var item = list[index];
  232. if (typeof item[opt.parentKey] !== 'undefined' && item[opt.parentKey] === startPid) {
  233. // 满足条件则递归
  234. var nextChild = this._listToTree(list, item[opt.primaryKey], currentDept + 1, opt);
  235. // 节点信息保存
  236. var node = {};
  237. if (nextChild.length > 0) {
  238. node[opt.childKey] = nextChild;
  239. }
  240. node['name'] = item[opt.nameKey];
  241. node['value'] = item[opt.valueKey];
  242. if (typeof opt.checkedKey === "string" || typeof opt.checkedKey === 'number') {
  243. node['checked'] = item[opt.checkedKey];
  244. } else if (typeof opt.checkedKey === 'object') {
  245. if ($.inArray(item[opt.valueKey], opt.checkedKey) != -1) {
  246. node['checked'] = true;
  247. } else {
  248. node['checked'] = false;
  249. }
  250. } else {
  251. node['checked'] = false;
  252. }
  253. child.push(node);
  254. }
  255. }
  256. return child;
  257. },
  258. /**
  259. * 将树转为单选可用的 select,如果后台返回列表数据,可以先转换为 tree
  260. * @param {[type]} tree [description]
  261. * @param {[type]} opt [description]
  262. * @return {[type]} [description]
  263. */
  264. treeConvertSelect: function (tree, opt) {
  265. if (typeof tree.length !== 'number' || tree.length <= 0) {
  266. return [];
  267. }
  268. // 初始化层级
  269. opt.currentDept = opt.currentDept ? opt.currentDept : 0;
  270. // 子节点列表的Key
  271. opt.childKey = opt.childKey ? opt.childKey : 'list';
  272. // 有子节点的前缀
  273. opt.prefixChildStr = opt.prefixChildStr ? opt.prefixChildStr : '├─ ';
  274. // 没有子节点的前缀
  275. opt.prefixNoChildStr = opt.prefixNoChildStr ? opt.prefixNoChildStr : '● ';
  276. // 树的深度影响的子节点数据
  277. opt.prefixDeptStr = opt.prefixDeptStr ? opt.prefixDeptStr : ' ';
  278. // 如果第一列就存在没有子节点的情况,加的特殊前缀
  279. opt.prefixFirstEmpty = opt.prefixFirstEmpty ? opt.prefixFirstEmpty : '  '
  280. return this._treeToSelect(tree, opt.currentDept, opt);
  281. },
  282. // 实际处理递归的函数
  283. _treeToSelect: function (tree, currentDept, opt) {
  284. var ansList = [];
  285. var prefix = '';
  286. for (var i = 0; i < currentDept; i++) {
  287. prefix += opt.prefixDeptStr;
  288. }
  289. for (index in tree) {
  290. var child_flag = 0;
  291. var item = tree[index];
  292. if (opt.childKey in item && item[opt.childKey] && item[opt.childKey].length > 0) {
  293. child_flag = 1;
  294. }
  295. name = item.name;
  296. if (child_flag) {
  297. name = opt.prefixChildStr + name;
  298. } else {
  299. if (currentDept > 1) {
  300. name = opt.prefixNoChildStr + name;
  301. } else {
  302. name = opt.prefixFirstEmpty + name;
  303. }
  304. }
  305. ansList.push({
  306. name: prefix + name,
  307. value: item.value,
  308. checked: item.checked,
  309. });
  310. // 添加子节点
  311. if (child_flag) {
  312. var child = this._treeToSelect(item[opt.childKey], currentDept + 1, opt);
  313. // apply 的骚操作,使用第二个参数可以用于合并两个数组
  314. ansList.push.apply(ansList, child);
  315. }
  316. }
  317. return ansList;
  318. },
  319. // 自动调整宽度以解决 form.render()生成元素兼容性问题,如果用户手动调用 form.render() 之后也需要调用此方法
  320. autoWidth: function (dst) {
  321. $(dst).css({
  322. 'whiteSpace': 'nowrap',
  323. 'maxWidth': '100%',
  324. });
  325. $(dst).find('.layui-form-checkbox').each(function (index, item) {
  326. if ($(this).is(':hidden')) {
  327. // 比较奇葩的获取隐藏元素宽度的手法,请见谅
  328. $('body').append('<div id="layui-authtree-get-width">' + $(this).html() + '</div>');
  329. $width = $('#layui-authtree-get-width').find('span').width() + $('#layui-authtree-get-width').find('i').width() + 29;
  330. $('#layui-authtree-get-width').remove();
  331. } else {
  332. $width = $(this).find('span').width() + $(this).find('i').width() + 25;
  333. }
  334. $(this).width($width);
  335. });
  336. },
  337. // 触发自定义事件
  338. _triggerEvent: function (dst, events, other) {
  339. var tree = this.renderedTrees[dst];
  340. var origin = $(dst);
  341. if (tree) {
  342. var opt = tree.opt;
  343. var data = {
  344. opt: opt,
  345. dst: dst,
  346. othis: origin,
  347. };
  348. if (other && typeof other === 'object') {
  349. data = $.extend(data, other);
  350. }
  351. // 支持 dst 和 用户的配置的 layfilter 监听
  352. layui.event.call(origin, MOD_NANE, events + '(' + dst + ')', data);
  353. layui.event.call(origin, MOD_NANE, events + '(' + opt.layfilter + ')', data);
  354. } else {
  355. return false;
  356. }
  357. },
  358. // 动态获取最大深度
  359. getMaxDept: function (dst) {
  360. var next = $(dst);
  361. var dept = 0;
  362. while (next.length && dept < 100000) {
  363. next = this._getNext(next);
  364. if (next.length) {
  365. dept++;
  366. } else {
  367. break;
  368. }
  369. }
  370. return dept;
  371. },
  372. // 全选
  373. checkAll: function (dst) {
  374. var origin = $(dst);
  375. origin.find('input[type="checkbox"]:not(:checked)').prop('checked', true);
  376. form.render('checkbox');
  377. obj.autoWidth(dst);
  378. // 变动则存一下临时状态
  379. obj._saveNodeStatus(dst);
  380. obj._triggerEvent(dst, 'change');
  381. obj._triggerEvent(dst, 'checkAll');
  382. },
  383. // 全不选
  384. uncheckAll: function (dst) {
  385. var origin = $(dst);
  386. origin.find('input[type="checkbox"]:checked').prop('checked', false);
  387. form.render('checkbox');
  388. obj.autoWidth(dst);
  389. // 变动则存一下临时状态
  390. obj._saveNodeStatus(dst);
  391. obj._triggerEvent(dst, 'change');
  392. obj._triggerEvent(dst, 'uncheckAll');
  393. },
  394. // 显示整个树
  395. showAll: function (dst) {
  396. this.showDept(dst, this.getMaxDept(dst));
  397. },
  398. // 关闭整颗树
  399. closeAll: function (dst) {
  400. this.closeDept(dst, 1);
  401. },
  402. // 切换整颗树的显示/关闭
  403. toggleAll: function (dst) {
  404. if (this._shownDept(2)) {
  405. this.closeDept(dst);
  406. } else {
  407. this.showAll(dst);
  408. }
  409. },
  410. // 显示到第 dept 层
  411. showDept: function (dst, dept) {
  412. var next = $(dst);
  413. for (var i = 1; i < dept; i++) {
  414. next = this._getNext(next);
  415. if (next.length) {
  416. this._showSingle(next);
  417. } else {
  418. break;
  419. }
  420. }
  421. obj._triggerEvent(dst, 'deptChange', {dept: dept});
  422. },
  423. // 第 dept 层之后全部关闭
  424. closeDept: function (dst, dept) {
  425. var next = $(dst);
  426. for (var i = 0; i < dept; i++) {
  427. next = this._getNext(next);
  428. }
  429. while (next.length) {
  430. this._closeSingle(next);
  431. next = this._getNext(next);
  432. }
  433. obj._triggerEvent(dst, 'deptChange', {dept: dept});
  434. },
  435. // 临时保存所有节点信息状态
  436. _saveNodeStatus: function (dst) {
  437. var currentChecked = this.getChecked(dst);
  438. var currentNotChecked = this.getNotChecked(dst);
  439. // 保存新信息前,最新选择的信息
  440. this.lastCheckedNode[dst] = this._getLastChecked(dst, currentChecked, currentNotChecked);
  441. this.lastNotCheckedNode[dst] = this._getLastNotChecked(dst, currentChecked, currentNotChecked);
  442. this.checkedNode[dst] = currentChecked;
  443. this.notCheckedNode[dst] = currentNotChecked;
  444. // console.log('保存节点信息', this.checkedNode[dst], this.notCheckedNode[dst], this.lastCheckedNode[dst], this.lastNotCheckedNode[dst]);
  445. },
  446. // 判断某一层是否显示
  447. _shownDept: function (dst, dept) {
  448. var next = $(dst);
  449. for (var i = 0; i < dept; i++) {
  450. next = this._getNext(next);
  451. }
  452. return !next.is(':hidden');
  453. },
  454. // 获取
  455. _getNext: function (dst) {
  456. return $(dst).find('.auth-single:first>div>.auth-child');
  457. },
  458. // 显示某层 single
  459. _showSingle: function (dst) {
  460. layui.each(dst, function (index, item) {
  461. var origin = $(item).find('.auth-single:first');
  462. var parentChild = origin.parent();
  463. var parentStatus = parentChild.prev();
  464. if (!parentStatus.find('.auth-icon').hasClass('active')) {
  465. parentChild.show();
  466. // 显示上级的 .auth-child节点,并修改.auth-status的折叠状态
  467. parentStatus.find('.auth-icon').addClass('active').html(obj.openIconContent);
  468. }
  469. });
  470. },
  471. // 关闭某层 single
  472. _closeSingle: function (dst) {
  473. var origin = $(dst).find('.auth-single:first');
  474. var parentChild = origin.parent();
  475. var parentStatus = parentChild.prev();
  476. if (parentStatus.find('.auth-icon').hasClass('active')) {
  477. parentChild.hide();
  478. // 显示上级的 .auth-child节点,并修改.auth-status的折叠状态
  479. parentStatus.find('.auth-icon').removeClass('active').html(obj.closeIconContent);
  480. }
  481. },
  482. // 获取选中叶子结点
  483. getLeaf: function (dst) {
  484. var leafs = $(dst).find('.auth-leaf').parent().find('input[type="checkbox"]:checked');
  485. var data = [];
  486. leafs.each(function (index, item) {
  487. // console.log(item);
  488. data.push(item.value);
  489. });
  490. // console.log(data);
  491. return data;
  492. },
  493. // 获取所有节点数据
  494. getAll: function (dst) {
  495. var inputs = $(dst).find('input[type="checkbox"]');
  496. var data = [];
  497. inputs.each(function (index, item) {
  498. data.push(item.value);
  499. });
  500. // console.log(data);
  501. return data;
  502. },
  503. // 获取最新选中(之前取消-现在选中)
  504. getLastChecked: function (dst) {
  505. return this.lastCheckedNode[dst] || [];
  506. },
  507. // (逻辑)最新选中(之前取消-现在选中)
  508. _getLastChecked: function (dst, currentChecked, currentNotChecked) {
  509. var lastCheckedNode = currentChecked;
  510. var data = [];
  511. for (i in lastCheckedNode) {
  512. if ($.inArray(lastCheckedNode[i], this.notCheckedNode[dst]) != -1) {
  513. data.push(lastCheckedNode[i]);
  514. }
  515. }
  516. return data;
  517. },
  518. // 获取所有选中的数据
  519. getChecked: function (dst) {
  520. var inputs = $(dst).find('input[type="checkbox"]:checked');
  521. var data = [];
  522. inputs.each(function (index, item) {
  523. data.push(item.value);
  524. });
  525. return data;
  526. },
  527. // 获取最新取消(之前取消-现在选中)
  528. getLastNotChecked: function (dst) {
  529. return this.lastNotCheckedNode[dst] || [];
  530. },
  531. // (逻辑)最新取消(之前选中-现在取消)
  532. _getLastNotChecked: function (dst, currentChecked, currentNotChecked) {
  533. var lastNotCheckedNode = currentNotChecked;
  534. var data = [];
  535. for (i in lastNotCheckedNode) {
  536. if ($.inArray(lastNotCheckedNode[i], this.checkedNode[dst]) != -1) {
  537. data.push(lastNotCheckedNode[i]);
  538. }
  539. }
  540. return data;
  541. },
  542. // 获取未选中数据
  543. getNotChecked: function (dst) {
  544. var inputs = $(dst).find('input[type="checkbox"]:not(:checked)');
  545. var data = [];
  546. inputs.each(function (index, item) {
  547. data.push(item.value);
  548. });
  549. // console.log(data);
  550. return data;
  551. }
  552. }
  553. exports('authtree', obj);
  554. });