/** * @author Leonard Martin * @author Luke Cuthbertson * @version 1.3.2 */ (function($){ $.fn.accordion = function(options) { var $this = $(this); var defaults = { node: 'div.node', heading: 'h2', content: 'div.content', open: 'open', speed: 'slow', update: [], forceClose: true, blockLinks: true }; var opts = $.extend(defaults, options); return $(this).each(function(){ var nodes = $(opts.node,this); var openElm = null; //if you do not supply a node - then all nodes will close/open $(this).bind('close', function(e, node){ closeElem(node,function(){ update(node,true); openElm = null; }); }) $(this).bind('open', function(e, node){ var n = nodes || $(node); n.each(function(){ if(!$(this).data('open')) if(toggleElem(this)) { openElm = this; } }); }) nodes.each(function(){ var obj = this; setDims(this); if($(this).hasClass(opts.open) && (!openElm || !opts.forceClose)) { openElm = obj; update(obj,true); setTimeout(function(){$this.trigger('onopen',obj);}, 0); $(this).data('open', true); $(this).data('closed', false); } else { $(this).removeClass(opts.open); $(opts.content,this).hide(); update(obj,false); setTimeout(function(){$this.trigger('onclose',obj);}, 0); $(this).data('open', false); $(this).data('closed', true); }; //make sure the content is relatively positioned - IE $(opts.content, obj).css('position', 'relative'); $(this).find(opts.heading) .each(function(i){ if($(this).attr('checked')){ /** * @todo set open/closed */ }; }) .css({cursor:'pointer'}) .click(function(e){ //FF fires click event on input as well as label, IE does not //to even out cancel event on label and manually trigger event on input var tag = $(this).attr('nodeName').toLowerCase(); var type = $(this).attr('type'); if(tag == 'label'){ $('#'+$(this).attr('htmlFor')).click(); return false; }; // if(openElm && openElm != obj && opts.forceClose) { closeElem(openElm,function(){ if(toggleElem(obj)) { openElm = obj; } }); } else { if (openElm && $this.find(opts.heading).attr('type') == 'radio') { return; }; if(toggleElem(obj)) { openElm = obj; update(obj,true); }; }; //cancel default on things that would cause page to reload if (tag == 'a' || tag == 'input' && type == 'submit') { return false; }; return false; }) .find('a').each(function(){ if(opts.blockLinks) { $(this).click(function(e){e.preventDefault();}); }; }); }); }); function setDims(node) { $(opts.content,node) .show() /*.each(function(){ var w = this.offsetWidth, h = this.offsetHeight; $(this).css({width:w+'px',height:h+'px'}); });*/ if (!$(node).hasClass(opts.open)) { $(opts.content,node).hide(); }; }; function closeElem(node,callback) { if ($(opts.content, node||$this).length > 0) { $(opts.content, node||$this).slideUp(opts.speed, function(){ $this.trigger('onclose',node); if (node) { $(node) .data('open', false) .removeClass(opts.open); } else{ $this .find(opts.node) .data('open', false) .removeClass(opts.open); } callback(); }); } else{ $(node).removeClass(opts.open); $this.trigger('onclose',node) callback(); }; update(node,false); }; function update(node,isopen) { for(var i=0;i 0) { if ($(node).data('open')) { $(opts.content, node).slideDown(opts.speed, function(){ $('*', node).css({ height: '' }); }); } else{ $(opts.content, node).slideUp(opts.speed, function(){ if (!$(node).data('open')) { $(node).removeClass(opts.open); $this.trigger('onclose', node); } }); } } update(node,open); return open; }; }; })(jQuery);