]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dijit/layout/AccordionContainer.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dijit / layout / AccordionContainer.js
1 if(!dojo._hasResource["dijit.layout.AccordionContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dijit.layout.AccordionContainer"] = true;
3 dojo.provide("dijit.layout.AccordionContainer");
4
5 dojo.require("dojo.fx");
6
7 dojo.require("dijit._Container");
8 dojo.require("dijit._Templated");
9 dojo.require("dijit.layout.StackContainer");
10 dojo.require("dijit.layout.ContentPane");
11
12 dojo.declare(
13         "dijit.layout.AccordionContainer",
14         dijit.layout.StackContainer,
15         {
16                 // summary:
17                 //              Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time,
18                 //              and switching between panes is visualized by sliding the other panes up/down.
19                 // example:
20                 // |    <div dojoType="dijit.layout.AccordionContainer">
21                 // |            <div dojoType="dijit.layout.AccordionPane" title="pane 1">
22                 // |                    <div dojoType="dijit.layout.ContentPane">...</div>
23                 // |    </div>
24                 // |            <div dojoType="dijit.layout.AccordionPane" title="pane 2">
25                 // |                    <p>This is some text</p>
26                 // ||           ...
27                 // |    </div>
28                 //
29                 // duration: Integer
30                 //              Amount of time (in ms) it takes to slide panes
31                 duration: 250,
32
33                 _verticalSpace: 0,
34
35                 postCreate: function(){
36                         this.domNode.style.overflow="hidden";
37                         this.inherited("postCreate",arguments); 
38                         dijit.setWaiRole(this.domNode, "tablist");
39                         dojo.addClass(this.domNode,"dijitAccordionContainer");
40                 },
41
42                 startup: function(){
43                         if(this._started){ return; }
44                         this.inherited("startup",arguments);    
45                         if(this.selectedChildWidget){
46                                 var style = this.selectedChildWidget.containerNode.style;
47                                 style.display = "";
48                                 style.overflow = "auto";
49                                 this.selectedChildWidget._setSelectedState(true);
50                         }
51                 },
52
53                 layout: function(){
54                         // summary: 
55                         //              Set the height of the open pane based on what room remains
56
57                         // get cumulative height of all the title bars, and figure out which pane is open
58                         var totalCollapsedHeight = 0;
59                         var openPane = this.selectedChildWidget;
60                         dojo.forEach(this.getChildren(), function(child){
61                                 totalCollapsedHeight += child.getTitleHeight();
62                         });
63                         var mySize = this._contentBox;
64                         this._verticalSpace = (mySize.h - totalCollapsedHeight);
65                         if(openPane){
66                                 openPane.containerNode.style.height = this._verticalSpace + "px";
67 /***
68 TODO: this is wrong.  probably you wanted to call resize on the SplitContainer
69 inside the AccordionPane??
70                                 if(openPane.resize){
71                                         openPane.resize({h: this._verticalSpace});
72                                 }
73 ***/
74                         }
75                 },
76
77                 _setupChild: function(/*Widget*/ page){
78                         // Summary: prepare the given child
79                         return page;
80                 },
81
82                 _transition: function(/*Widget?*/newWidget, /*Widget?*/oldWidget){
83 //TODO: should be able to replace this with calls to slideIn/slideOut
84                         if(this._inTransition){ return; }
85                         this._inTransition = true;
86                         var animations = [];
87                         var paneHeight = this._verticalSpace;
88                         if(newWidget){
89                                 newWidget.setSelected(true);
90                                 var newContents = newWidget.containerNode;
91                                 newContents.style.display = "";
92
93                                 animations.push(dojo.animateProperty({
94                                         node: newContents,
95                                         duration: this.duration,
96                                         properties: {
97                                                 height: { start: "1", end: paneHeight }
98                                         },
99                                         onEnd: function(){
100                                                 newContents.style.overflow = "auto";
101                                         }
102                                 }));
103                         }
104                         if(oldWidget){
105                                 oldWidget.setSelected(false);
106                                 var oldContents = oldWidget.containerNode;
107                                 oldContents.style.overflow = "hidden";
108                                 animations.push(dojo.animateProperty({
109                                         node: oldContents,
110                                         duration: this.duration,
111                                         properties: {
112                                                 height: { start: paneHeight, end: "1" }
113                                         },
114                                         onEnd: function(){
115                                                 oldContents.style.display = "none";
116                                         }
117                                 }));
118                         }
119
120                         this._inTransition = false;
121
122                         dojo.fx.combine(animations).play();
123                 },
124
125                 // note: we are treating the container as controller here
126                 _onKeyPress: function(/*Event*/ e){
127                         if(this.disabled || e.altKey || !(e._dijitWidget || e.ctrlKey)){ return; }
128                         var k = dojo.keys;
129                         var fromTitle = e._dijitWidget;
130                         switch(e.keyCode){
131                                 case k.LEFT_ARROW:
132                                 case k.UP_ARROW:
133                                         if (fromTitle){
134                                                 this._adjacent(false)._onTitleClick();
135                                                 dojo.stopEvent(e);
136                                         }
137                                         break;
138                                 case k.PAGE_UP:
139                                         if (e.ctrlKey){
140                                                 this._adjacent(false)._onTitleClick();
141                                                 dojo.stopEvent(e);
142                                         }
143                                         break;
144                                 case k.RIGHT_ARROW:
145                                 case k.DOWN_ARROW:
146                                         if (fromTitle){
147                                                 this._adjacent(true)._onTitleClick();
148                                                 dojo.stopEvent(e);
149                                         }
150                                         break;
151                                 case k.PAGE_DOWN:
152                                         if (e.ctrlKey){
153                                                 this._adjacent(true)._onTitleClick();
154                                                 dojo.stopEvent(e);
155                                         }
156                                         break;
157                                 default:
158                                         if(e.ctrlKey && e.keyCode == k.TAB){
159                                                 this._adjacent(e._dijitWidget, !e.shiftKey)._onTitleClick();
160                                                 dojo.stopEvent(e);
161                                         }
162                                 
163                         }
164                 }
165         }
166 );
167
168 dojo.declare("dijit.layout.AccordionPane",
169         [dijit.layout.ContentPane, dijit._Templated, dijit._Contained],
170         {
171         // summary:
172         //              AccordionPane is a ContentPane with a title that may contain another widget.
173         //              Nested layout widgets, such as SplitContainer, are not supported at this time.
174         // example: 
175         // | see dijit.layout.AccordionContainer
176
177         templateString:"<div class='dijitAccordionPane'\n\t><div dojoAttachPoint='titleNode,focusNode' dojoAttachEvent='ondijitclick:_onTitleClick,onkeypress:_onTitleKeyPress,onfocus:_handleFocus,onblur:_handleFocus'\n\t\tclass='dijitAccordionTitle' wairole=\"tab\"\n\t\t><div class='dijitAccordionArrow' waiRole=\"presentation\"></div\n\t\t><div class='arrowTextUp' waiRole=\"presentation\">&#9650;</div\n\t\t><div class='arrowTextDown' waiRole=\"presentation\">&#9660;</div\n\t\t><div waiRole=\"presentation\" dojoAttachPoint='titleTextNode' class='dijitAccordionText'>${title}</div></div\n\t><div><div dojoAttachPoint='containerNode' style='overflow: hidden; height: 1px; display: none'\n\t\tclass='dijitAccordionBody' wairole=\"tabpanel\"\n\t></div></div>\n</div>\n",
178
179         postCreate: function(){
180                 this.inherited("postCreate",arguments)
181                 dojo.setSelectable(this.titleNode, false);
182                 this.setSelected(this.selected);
183         },
184
185         getTitleHeight: function(){
186                 // summary: returns the height of the title dom node
187                 return dojo.marginBox(this.titleNode).h;        // Integer
188         },
189
190         _onTitleClick: function(){
191                 // summary: callback when someone clicks my title
192                 var parent = this.getParent();
193                 if(!parent._inTransition){
194                         parent.selectChild(this);
195                         dijit.focus(this.focusNode);
196                 }
197         },
198
199         _onTitleKeyPress: function(/*Event*/ evt){
200                 evt._dijitWidget = this;
201                 return this.getParent()._onKeyPress(evt);
202         },
203
204         _setSelectedState: function(/*Boolean*/ isSelected){
205                 this.selected = isSelected;
206                 dojo[(isSelected ? "addClass" : "removeClass")](this.titleNode,"dijitAccordionTitle-selected");
207                 this.focusNode.setAttribute("tabIndex", isSelected ? "0" : "-1");
208         },
209
210         _handleFocus: function(/*Event*/e){
211                 // summary: handle the blur and focus state of this widget
212                 dojo[(e.type=="focus" ? "addClass" : "removeClass")](this.focusNode,"dijitAccordionFocused");           
213         },
214
215         setSelected: function(/*Boolean*/ isSelected){
216                 // summary: change the selected state on this pane
217                 this._setSelectedState(isSelected);
218                 if(isSelected){
219                         this.onSelected();
220                         this._loadCheck(true); // if href specified, trigger load
221                 }
222         },
223
224         onSelected: function(){
225                 // summary: called when this pane is selected
226         }
227 });
228
229 }