aboutsummaryrefslogtreecommitdiffstats
path: root/template-common/jquery.accordion.js
diff options
context:
space:
mode:
Diffstat (limited to 'template-common/jquery.accordion.js')
-rw-r--r--template-common/jquery.accordion.js311
1 files changed, 311 insertions, 0 deletions
diff --git a/template-common/jquery.accordion.js b/template-common/jquery.accordion.js
new file mode 100644
index 000000000..ffa0711a5
--- /dev/null
+++ b/template-common/jquery.accordion.js
@@ -0,0 +1,311 @@
+/*
+ * jQuery UI Accordion 1.6
+ *
+ * Copyright (c) 2007 Jörn Zaefferer
+ *
+ * http://docs.jquery.com/UI/Accordion
+ *
+ * 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$
+ *
+ */
+
+;(function($) {
+
+// If the UI scope is not available, add it
+$.ui = $.ui || {};
+
+$.fn.extend({
+ accordion: function(options, data) {
+ var args = Array.prototype.slice.call(arguments, 1);
+
+ return this.each(function() {
+ if (typeof options == "string") {
+ var accordion = $.data(this, "ui-accordion");
+ accordion[options].apply(accordion, args);
+ // INIT with optional options
+ } else if (!$(this).is(".ui-accordion"))
+ $.data(this, "ui-accordion", new $.ui.accordion(this, options));
+ });
+ },
+ // deprecated, use accordion("activate", index) instead
+ activate: function(index) {
+ return this.accordion("activate", index);
+ }
+});
+
+$.ui.accordion = function(container, options) {
+
+ // setup configuration
+ this.options = options = $.extend({}, $.ui.accordion.defaults, options);
+ this.element = container;
+
+ $(container).addClass("ui-accordion");
+
+ if ( options.navigation ) {
+ var current = $(container).find("a").filter(options.navigationFilter);
+ if ( current.length ) {
+ if ( current.filter(options.header).length ) {
+ options.active = current;
+ } else {
+ options.active = current.parent().parent().prev();
+ current.addClass("current");
+ }
+ }
+ }
+
+ // calculate active if not specified, using the first header
+ options.headers = $(container).find(options.header);
+ options.active = findActive(options.headers, options.active);
+
+ if ( options.fillSpace ) {
+ var maxHeight = $(container).parent().height();
+ options.headers.each(function() {
+ maxHeight -= $(this).outerHeight();
+ });
+ var maxPadding = 0;
+ options.headers.next().each(function() {
+ maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());
+ }).height(maxHeight - maxPadding);
+ } else if ( options.autoheight ) {
+ var maxHeight = 0;
+ options.headers.next().each(function() {
+ maxHeight = Math.max(maxHeight, $(this).outerHeight());
+ }).height(maxHeight);
+ }
+
+ options.headers
+ .not(options.active || "")
+ .next()
+ .hide();
+ options.active.parent().andSelf().addClass(options.selectedClass);
+
+ if (options.event)
+ $(container).bind((options.event) + ".ui-accordion", clickHandler);
+};
+
+$.ui.accordion.prototype = {
+ activate: function(index) {
+ // call clickHandler with custom event
+ clickHandler.call(this.element, {
+ target: findActive( this.options.headers, index )[0]
+ });
+ },
+
+ enable: function() {
+ this.options.disabled = false;
+ },
+ disable: function() {
+ this.options.disabled = true;
+ },
+ destroy: function() {
+ this.options.headers.next().css("display", "");
+ if ( this.options.fillSpace || this.options.autoheight ) {
+ this.options.headers.next().css("height", "");
+ }
+ $.removeData(this.element, "ui-accordion");
+ $(this.element).removeClass("ui-accordion").unbind(".ui-accordion");
+ }
+}
+
+function scopeCallback(callback, scope) {
+ return function() {
+ return callback.apply(scope, arguments);
+ };
+}
+
+function completed(cancel) {
+ // if removed while animated data can be empty
+ if (!$.data(this, "ui-accordion"))
+ return;
+ var instance = $.data(this, "ui-accordion");
+ var options = instance.options;
+ options.running = cancel ? 0 : --options.running;
+ if ( options.running )
+ return;
+ if ( options.clearStyle ) {
+ options.toShow.add(options.toHide).css({
+ height: "",
+ overflow: ""
+ });
+ }
+ $(this).triggerHandler("change.ui-accordion", [options.data], options.change);
+}
+
+function toggle(toShow, toHide, data, clickedActive, down) {
+ var options = $.data(this, "ui-accordion").options;
+ options.toShow = toShow;
+ options.toHide = toHide;
+ options.data = data;
+ var complete = scopeCallback(completed, this);
+
+ // count elements to animate
+ options.running = toHide.size() == 0 ? toShow.size() : toHide.size();
+
+ if ( options.animated ) {
+ if ( !options.alwaysOpen && clickedActive ) {
+ $.ui.accordion.animations[options.animated]({
+ toShow: jQuery([]),
+ toHide: toHide,
+ complete: complete,
+ down: down,
+ autoheight: options.autoheight
+ });
+ } else {
+ $.ui.accordion.animations[options.animated]({
+ toShow: toShow,
+ toHide: toHide,
+ complete: complete,
+ down: down,
+ autoheight: options.autoheight
+ });
+ }
+ } else {
+ if ( !options.alwaysOpen && clickedActive ) {
+ toShow.toggle();
+ } else {
+ toHide.hide();
+ toShow.show();
+ }
+ complete(true);
+ }
+}
+
+function clickHandler(event) {
+ var options = $.data(this, "ui-accordion").options;
+ if (options.disabled)
+ return false;
+
+ // called only when using activate(false) to close all parts programmatically
+ if ( !event.target && !options.alwaysOpen ) {
+ options.active.parent().andSelf().toggleClass(options.selectedClass);
+ var toHide = options.active.next(),
+ data = {
+ instance: this,
+ options: options,
+ newHeader: jQuery([]),
+ oldHeader: options.active,
+ newContent: jQuery([]),
+ oldContent: toHide
+ },
+ toShow = options.active = $([]);
+ toggle.call(this, toShow, toHide, data );
+ return false;
+ }
+ // get the click target
+ var clicked = $(event.target);
+
+ // due to the event delegation model, we have to check if one
+ // of the parent elements is our actual header, and find that
+ if ( clicked.parents(options.header).length )
+ while ( !clicked.is(options.header) )
+ clicked = clicked.parent();
+
+ var clickedActive = clicked[0] == options.active[0];
+
+ // if animations are still active, or the active header is the target, ignore click
+ if (options.running || (options.alwaysOpen && clickedActive))
+ return false;
+ if (!clicked.is(options.header))
+ return;
+
+ // switch classes
+ options.active.parent().andSelf().toggleClass(options.selectedClass);
+ if ( !clickedActive ) {
+ clicked.parent().andSelf().addClass(options.selectedClass);
+ }
+
+ // find elements to show and hide
+ var toShow = clicked.next(),
+ toHide = options.active.next(),
+ //data = [clicked, options.active, toShow, toHide],
+ data = {
+ instance: this,
+ options: options,
+ newHeader: clicked,
+ oldHeader: options.active,
+ newContent: toShow,
+ oldContent: toHide
+ },
+ down = options.headers.index( options.active[0] ) > options.headers.index( clicked[0] );
+
+ options.active = clickedActive ? $([]) : clicked;
+ toggle.call(this, toShow, toHide, data, clickedActive, down );
+
+ return false;
+};
+
+function findActive(headers, selector) {
+ return selector != undefined
+ ? typeof selector == "number"
+ ? headers.filter(":eq(" + selector + ")")
+ : headers.not(headers.not(selector))
+ : selector === false
+ ? $([])
+ : headers.filter(":eq(0)");
+}
+
+$.extend($.ui.accordion, {
+ defaults: {
+ selectedClass: "selected",
+ alwaysOpen: true,
+ animated: 'slide',
+ event: "click",
+ header: "a",
+ autoheight: true,
+ running: 0,
+ navigationFilter: function() {
+ return this.href.toLowerCase() == location.href.toLowerCase();
+ }
+ },
+ animations: {
+ slide: function(options, additions) {
+ options = $.extend({
+ easing: "swing",
+ duration: 300
+ }, options, additions);
+ if ( !options.toHide.size() ) {
+ options.toShow.animate({height: "show"}, options);
+ return;
+ }
+ var hideHeight = options.toHide.height(),
+ showHeight = options.toShow.height(),
+ difference = showHeight / hideHeight;
+ options.toShow.css({ height: 0, overflow: 'hidden' }).show();
+ options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate({height:"hide"},{
+ step: function(now) {
+ var current = (hideHeight - now) * difference;
+ if ($.browser.msie || $.browser.opera) {
+ current = Math.ceil(current);
+ }
+ options.toShow.height( current );
+ },
+ duration: options.duration,
+ easing: options.easing,
+ complete: function() {
+ if ( !options.autoheight ) {
+ options.toShow.css("height", "auto");
+ }
+ options.complete();
+ }
+ });
+ },
+ bounceslide: function(options) {
+ this.slide(options, {
+ easing: options.down ? "bounceout" : "swing",
+ duration: options.down ? 1000 : 200
+ });
+ },
+ easeslide: function(options) {
+ this.slide(options, {
+ easing: "easeinout",
+ duration: 700
+ })
+ }
+ }
+});
+
+})(jQuery);