11 The Accordion class creates a group of elements that are toggled when their handles are clicked. When one elements toggles in, the others toggles back.
14 The Accordion requires an XHTML doctype.
17 togglers - required, a collection of elements, the elements handlers that will be clickable.
18 elements - required, a collection of elements the transitions will be applied to.
19 options - optional, see options below, and <Fx.Base> options.
22 show - integer, the Index of the element to show at start.
23 display - integer, the Index of the element to show at start (with a transition). defaults to 0.
24 fixedHeight - integer, if you want the elements to have a fixed height. defaults to false.
25 fixedWidth - integer, if you want the elements to have a fixed width. defaults to false.
26 onActive - function to execute when an element starts to show
27 onBackground - function to execute when an element starts to hide
28 height - boolean, will add a height transition to the accordion if true. defaults to true.
29 opacity - boolean, will add an opacity transition to the accordion if true. defaults to true.
30 width - boolean, will add a width transition to the accordion if true. defaults to false, css mastery is required to make this work!
31 alwaysHide - boolean, will allow to hide all elements if true, instead of always keeping one element shown. defaults to false.
34 var Accordion = Fx.Elements.extend({
37 onActive: Class.empty,
38 onBackground: Class.empty,
50 initialize: function(){
51 var options, togglers, elements, container;
52 $each(arguments, function(argument, i){
53 switch($type(argument)){
54 case 'object': options = argument; break;
55 case 'element': container = $(argument); break;
57 var temp = $$(argument);
58 if (!togglers) togglers = temp;
62 this.togglers = togglers || [];
63 this.elements = elements || [];
64 this.container = $(container);
65 this.setOptions(options);
67 if (this.options.alwaysHide) this.options.wait = true;
68 if ($chk(this.options.show)){
69 this.options.display = false;
70 this.previous = this.options.show;
72 if (this.options.start){
73 this.options.display = false;
74 this.options.show = false;
77 if (this.options.opacity) this.effects.opacity = 'fullOpacity';
78 if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth';
79 if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight';
80 for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]);
81 this.elements.each(function(el, i){
82 if (this.options.show === i) this.fireEvent('onActive', [this.togglers[i], el]);
83 else for (var fx in this.effects) el.setStyle(fx, 0);
85 this.parent(this.elements);
86 if ($chk(this.options.display)) this.display(this.options.display);
89 addSection: function(toggler, element, pos){
92 var test = this.togglers.contains(toggler);
93 var len = this.togglers.length;
94 this.togglers.include(toggler);
95 this.elements.include(element);
96 if (len && (!test || pos)){
97 pos = $pick(pos, len - 1);
98 toggler.injectBefore(this.togglers[pos]);
99 element.injectAfter(toggler);
100 } else if (this.container && !test){
101 toggler.inject(this.container);
102 element.inject(this.container);
104 var idx = this.togglers.indexOf(toggler);
105 toggler.addEvent('click', this.display.bind(this, idx));
106 if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'});
107 if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'});
108 element.fullOpacity = 1;
109 if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth;
110 if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight;
111 element.setStyle('overflow', 'hidden');
112 if (!test) for (var fx in this.effects) element.setStyle(fx, 0);
118 Shows a specific section and hides all others. Useful when triggering an accordion from outside.
121 index - integer, the index of the item to show, or the actual element to show.
124 display: function(index){
125 index = ($type(index) == 'element') ? this.elements.indexOf(index) : index;
126 if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this;
127 this.previous = index;
129 this.elements.each(function(el, i){
131 if ((i != index) || (this.options.alwaysHide && (el.offsetHeight > 0))){
132 this.fireEvent('onBackground', [this.togglers[i], el]);
133 for (var fx in this.effects) obj[i][fx] = 0;
135 this.fireEvent('onActive', [this.togglers[i], el]);
136 for (var fx in this.effects) obj[i][fx] = el[this.effects[fx]];
139 return this.start(obj);
142 showThisHideOpen: function(index){return this.display(index)}
146 Fx.Accordion = Accordion;