PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/openconstructor/i/newskin/js/jquery.treeview.js

http://openconstructor.googlecode.com/
JavaScript | 269 lines | 204 code | 23 blank | 42 comment | 19 complexity | 77a5ed0c3e5e7cdf82911f0a3e32a358 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * Treeview 1.4 - jQuery plugin to hide and show branches of a tree
  3. *
  4. * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/
  5. * http://docs.jquery.com/Plugins/Treeview
  6. *
  7. * Copyright (c) 2007 J??rn Zaefferer
  8. *
  9. * Dual licensed under the MIT and GPL licenses:
  10. * http://www.opensource.org/licenses/mit-license.php
  11. * http://www.gnu.org/licenses/gpl.html
  12. *
  13. * Revision: $Id: jquery.treeview.js 4684 2008-02-07 19:08:06Z joern.zaefferer $
  14. *
  15. */
  16. ;(function($) {
  17. $.extend($.fn, {
  18. swapClass: function(c1, c2) {
  19. var c1Elements = this.filter('.' + c1);
  20. this.filter('.' + c2).removeClass(c2).addClass(c1);
  21. c1Elements.removeClass(c1).addClass(c2);
  22. return this;
  23. },
  24. replaceClass: function(c1, c2) {
  25. return this.filter('.' + c1).removeClass(c1).addClass(c2).end();
  26. },
  27. hoverClass: function(className) {
  28. className = className || "hover";
  29. return this.hover(function() {
  30. $(this).addClass(className);
  31. }, function() {
  32. $(this).removeClass(className);
  33. });
  34. },
  35. heightToggle: function(animated, callback) {
  36. animated ?
  37. this.animate({ height: "toggle" }, animated, callback) :
  38. this.each(function(){
  39. jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
  40. if(callback)
  41. callback.apply(this, arguments);
  42. });
  43. },
  44. heightHide: function(animated, callback) {
  45. if (animated) {
  46. this.animate({ height: "hide" }, animated, callback);
  47. } else {
  48. this.hide();
  49. if (callback)
  50. this.each(callback);
  51. }
  52. },
  53. prepareBranches: function(settings) {
  54. if (!settings.prerendered) {
  55. // mark last tree items
  56. this.filter(":last-child:not(ul)").addClass(CLASSES.last);
  57. // collapse whole tree, or only those marked as closed, anyway except those marked as open
  58. this.filter((settings.collapsed ? "" : "." + CLASSES.closed) + ":not(." + CLASSES.open + ")").find(">ul").hide();
  59. }
  60. // return all items with sublists
  61. return this.filter(":has(>ul)");
  62. },
  63. applyClasses: function(settings, toggler) {
  64. if (settings.link_unfold_onclick) {
  65. this.filter(":has(>ul):not(:has(>a))").find(">span span.fldname").click(function(event) {
  66. toggler.apply($(this).parent().next());
  67. }).add( $("a", this) ).hoverClass();
  68. }
  69. if (!settings.prerendered) {
  70. // handle closed ones first
  71. this.filter(":has(>ul:hidden)")
  72. .addClass(CLASSES.expandable)
  73. .replaceClass(CLASSES.last, CLASSES.lastExpandable);
  74. // handle open ones
  75. this.not(":has(>ul:hidden)")
  76. .addClass(CLASSES.collapsable)
  77. .replaceClass(CLASSES.last, CLASSES.lastCollapsable);
  78. // create hitarea
  79. this.prepend("<div class=\"" + CLASSES.hitarea + "\"/>").find("div." + CLASSES.hitarea).each(function() {
  80. var classes = "";
  81. $.each($(this).parent().attr("class").split(" "), function() {
  82. classes += this + "-hitarea ";
  83. });
  84. $(this).addClass( classes );
  85. });
  86. }
  87. // apply event to hitarea
  88. this.find("div." + CLASSES.hitarea).click( toggler );
  89. },
  90. treeview: function(settings) {
  91. settings = $.extend({
  92. cookieId: "treeview"
  93. }, settings);
  94. if (settings.add) {
  95. return this.trigger("add", [settings.add]);
  96. }
  97. if ( settings.toggle ) {
  98. var callback = settings.toggle;
  99. settings.toggle = function() {
  100. return callback.apply($(this).parent()[0], arguments);
  101. };
  102. }
  103. // factory for treecontroller
  104. function treeController(tree, control) {
  105. // factory for click handlers
  106. function handler(filter) {
  107. return function() {
  108. // reuse toggle event handler, applying the elements to toggle
  109. // start searching for all hitareas
  110. toggler.apply( $("div." + CLASSES.hitarea, tree).filter(function() {
  111. // for plain toggle, no filter is provided, otherwise we need to check the parent element
  112. return filter ? $(this).parent("." + filter).length : true;
  113. }) );
  114. return false;
  115. };
  116. }
  117. // click on first element to collapse tree
  118. $("a:eq(0)", control).click( handler(CLASSES.collapsable) );
  119. // click on second to expand tree
  120. $("a:eq(1)", control).click( handler(CLASSES.expandable) );
  121. // click on third to toggle tree
  122. $("a:eq(2)", control).click( handler() );
  123. }
  124. // handle toggle event
  125. function toggler() {
  126. $(this)
  127. .parent()
  128. // swap classes for hitarea
  129. .find(">.hitarea")
  130. .swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
  131. .swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea )
  132. .end()
  133. // swap classes for parent li
  134. .swapClass( CLASSES.collapsable, CLASSES.expandable )
  135. .swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
  136. // find child lists
  137. .find( ">ul" )
  138. // toggle them
  139. .heightToggle( settings.animated, settings.toggle );
  140. if ( settings.unique ) {
  141. $(this).parent()
  142. .siblings()
  143. // swap classes for hitarea
  144. .find(">.hitarea")
  145. .replaceClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
  146. .replaceClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea )
  147. .end()
  148. .replaceClass( CLASSES.collapsable, CLASSES.expandable )
  149. .replaceClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
  150. .find( ">ul" )
  151. .heightHide( settings.animated, settings.toggle );
  152. }
  153. }
  154. function serialize() {
  155. function binary(arg) {
  156. return arg ? 1 : 0;
  157. }
  158. var data = [];
  159. branches.each(function(i, e) {
  160. data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0;
  161. });
  162. $.cookie(settings.cookieId, data.join("") );
  163. }
  164. function deserialize() {
  165. var stored = $.cookie(settings.cookieId);
  166. if ( stored ) {
  167. var data = stored.split("");
  168. branches.each(function(i, e) {
  169. $(e).find(">ul")[ parseInt(data[i]) ? "show" : "hide" ]();
  170. });
  171. }
  172. }
  173. // add treeview class to activate styles
  174. this.addClass("treeview");
  175. // prepare branches and find all tree items with child lists
  176. var branches = this.find("li").prepareBranches(settings);
  177. switch(settings.persist) {
  178. case "cookie":
  179. var toggleCallback = settings.toggle;
  180. settings.toggle = function() {
  181. serialize();
  182. if (toggleCallback) {
  183. toggleCallback.apply(this, arguments);
  184. }
  185. };
  186. deserialize();
  187. break;
  188. case "location":
  189. var current = this.find("a").filter(function() { return this.href.toLowerCase() == location.href.toLowerCase(); });
  190. if ( current.length ) {
  191. current.addClass("selected").parents("ul, li").add( current.parent().parent().next() ).show();
  192. }
  193. break;
  194. case "curnode":
  195. var current = this.find("a").filter(function() { return this.id == $.cookie('curnode'); });
  196. if ( current.length ) {
  197. current.addClass("selected").parents("ul, li").add( current.parent().parent().next() ).show();
  198. }
  199. break;
  200. case "multiple":
  201. var current = this.find("img").filter(function() {
  202. ids = $.cookie('curnode').split(',');
  203. return ids.find($(this).attr('index'));
  204. });
  205. if ( current.length ) {
  206. current.addClass("selected").parents("ul, li").add( current.parent().next() ).show();
  207. }
  208. break;
  209. }
  210. branches.applyClasses(settings, toggler);
  211. // if control option is set, create the treecontroller and show it
  212. if ( settings.control ) {
  213. treeController(this, settings.control);
  214. $(settings.control).show();
  215. }
  216. return this.bind("add", function(event, branches) {
  217. $(branches).prev()
  218. .removeClass(CLASSES.last)
  219. .removeClass(CLASSES.lastCollapsable)
  220. .removeClass(CLASSES.lastExpandable)
  221. .find(">.hitarea")
  222. .removeClass(CLASSES.lastCollapsableHitarea)
  223. .removeClass(CLASSES.lastExpandableHitarea);
  224. $(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings, toggler);
  225. });
  226. }
  227. });
  228. // classes used by the plugin
  229. // need to be styled via external stylesheet, see first example
  230. var CLASSES = $.fn.treeview.classes = {
  231. open: "open",
  232. closed: "closed",
  233. expandable: "expandable",
  234. expandableHitarea: "expandable-hitarea",
  235. lastExpandableHitarea: "lastExpandable-hitarea",
  236. collapsable: "collapsable",
  237. collapsableHitarea: "collapsable-hitarea",
  238. lastCollapsableHitarea: "lastCollapsable-hitarea",
  239. lastCollapsable: "lastCollapsable",
  240. lastExpandable: "lastExpandable",
  241. last: "last",
  242. hitarea: "hitarea"
  243. };
  244. // provide backwards compability
  245. $.fn.Treeview = $.fn.treeview;
  246. })(jQuery);