dwz.tree.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /**
  2. * @author Roger Wu
  3. * @version 1.0
  4. * added extend property oncheck
  5. */
  6. (function($){
  7. $.extend($.fn, {
  8. jTree:function(options) {
  9. var op = $.extend({checkFn:null, selected:"selected", exp:"expandable", coll:"collapsable", firstExp:"first_expandable", firstColl:"first_collapsable", lastExp:"last_expandable", lastColl:"last_collapsable", folderExp:"folder_expandable", folderColl:"folder_collapsable", endExp:"end_expandable", endColl:"end_collapsable",file:"file",ck:"checked", unck:"unchecked"}, options);
  10. return this.each(function(){
  11. var $this = $(this);
  12. var cnum = $this.children().length;
  13. $(">li", $this).each(function(){
  14. var $li = $(this);
  15. var first = $li.prev()[0]?false:true;
  16. var last = $li.next()[0]?false:true;
  17. $li.genTree({
  18. icon:$this.hasClass("treeFolder"),
  19. ckbox:$this.hasClass("treeCheck"),
  20. options: op,
  21. level: 0,
  22. exp:(cnum>1?(first?op.firstExp:(last?op.lastExp:op.exp)):op.endExp),
  23. coll:(cnum>1?(first?op.firstColl:(last?op.lastColl:op.coll)):op.endColl),
  24. showSub:(!$this.hasClass("collapse") && ($this.hasClass("expand") || (cnum>1?(first?true:false):true))),
  25. isLast:(cnum>1?(last?true:false):true)
  26. });
  27. });
  28. setTimeout(function(){
  29. if($this.hasClass("treeCheck")){
  30. var checkFn = eval($this.attr("oncheck"));
  31. if(checkFn && $.isFunction(checkFn)) {
  32. $("div.ckbox", $this).each(function(){
  33. var ckbox = $(this);
  34. ckbox.click(function(){
  35. var checked = $(ckbox).hasClass("checked");
  36. var items = [];
  37. if(checked){
  38. var tnode = $(ckbox).parent().parent();
  39. var boxes = $("input", tnode);
  40. if(boxes.size() > 1) {
  41. $(boxes).each(function(){
  42. items[items.length] = {name:$(this).attr("name"), value:$(this).val(), text:$(this).attr("text")};
  43. });
  44. } else {
  45. items = {name:boxes.attr("name"), value:boxes.val(), text:boxes.attr("text")};
  46. }
  47. }
  48. checkFn({checked:checked, items:items});
  49. });
  50. });
  51. }
  52. }
  53. $("a", $this).click(function(event){
  54. $("div." + op.selected, $this).removeClass(op.selected);
  55. var parent = $(this).parent().addClass(op.selected);
  56. var $li = $(this).parents("li:first"), sTarget = $li.attr("target");
  57. if (sTarget) {
  58. if ($("#"+sTarget, $this).size() == 0) {
  59. $this.prepend('<input id="'+sTarget+'" type="hidden" />');
  60. }
  61. $("#"+sTarget, $this).val($li.attr("rel"));
  62. }
  63. $(".ckbox",parent).trigger("click");
  64. event.stopPropagation();
  65. $(document).trigger("click");
  66. if (!$(this).attr("target")) return false;
  67. });
  68. },1);
  69. });
  70. },
  71. subTree:function(op, level) {
  72. return this.each(function(){
  73. $(">li", this).each(function(){
  74. var $this = $(this);
  75. var isLast = ($this.next()[0]?false:true);
  76. $this.genTree({
  77. icon:op.icon,
  78. ckbox:op.ckbox,
  79. exp:isLast?op.options.lastExp:op.options.exp,
  80. coll:isLast?op.options.lastColl:op.options.coll,
  81. options:op.options,
  82. level:level,
  83. space:isLast?null:op.space,
  84. showSub:op.showSub,
  85. isLast:isLast
  86. });
  87. });
  88. });
  89. },
  90. genTree:function(options) {
  91. var op = $.extend({icon:options.icon,ckbox:options.ckbox,exp:"", coll:"", showSub:false, level:0, options:null, isLast:false}, options);
  92. return this.each(function(){
  93. var node = $(this);
  94. var tree = $(">ul", node);
  95. var parent = node.parent().prev();
  96. var checked = 'unchecked';
  97. if(op.ckbox) {
  98. if($(">.checked",parent).size() > 0) checked = 'checked';
  99. }
  100. if (tree.size()>0) {
  101. node.children(":first").wrap("<div></div>");
  102. $(">div", node).prepend("<div class='" + (op.showSub ? op.coll : op.exp) + "'></div>"+(op.ckbox ?"<div class='ckbox " + checked + "'></div>":"")+(op.icon?"<div class='"+ (op.showSub ? op.options.folderColl : op.options.folderExp) +"'></div>":""));
  103. op.showSub ? tree.show() : tree.hide();
  104. $(">div>div:first,>div>a", node).click(function(){
  105. var $fnode = $(">li:first",tree);
  106. if($fnode.children(":first").isTag('a')) tree.subTree(op, op.level + 1);
  107. var $this = $(this);
  108. var isA = $this.isTag('a');
  109. var $this = isA?$(">div>div", node).eq(op.level):$this;
  110. if (!isA || tree.is(":hidden")) {
  111. $this.toggleClass(op.exp).toggleClass(op.coll);
  112. if (op.icon) {
  113. $(">div>div:last", node).toggleClass(op.options.folderExp).toggleClass(op.options.folderColl);
  114. }
  115. }
  116. (tree.is(":hidden"))?tree.slideDown("fast"):(isA?"":tree.slideUp("fast"));
  117. return false;
  118. });
  119. addSpace(op.level, node);
  120. if(op.showSub) tree.subTree(op, op.level + 1);
  121. } else {
  122. node.children().wrap("<div></div>");
  123. $(">div", node).prepend("<div class='node'></div>"+(op.ckbox?"<div class='ckbox "+checked+"'></div>":"")+(op.icon?"<div class='file'></div>":""));
  124. addSpace(op.level, node);
  125. if(op.isLast)$(node).addClass("last");
  126. }
  127. if (op.ckbox) node._check(op);
  128. $(">div",node).mouseover(function(){
  129. $(this).addClass("hover");
  130. }).mouseout(function(){
  131. $(this).removeClass("hover");
  132. });
  133. if(/msie/.test(navigator.userAgent.toLowerCase()))
  134. $(">div",node).click(function(){
  135. $("a", this).trigger("click");
  136. return false;
  137. });
  138. });
  139. function addSpace(level,node) {
  140. if (level > 0) {
  141. var parent = node.parent().parent();
  142. var space = !parent.next()[0]?"indent":"line";
  143. var plist = "<div class='" + space + "'></div>";
  144. if (level > 1) {
  145. var next = $(">div>div", parent).filter(":first");
  146. var prev = "";
  147. while(level > 1){
  148. prev = prev + "<div class='" + next.attr("class") + "'></div>";
  149. next = next.next();
  150. level--;
  151. }
  152. plist = prev + plist;
  153. }
  154. $(">div", node).prepend(plist);
  155. }
  156. }
  157. },
  158. _check:function(op) {
  159. var node = $(this);
  160. var ckbox = $(">div>.ckbox", node);
  161. var $input = node.find("a");
  162. var tname = $input.attr("tname"), tvalue = $input.attr("tvalue");
  163. var attrs = "text='"+$input.text()+"' ";
  164. if (tname) attrs += "name='"+tname+"' ";
  165. if (tvalue) attrs += "value='"+tvalue+"' ";
  166. ckbox.append("<input type='checkbox' style='display:none;' " + attrs + "/>").click(function(){
  167. var cked = ckbox.hasClass("checked");
  168. var aClass = cked?"unchecked":"checked";
  169. var rClass = cked?"checked":"unchecked";
  170. ckbox.removeClass(rClass).removeClass(!cked?"indeterminate":"").addClass(aClass);
  171. $("input", ckbox).attr("checked", !cked);
  172. $(">ul", node).find("li").each(function(){
  173. var box = $("div.ckbox", this);
  174. box.removeClass(rClass).removeClass(!cked?"indeterminate":"").addClass(aClass)
  175. .find("input").attr("checked", !cked);
  176. });
  177. $(node)._checkParent();
  178. return false;
  179. });
  180. var cAttr = $input.attr("checked") || false;
  181. if (cAttr) {
  182. ckbox.find("input").attr("checked", true);
  183. ckbox.removeClass("unchecked").addClass("checked");
  184. $(node)._checkParent();
  185. }
  186. },
  187. _checkParent:function(){
  188. if($(this).parent().hasClass("tree")) return;
  189. var parent = $(this).parent().parent();
  190. var stree = $(">ul", parent);
  191. var ckbox = stree.find(">li>a").size()+stree.find("div.ckbox").size();
  192. var ckboxed = stree.find("div.checked").size();
  193. var aClass = (ckboxed==ckbox?"checked":(ckboxed!=0?"indeterminate":"unchecked"));
  194. var rClass = (ckboxed==ckbox?"indeterminate":(ckboxed!=0?"checked":"indeterminate"));
  195. $(">div>.ckbox", parent).removeClass("unchecked").removeClass("checked").removeClass(rClass).addClass(aClass);
  196. var $checkbox = $(":checkbox", parent);
  197. if (aClass == "checked") $checkbox.attr("checked","checked");
  198. else if (aClass == "unchecked") $checkbox.removeAttr("checked");
  199. parent._checkParent();
  200. }
  201. });
  202. })(jQuery);