abn_tree_directive.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. (function() {
  2. var module,
  3. __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  4. module = angular.module('angularBootstrapNavTree', []);
  5. module.directive('abnTree', [
  6. '$timeout', function($timeout) {
  7. return {
  8. restrict: 'E',
  9. template: "<ul class=\"nav nav-list nav-pills nav-stacked abn-tree\">\n <li ng-repeat=\"row in tree_rows | filter:{visible:true} track by row.branch.uid\" ng-animate=\"'abn-tree-animate'\" ng-class=\"'level-' + {{ row.level }} + (row.branch.selected ? ' active':'') + ' ' +row.classes.join(' ')\" class=\"abn-tree-row\" ng-click=\"row.branch.expanded = !row.branch.expanded\"><a ng-click=\"user_clicks_branch(row.branch)\"><i ng-class=\"row.tree_icon\" class=\"indented tree-icon\" > </i><span class=\"indented tree-label\">{{ row.label }} </span></a></li>\n</ul>",
  10. replace: true,
  11. scope: {
  12. treeData: '=',
  13. onSelect: '&',
  14. initialSelection: '@',
  15. treeControl: '='
  16. },
  17. link: function(scope, element, attrs) {
  18. var error, expand_all_parents, expand_level, for_all_ancestors, for_each_branch, get_parent, n, on_treeData_change, select_branch, selected_branch, tree;
  19. error = function(s) {
  20. console.log('ERROR:' + s);
  21. debugger;
  22. return void 0;
  23. };
  24. if (attrs.iconExpand == null) {
  25. attrs.iconExpand = 'icon-plus glyphicon glyphicon-plus fa fa-plus';
  26. }
  27. if (attrs.iconCollapse == null) {
  28. attrs.iconCollapse = 'icon-minus glyphicon glyphicon-minus fa fa-minus';
  29. }
  30. if (attrs.iconLeaf == null) {
  31. attrs.iconLeaf = 'icon-file glyphicon glyphicon-file fa fa-file';
  32. }
  33. if (attrs.iconRight == null) {
  34. attrs.iconRight = 'icon-file glyphicon glyphicon-file fa fa-file';
  35. }
  36. if (attrs.expandLevel == null) {
  37. attrs.expandLevel = '3';
  38. }
  39. expand_level = parseInt(attrs.expandLevel, 10);
  40. if (!scope.treeData) {
  41. alert('no treeData defined for the tree!');
  42. return;
  43. }
  44. if (scope.treeData.length == null) {
  45. if (treeData.label != null) {
  46. scope.treeData = [treeData];
  47. } else {
  48. alert('treeData should be an array of root branches');
  49. return;
  50. }
  51. }
  52. for_each_branch = function(f) {
  53. var do_f, root_branch, _i, _len, _ref, _results;
  54. do_f = function(branch, level) {
  55. var child, _i, _len, _ref, _results;
  56. f(branch, level);
  57. if (branch.children != null) {
  58. _ref = branch.children;
  59. _results = [];
  60. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  61. child = _ref[_i];
  62. _results.push(do_f(child, level + 1));
  63. }
  64. return _results;
  65. }
  66. };
  67. _ref = scope.treeData;
  68. _results = [];
  69. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  70. root_branch = _ref[_i];
  71. _results.push(do_f(root_branch, 1));
  72. }
  73. return _results;
  74. };
  75. selected_branch = null;
  76. select_branch = function(branch) {
  77. if (!branch) {
  78. if (selected_branch != null) {
  79. selected_branch.selected = false;
  80. }
  81. selected_branch = null;
  82. return;
  83. }
  84. if (branch !== selected_branch) {
  85. if (selected_branch != null) {
  86. selected_branch.selected = false;
  87. }
  88. branch.selected = true;
  89. selected_branch = branch;
  90. expand_all_parents(branch);
  91. if (branch.onSelect != null) {
  92. return $timeout(function() {
  93. return branch.onSelect(branch);
  94. });
  95. } else {
  96. if (scope.onSelect != null) {
  97. return $timeout(function() {
  98. return scope.onSelect({
  99. branch: branch
  100. });
  101. });
  102. }
  103. }
  104. }
  105. };
  106. scope.user_clicks_branch = function(branch) {
  107. if (branch !== selected_branch) {
  108. return select_branch(branch);
  109. }
  110. };
  111. get_parent = function(child) {
  112. var parent;
  113. parent = void 0;
  114. if (child.parent_uid) {
  115. for_each_branch(function(b) {
  116. if (b.uid === child.parent_uid) {
  117. return parent = b;
  118. }
  119. });
  120. }
  121. return parent;
  122. };
  123. for_all_ancestors = function(child, fn) {
  124. var parent;
  125. parent = get_parent(child);
  126. if (parent != null) {
  127. fn(parent);
  128. return for_all_ancestors(parent, fn);
  129. }
  130. };
  131. expand_all_parents = function(child) {
  132. return for_all_ancestors(child, function(b) {
  133. return b.expanded = true;
  134. });
  135. };
  136. scope.tree_rows = [];
  137. on_treeData_change = function() {
  138. var add_branch_to_list, root_branch, _i, _len, _ref, _results;
  139. for_each_branch(function(b, level) {
  140. if (!b.uid) {
  141. return b.uid = "" + Math.random();
  142. }
  143. });
  144. console.log('UIDs are set.');
  145. for_each_branch(function(b) {
  146. var child, _i, _len, _ref, _results;
  147. if (angular.isArray(b.children)) {
  148. _ref = b.children;
  149. _results = [];
  150. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  151. child = _ref[_i];
  152. _results.push(child.parent_uid = b.uid);
  153. }
  154. return _results;
  155. }
  156. });
  157. scope.tree_rows = [];
  158. for_each_branch(function(branch) {
  159. var child, f;
  160. if (branch.children) {
  161. if (branch.children.length > 0) {
  162. f = function(e) {
  163. if (typeof e === 'string') {
  164. return {
  165. label: e,
  166. children: []
  167. };
  168. } else {
  169. return e;
  170. }
  171. };
  172. return branch.children = (function() {
  173. var _i, _len, _ref, _results;
  174. _ref = branch.children;
  175. _results = [];
  176. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  177. child = _ref[_i];
  178. _results.push(f(child));
  179. }
  180. return _results;
  181. })();
  182. }
  183. } else {
  184. return branch.children = [];
  185. }
  186. });
  187. add_branch_to_list = function(level, branch, visible) {
  188. var child, child_visible, tree_icon, _i, _len, _ref, _results;
  189. if (branch.expanded == null) {
  190. branch.expanded = false;
  191. }
  192. if (branch.classes == null) {
  193. branch.classes = [];
  194. }
  195. if (!branch.noLeaf && (!branch.children || branch.children.length === 0)) {
  196. tree_icon = attrs.iconLeaf;
  197. if (__indexOf.call(branch.classes, "leaf") < 0) {
  198. branch.classes.push("leaf");
  199. }
  200. }else if(!branch.noRight && (!branch.children || branch.children.length === 0)){
  201. tree_iconright = attrs.iconRight;
  202. if (__indexOf.call(branch.classes, "right") < 0) {
  203. branch.classes.push("right");
  204. }
  205. } else {
  206. if (branch.expanded) {
  207. tree_icon = attrs.iconCollapse;
  208. } else {
  209. tree_icon = attrs.iconExpand;
  210. }
  211. }
  212. scope.tree_rows.push({
  213. level: level,
  214. branch: branch,
  215. label: branch.label,
  216. classes: branch.classes,
  217. tree_icon: tree_icon,
  218. visible: visible
  219. });
  220. if (branch.children != null) {
  221. _ref = branch.children;
  222. _results = [];
  223. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  224. child = _ref[_i];
  225. child_visible = visible && branch.expanded;
  226. _results.push(add_branch_to_list(level + 1, child, child_visible));
  227. }
  228. return _results;
  229. }
  230. };
  231. _ref = scope.treeData;
  232. _results = [];
  233. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  234. root_branch = _ref[_i];
  235. _results.push(add_branch_to_list(1, root_branch, true));
  236. }
  237. return _results;
  238. };
  239. scope.$watch('treeData', on_treeData_change, true);
  240. if (attrs.initialSelection != null) {
  241. for_each_branch(function(b) {
  242. if (b.label === attrs.initialSelection) {
  243. return $timeout(function() {
  244. return select_branch(b);
  245. });
  246. }
  247. });
  248. }
  249. n = scope.treeData.length;
  250. console.log('num root branches = ' + n);
  251. for_each_branch(function(b, level) {
  252. b.level = level;
  253. return b.expanded = b.level < expand_level;
  254. });
  255. if (scope.treeControl != null) {
  256. if (angular.isObject(scope.treeControl)) {
  257. tree = scope.treeControl;
  258. tree.expand_all = function() {
  259. return for_each_branch(function(b, level) {
  260. return b.expanded = true;
  261. });
  262. };
  263. tree.collapse_all = function() {
  264. return for_each_branch(function(b, level) {
  265. return b.expanded = false;
  266. });
  267. };
  268. tree.get_first_branch = function() {
  269. n = scope.treeData.length;
  270. if (n > 0) {
  271. return scope.treeData[0];
  272. }
  273. };
  274. tree.select_first_branch = function() {
  275. var b;
  276. b = tree.get_first_branch();
  277. return tree.select_branch(b);
  278. };
  279. tree.get_selected_branch = function() {
  280. return selected_branch;
  281. };
  282. tree.get_parent_branch = function(b) {
  283. return get_parent(b);
  284. };
  285. tree.select_branch = function(b) {
  286. select_branch(b);
  287. return b;
  288. };
  289. tree.get_children = function(b) {
  290. return b.children;
  291. };
  292. tree.select_parent_branch = function(b) {
  293. var p;
  294. if (b == null) {
  295. b = tree.get_selected_branch();
  296. }
  297. if (b != null) {
  298. p = tree.get_parent_branch(b);
  299. if (p != null) {
  300. tree.select_branch(p);
  301. return p;
  302. }
  303. }
  304. };
  305. tree.add_branch = function(parent, new_branch) {
  306. if (parent != null) {
  307. parent.children.push(new_branch);
  308. parent.expanded = true;
  309. } else {
  310. scope.treeData.push(new_branch);
  311. }
  312. return new_branch;
  313. };
  314. tree.add_root_branch = function(new_branch) {
  315. tree.add_branch(null, new_branch);
  316. return new_branch;
  317. };
  318. tree.expand_branch = function(b) {
  319. if (b == null) {
  320. b = tree.get_selected_branch();
  321. }
  322. if (b != null) {
  323. b.expanded = true;
  324. return b;
  325. }
  326. };
  327. tree.collapse_branch = function(b) {
  328. if (b == null) {
  329. b = selected_branch;
  330. }
  331. if (b != null) {
  332. b.expanded = false;
  333. return b;
  334. }
  335. };
  336. tree.get_siblings = function(b) {
  337. var p, siblings;
  338. if (b == null) {
  339. b = selected_branch;
  340. }
  341. if (b != null) {
  342. p = tree.get_parent_branch(b);
  343. if (p) {
  344. siblings = p.children;
  345. } else {
  346. siblings = scope.treeData;
  347. }
  348. return siblings;
  349. }
  350. };
  351. tree.get_next_sibling = function(b) {
  352. var i, siblings;
  353. if (b == null) {
  354. b = selected_branch;
  355. }
  356. if (b != null) {
  357. siblings = tree.get_siblings(b);
  358. n = siblings.length;
  359. i = siblings.indexOf(b);
  360. if (i < n) {
  361. return siblings[i + 1];
  362. }
  363. }
  364. };
  365. tree.get_prev_sibling = function(b) {
  366. var i, siblings;
  367. if (b == null) {
  368. b = selected_branch;
  369. }
  370. siblings = tree.get_siblings(b);
  371. n = siblings.length;
  372. i = siblings.indexOf(b);
  373. if (i > 0) {
  374. return siblings[i - 1];
  375. }
  376. };
  377. tree.select_next_sibling = function(b) {
  378. var next;
  379. if (b == null) {
  380. b = selected_branch;
  381. }
  382. if (b != null) {
  383. next = tree.get_next_sibling(b);
  384. if (next != null) {
  385. return tree.select_branch(next);
  386. }
  387. }
  388. };
  389. tree.select_prev_sibling = function(b) {
  390. var prev;
  391. if (b == null) {
  392. b = selected_branch;
  393. }
  394. if (b != null) {
  395. prev = tree.get_prev_sibling(b);
  396. if (prev != null) {
  397. return tree.select_branch(prev);
  398. }
  399. }
  400. };
  401. tree.get_first_child = function(b) {
  402. var _ref;
  403. if (b == null) {
  404. b = selected_branch;
  405. }
  406. if (b != null) {
  407. if (((_ref = b.children) != null ? _ref.length : void 0) > 0) {
  408. return b.children[0];
  409. }
  410. }
  411. };
  412. tree.get_closest_ancestor_next_sibling = function(b) {
  413. var next, parent;
  414. next = tree.get_next_sibling(b);
  415. if (next != null) {
  416. return next;
  417. } else {
  418. parent = tree.get_parent_branch(b);
  419. return tree.get_closest_ancestor_next_sibling(parent);
  420. }
  421. };
  422. tree.get_next_branch = function(b) {
  423. var next;
  424. if (b == null) {
  425. b = selected_branch;
  426. }
  427. if (b != null) {
  428. next = tree.get_first_child(b);
  429. if (next != null) {
  430. return next;
  431. } else {
  432. next = tree.get_closest_ancestor_next_sibling(b);
  433. return next;
  434. }
  435. }
  436. };
  437. tree.select_next_branch = function(b) {
  438. var next;
  439. if (b == null) {
  440. b = selected_branch;
  441. }
  442. if (b != null) {
  443. next = tree.get_next_branch(b);
  444. if (next != null) {
  445. tree.select_branch(next);
  446. return next;
  447. }
  448. }
  449. };
  450. tree.last_descendant = function(b) {
  451. var last_child;
  452. if (b == null) {
  453. debugger;
  454. }
  455. n = b.children.length;
  456. if (n === 0) {
  457. return b;
  458. } else {
  459. last_child = b.children[n - 1];
  460. return tree.last_descendant(last_child);
  461. }
  462. };
  463. tree.get_prev_branch = function(b) {
  464. var parent, prev_sibling;
  465. if (b == null) {
  466. b = selected_branch;
  467. }
  468. if (b != null) {
  469. prev_sibling = tree.get_prev_sibling(b);
  470. if (prev_sibling != null) {
  471. return tree.last_descendant(prev_sibling);
  472. } else {
  473. parent = tree.get_parent_branch(b);
  474. return parent;
  475. }
  476. }
  477. };
  478. return tree.select_prev_branch = function(b) {
  479. var prev;
  480. if (b == null) {
  481. b = selected_branch;
  482. }
  483. if (b != null) {
  484. prev = tree.get_prev_branch(b);
  485. if (prev != null) {
  486. tree.select_branch(prev);
  487. return prev;
  488. }
  489. }
  490. };
  491. }
  492. }
  493. }
  494. };
  495. }
  496. ]);
  497. }).call(this);