

/*

 * jQuery Accordion Plug-in

 *

 * Based on code published by John Resig.

 *

 * Revision: 3

 * Version: 0.3

 *

 * Revision History

 * v0.3

 * - Added a "hack" to fix bug which could occur if another panel

 *   was clicked to be open before the previous panel was fully open.

 *   You can not open another panel until the previous one is fully open.

 *

 * v0.2

 * - Added code to try and future proof the step() code.

 * - Added check for jQuery v1.2+

 *

 * v0.1

 * - First public release

 *

*/

(function ($){

 

	// set the defaults

	var defaults = {

		easing: "linear",

		duration: 300,

		onSelected: function (){}

	}

	, settings, bPercBased=(parseFloat(jQuery.fn.jquery) >= 1.2);

 

	// set default options

	$.accordion = {

		version: "0.3",

		setDefaults: function(options){

			$.extend(defaults, options);

		},

		setSettings: function(options){

			$.extend(settings, options);

		}

	};

 

	/*

	 * jQuery.fn.accordion()

	 *

	 * Examples:

	 * $("dl").accordion();

	 * > Creates an accordion out of a DL element

	 *

	 */

	// the accordion() method

	$.fn.accordion = function(options){

		// get the current settings

		settings = jQuery.extend({}, defaults, options);

 

		// create a reference to the current jQuery object

		var me = this, bRunning = false;

 

		// hide everything but the first

		$("dd:not(:first)", me).hide();

 

		// show the first dd

		$("dd:first", me).show();

 

		// make the first accordion active

		$("dt:first", me).addClass("focus");

 

		// add the click event handler

		$("dt a", me).click(function(){

			// blur the anchor (so it's not outlined)

			this.blur();

 

			// do not allow if animation running. this is quick hack to prevent errors

			// from occuring another panel was clicked on while the previous panel was

			// still in the process of being opened. in the long run better handling

			// should be added, but until you can cancel an jQuery FX, this is the

			// most straightforward hack

			if( bRunning ) return false;

 

			$("dt").removeClass("focus");

 

			$(this).parent("dt").addClass("focus");

 

			var visible = $("dd:visible", me),

				height = visible.height(),

				hidden = $(this).parent().next();

 

			if ( !hidden.is(":visible") ) {

				hidden.show();

 

				// an animation is running

				bRunning = true;

 

				visible.animate(

					{height:"hide"},

					{

						step: function(n){

							hidden.height(

								// if using jQuery v1.2+, then "n" is a percentage that indicates

								// the percentage of completion (0 - 1) of current animation step.

								// older versions of jQuery (v1.1 and below) pass in the current

								// pixel value of the effect

								Math.ceil( (bPercBased) ? (height - (height * n)) : (height - n) )

							);

						},

						complete: function(){

							// animation is complete

							bRunning = false;

						},

						duration: settings.duration,

						easing: settings.easing

					}

				);

			}

			settings.onSelected(this);

 

			return false;

		});

 

		// return the values as a comma-delimited string

		return me;

	};

 

})(jQuery);

