You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

211 lines
6.3 KiB

  1. // Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. //
  3. // MIT License (MIT)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a
  6. // copy of this software and associated documentation files (the "Software"),
  7. // to deal in the Software without restriction, including without limitation
  8. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. // and/or sell copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. //
  22. // Tree
  23. // ---------------------------------
  24. function Tree(parent, width, do_animate) {
  25. this.width = width;
  26. this.nodes = {};
  27. this.allnodes = {};
  28. this.cur_node;
  29. this.is_root = 1;
  30. this.do_animate = do_animate;
  31. var me = this;
  32. this.exp_img = 'lib/images/icons/plus.gif';
  33. this.col_img = 'lib/images/icons/minus.gif';
  34. this.body = $a(parent, 'div');
  35. if(width)$w(this.body, width);
  36. this.addNode = function(parent, id, imagesrc, onclick, onexpand, opts, label) {
  37. var t = new TreeNode(me, parent, id, imagesrc, onclick, onexpand, opts, label);
  38. if(!parent) {
  39. me.nodes[id]=t; // add to roots
  40. } else {
  41. parent.nodes[id]=t; // add to the node
  42. }
  43. me.allnodes[id] = t;
  44. // note: this will only be for groups
  45. if(onexpand)
  46. t.create_expimage();
  47. t.expanded_once = 0;
  48. return t;
  49. }
  50. var me = this;
  51. this.collapseall = function() {
  52. for(n in me.allnodes) {
  53. me.allnodes[n].collapse();
  54. }
  55. }
  56. }
  57. function TreeNode(tree, parent, id, imagesrc, onclick, onexpand, opts, label) {
  58. var me = this;
  59. if(!parent) parent = tree;
  60. this.parent = parent;
  61. this.nodes = {};
  62. this.onclick = onclick;
  63. this.onexpand = onexpand;
  64. this.text = label ? label : id;
  65. this.tree = tree;
  66. if(opts)
  67. this.opts = opts;
  68. else
  69. this.opts = {
  70. show_exp_img:1
  71. ,show_icon:1
  72. ,label_style:{padding:'2px', cursor: 'pointer', fontSize:'11px'}
  73. ,onselect_style:{fontWeight: 'bold'}
  74. ,ondeselect_style:{fontWeight: 'normal'}
  75. } // only useful for 1st node in the tree
  76. var tc = 1;
  77. if(this.opts.show_exp_img) tc+=1;
  78. if(!this.parent.tab) {
  79. this.parent.tab = make_table(this.parent.body, 2, tc, '100%');
  80. $y(this.parent.tab,{tableLayout:'fixed',borderCollapse: 'collapse'});
  81. } else {
  82. this.parent.tab.append_row(); this.parent.tab.append_row();
  83. }
  84. var mytab = this.parent.tab;
  85. // expand / collapse
  86. if(this.opts.show_exp_img) {
  87. this.exp_cell=$td(mytab,mytab.rows.length-2, 0);
  88. $y(this.exp_cell, {cursor:'pointer', textAlign:'center', verticalAlign:'middle',width:'20px'});
  89. this.exp_cell.innerHTML = ' ';
  90. } else {
  91. // pass
  92. }
  93. this.create_expimage = function() {
  94. if(!me.opts.show_exp_img) return; // no expand image
  95. if(!me.expimage) {
  96. me.exp_cell.innerHTML='';
  97. me.expimage = $a(me.exp_cell, 'img');
  98. me.expimage.src = me.exp_img ? me.exp_img : me.tree.exp_img;
  99. me.expimage.onclick = me.toggle;
  100. }
  101. }
  102. // label
  103. this.label = $a($td(mytab, mytab.rows.length-2, tc-1), 'div');
  104. $y(this.label, this.opts.label_style);
  105. // image
  106. if(this.opts.show_icon) { // for second row, where children will come icon to be included
  107. var t2 = make_table($a(this.label,'div'), 1, 2, '100%', ['20px',null]);
  108. $y(t2,{borderCollapse:'collapse'});
  109. this.img_cell = $td(t2, 0, 0);
  110. $y(this.img_cell, {cursor:'pointer',verticalAlign:'middle',width:'20px'});
  111. if(!imagesrc) imagesrc = "lib/images/icons/folder.gif";
  112. this.usrimg = $a(this.img_cell, 'img');
  113. this.usrimg.src = imagesrc;
  114. this.label = $td(t2, 0, 1);
  115. $y(this.label,{verticalAlign:'middle'});
  116. }
  117. this.loading_div = $a($td(mytab, mytab.rows.length-1, this.opts.show_exp_img ? 1 : 0), "div", "comment", {fontSize:'11px'});
  118. $dh(this.loading_div);
  119. this.loading_div.innerHTML = 'Loading...';
  120. this.body = $a($td(mytab, mytab.rows.length-1, this.opts.show_exp_img ? 1 : 0), "div", '', {overflow:'hidden', display:'none'});
  121. this.select = function() {
  122. me.show_selected();
  123. if(me.onclick)me.onclick(me);
  124. }
  125. this.show_selected = function() {
  126. if(me.tree.cur_node)me.tree.cur_node.deselect();
  127. if(me.opts.onselect_style) $y(me.label,me.opts.onselect_style)
  128. //me.label.style.fontWeight = 'bold';
  129. me.tree.cur_node = me;
  130. }
  131. this.deselect = function() {
  132. if(me.opts.ondeselect_style) $y(me.label,me.opts.ondeselect_style)
  133. //me.label.style.fontWeight = 'normal';
  134. me.tree.cur_node=null
  135. }
  136. this.expanded = 0;
  137. this.toggle = function() {
  138. if(me.expanded)
  139. me.collapse();
  140. else
  141. me.expand();
  142. }
  143. this.collapse = function() {
  144. me.expanded = 0;
  145. $(me.body).slideUp();
  146. me.expimage.src = me.exp_img ? me.exp_img : me.tree.exp_img;
  147. }
  148. this.expand = function() {
  149. if(me.onexpand && !me.expanded_once){
  150. me.onexpand(me);
  151. if(!me.tree.do_animate) me.show_expanded(); // else to be called from expand (for animation)
  152. } else {
  153. me.show_expanded();
  154. }
  155. me.expanded = 1;
  156. me.expanded_once = 1;
  157. me.expimage.src = me.col_img ? me.col_img : me.tree.col_img;
  158. }
  159. this.show_expanded = function() {
  160. if(me.tree.do_animate && (!keys(me.nodes).length)) return; // no children
  161. $(me.body).slideDown();
  162. }
  163. this.setlabel = function(l) {
  164. me.label.value = l;
  165. me.label.innerHTML = l;
  166. }
  167. this.setlabel(this.text);
  168. this.setcolor = function(c) {
  169. this.backColor = c;
  170. if(cur_node!=this)
  171. $bg(this.body,this.backColor);
  172. }
  173. this.label.onclick= function(e) { me.select(); }
  174. this.label.ondblclick = function(e) { me.select(); if(me.ondblclick)me.ondblclick(me); }
  175. this.clear_child_nodes = function() {
  176. if(this.tab){
  177. this.tab.parentNode.removeChild(this.tab);
  178. delete this.tab;
  179. }
  180. this.expanded_once = 0;
  181. }
  182. }