/* * Treeview pre-1.4.1 - jQuery plugin to hide and show branches of a tree *  * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/ * http://docs.jquery.com/Plugins/Treeview * * Copyright (c) 2007 Jörn Zaefferer * * Dual licensed under the MIT and GPL licenses: *   http://www.opensource.org/licenses/mit-license.php *   http://www.gnu.org/licenses/gpl.html * * Revision: $Id: jquery.treeview.js 5324 2008-04-25 13:13:02Z joern.zaefferer $ * */;(function($) {$.extend($.fn, {swapClass: function(c1, c2) {var c1Elements = this.filter('.' + c1);this.filter('.' + c2).removeClass(c2).addClass(c1);c1Elements.removeClass(c1).addClass(c2);return this;},replaceClass: function(c1, c2) {return this.filter('.' + c1).removeClass(c1).addClass(c2).end();},hoverClass: function(className) {className = className || "hover";return this.hover(function() {$(this).addClass(className);}, function() {$(this).removeClass(className);});},heightToggle: function(animated, callback) {animated ?this.animate({ height: "toggle" }, animated, callback) :this.each(function(){jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();if(callback)callback.apply(this, arguments);});},heightHide: function(animated, callback) {if (animated) {this.animate({ height: "hide" }, animated, callback);} else {this.hide();if (callback)this.each(callback);				}},prepareBranches: function(settings) {if (!settings.prerendered) {// mark last tree itemsthis.filter(":last-child:not(ul)").addClass(CLASSES.last);// collapse whole tree, or only those marked as closed, anyway except those marked as openthis.filter((settings.collapsed ? "" : "." + CLASSES.closed) + ":not(." + CLASSES.open + ")").find(">ul").hide();}// return all items with sublistsreturn this.filter(":has(>ul)");},applyClasses: function(settings, toggler) {this.filter(":has(>ul):not(:has(>a))").find(">span").unbind("click.treeview").bind("click.treeview", function(event) {// don't handle click events on children, eg. checkboxesif ( this == event.target )toggler.apply($(this).next());}).add( $("a", this) ).hoverClass();if (!settings.prerendered) {// handle closed ones firstthis.filter(":has(>ul:hidden)").addClass(CLASSES.expandable).replaceClass(CLASSES.last, CLASSES.lastExpandable);// handle open onesthis.not(":has(>ul:hidden)").addClass(CLASSES.collapsable).replaceClass(CLASSES.last, CLASSES.lastCollapsable);            // create hitarea if not presentvar hitarea = this.find("div." + CLASSES.hitarea);if (!hitarea.length)hitarea = this.prepend("<div class=\"" + CLASSES.hitarea + "\"/>").find("div." + CLASSES.hitarea);hitarea.removeClass().addClass(CLASSES.hitarea).each(function() {var classes = "";$.each($(this).parent().attr("class").split(" "), function() {classes += this + "-hitarea ";});$(this).addClass( classes );})}// apply event to hitareathis.find("div." + CLASSES.hitarea).click( toggler );},treeview: function(settings) {settings = $.extend({cookieId: "treeview"}, settings);if ( settings.toggle ) {var callback = settings.toggle;settings.toggle = function() {return callback.apply($(this).parent()[0], arguments);};}// factory for treecontrollerfunction treeController(tree, control) {// factory for click handlersfunction handler(filter) {return function() {// reuse toggle event handler, applying the elements to toggle// start searching for all hitareastoggler.apply( $("div." + CLASSES.hitarea, tree).filter(function() {// for plain toggle, no filter is provided, otherwise we need to check the parent elementreturn filter ? $(this).parent("." + filter).length : true;}) );return false;};}// click on first element to collapse tree$("a:eq(0)", control).click( handler(CLASSES.collapsable) );// click on second to expand tree$("a:eq(1)", control).click( handler(CLASSES.expandable) );// click on third to toggle tree$("a:eq(2)", control).click( handler() ); }// handle toggle eventfunction toggler() {$(this).parent()// swap classes for hitarea.find(">.hitarea").swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea ).swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea ).end()// swap classes for parent li.swapClass( CLASSES.collapsable, CLASSES.expandable ).swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )// find child lists.find( ">ul" )// toggle them.heightToggle( settings.animated, settings.toggle );if ( settings.unique ) {$(this).parent().siblings()// swap classes for hitarea.find(">.hitarea").replaceClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea ).replaceClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea ).end().replaceClass( CLASSES.collapsable, CLASSES.expandable ).replaceClass( CLASSES.lastCollapsable, CLASSES.lastExpandable ).find( ">ul" ).heightHide( settings.animated, settings.toggle );}}this.data("toggler", toggler);function serialize() {function binary(arg) {return arg ? 1 : 0;}var data = [];branches.each(function(i, e) {data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0;});$.cookie(settings.cookieId, data.join("") );}function deserialize() {var stored = $.cookie(settings.cookieId);if ( stored ) {var data = stored.split("");branches.each(function(i, e) {$(e).find(">ul")[ parseInt(data[i]) ? "show" : "hide" ]();});}}// add treeview class to activate stylesthis.addClass("treeview");// prepare branches and find all tree items with child listsvar branches = this.find("li").prepareBranches(settings);switch(settings.persist) {case "cookie":var toggleCallback = settings.toggle;settings.toggle = function() {serialize();if (toggleCallback) {toggleCallback.apply(this, arguments);}};deserialize();break;case "location":var current = this.find("a").filter(function() { return this.href.toLowerCase() == location.href.toLowerCase(); });if ( current.length ) {current.addClass("selected").parents("ul, li").add( current.next() ).show();}break;}branches.applyClasses(settings, toggler);// if control option is set, create the treecontroller and show itif ( settings.control ) {treeController(this, settings.control);$(settings.control).show();}return this;}});// classes used by the plugin// need to be styled via external stylesheet, see first example$.treeview = {};var CLASSES = ($.treeview.classes = {open: "open",closed: "closed",expandable: "expandable",expandableHitarea: "expandable-hitarea",lastExpandableHitarea: "lastExpandable-hitarea",collapsable: "collapsable",collapsableHitarea: "collapsable-hitarea",lastCollapsableHitarea: "lastCollapsable-hitarea",lastCollapsable: "lastCollapsable",lastExpandable: "lastExpandable",last: "last",hitarea: "hitarea"});// provide backwards compability$.fn.Treeview = $.fn.treeview;})(jQuery);
