source: Dev/branches/rest-dojo-ui/client/dijit/TitlePane.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 8.0 KB
Line 
1define([
2        "dojo/_base/array", // array.forEach
3        "dojo/_base/declare", // declare
4        "dojo/dom", // dom.setSelectable
5        "dojo/dom-attr", // domAttr.set or get domAttr.remove
6        "dojo/dom-class", // domClass.replace
7        "dojo/dom-geometry", // domGeometry.setMarginBox domGeometry.getMarginBox
8        "dojo/_base/event", // event.stop
9        "dojo/fx", // fxUtils.wipeIn fxUtils.wipeOut
10        "dojo/_base/kernel", // kernel.deprecated
11        "dojo/keys", // keys.DOWN_ARROW keys.ENTER
12        "./_CssStateMixin",
13        "./_TemplatedMixin",
14        "./layout/ContentPane",
15        "dojo/text!./templates/TitlePane.html",
16        "./_base/manager"       // defaultDuration
17], function(array, declare, dom, domAttr, domClass, domGeometry, event, fxUtils, kernel, keys,
18                        _CssStateMixin, _TemplatedMixin, ContentPane, template, manager){
19
20/*=====
21        var _Widget = dijit._Widget;
22        var _TemplatedMixin = dijit._TemplatedMixin;
23        var _CssStateMixin = dijit._CssStateMixin;
24        var ContentPane = dijit.layout.ContentPane;
25=====*/
26
27// module:
28//              dijit/TitlePane
29// summary:
30//              A pane with a title on top, that can be expanded or collapsed.
31
32
33return declare("dijit.TitlePane", [ContentPane, _TemplatedMixin, _CssStateMixin], {
34        // summary:
35        //              A pane with a title on top, that can be expanded or collapsed.
36        //
37        // description:
38        //              An accessible container with a title Heading, and a content
39        //              section that slides open and closed. TitlePane is an extension to
40        //              `dijit.layout.ContentPane`, providing all the useful content-control aspects from it.
41        //
42        // example:
43        // |    // load a TitlePane from remote file:
44        // |    var foo = new dijit.TitlePane({ href: "foobar.html", title:"Title" });
45        // |    foo.startup();
46        //
47        // example:
48        // |    <!-- markup href example: -->
49        // |    <div data-dojo-type="dijit.TitlePane" data-dojo-props="href: 'foobar.html', title: 'Title'"></div>
50        //
51        // example:
52        // |    <!-- markup with inline data -->
53        // |    <div data-dojo-type="dijit.TitlePane" title="Title">
54        // |            <p>I am content</p>
55        // |    </div>
56
57        // title: String
58        //              Title of the pane
59        title: "",
60        _setTitleAttr: { node: "titleNode", type: "innerHTML" },        // override default where title becomes a hover tooltip
61
62        // open: Boolean
63        //              Whether pane is opened or closed.
64        open: true,
65
66        // toggleable: Boolean
67        //              Whether pane can be opened or closed by clicking the title bar.
68        toggleable: true,
69
70        // tabIndex: String
71        //              Tabindex setting for the title (so users can tab to the title then
72        //              use space/enter to open/close the title pane)
73        tabIndex: "0",
74
75        // duration: Integer
76        //              Time in milliseconds to fade in/fade out
77        duration: manager.defaultDuration,
78
79        // baseClass: [protected] String
80        //              The root className to be placed on this widget's domNode.
81        baseClass: "dijitTitlePane",
82
83        templateString: template,
84
85        // doLayout: [protected] Boolean
86        //              Don't change this parameter from the default value.
87        //              This ContentPane parameter doesn't make sense for TitlePane, since TitlePane
88        //              is never a child of a layout container, nor should TitlePane try to control
89        //              the size of an inner widget.
90        doLayout: false,
91
92        // Tooltip is defined in _WidgetBase but we need to handle the mapping to DOM here
93        _setTooltipAttr: {node: "focusNode", type: "attribute", attribute: "title"},    // focusNode spans the entire width, titleNode doesn't
94
95        buildRendering: function(){
96                this.inherited(arguments);
97                dom.setSelectable(this.titleNode, false);
98        },
99
100        postCreate: function(){
101                this.inherited(arguments);
102
103                // Hover and focus effect on title bar, except for non-toggleable TitlePanes
104                // This should really be controlled from _setToggleableAttr() but _CssStateMixin
105                // doesn't provide a way to disconnect a previous _trackMouseState() call
106                if(this.toggleable){
107                        this._trackMouseState(this.titleBarNode, "dijitTitlePaneTitle");
108                }
109
110                // setup open/close animations
111                var hideNode = this.hideNode, wipeNode = this.wipeNode;
112                this._wipeIn = fxUtils.wipeIn({
113                        node: wipeNode,
114                        duration: this.duration,
115                        beforeBegin: function(){
116                                hideNode.style.display="";
117                        }
118                });
119                this._wipeOut = fxUtils.wipeOut({
120                        node: wipeNode,
121                        duration: this.duration,
122                        onEnd: function(){
123                                hideNode.style.display="none";
124                        }
125                });
126        },
127
128        _setOpenAttr: function(/*Boolean*/ open, /*Boolean*/ animate){
129                // summary:
130                //              Hook to make set("open", boolean) control the open/closed state of the pane.
131                // open: Boolean
132                //              True if you want to open the pane, false if you want to close it.
133
134                array.forEach([this._wipeIn, this._wipeOut], function(animation){
135                        if(animation && animation.status() == "playing"){
136                                animation.stop();
137                        }
138                });
139
140                if(animate){
141                        var anim = this[open ? "_wipeIn" : "_wipeOut"];
142                        anim.play();
143                }else{
144                        this.hideNode.style.display = this.wipeNode.style.display = open ? "" : "none";
145                }
146
147                // load content (if this is the first time we are opening the TitlePane
148                // and content is specified as an href, or href was set when hidden)
149                if(this._started){
150                        if(open){
151                                this._onShow();
152                        }else{
153                                this.onHide();
154                        }
155                }
156
157                this.arrowNodeInner.innerHTML = open ? "-" : "+";
158
159                this.containerNode.setAttribute("aria-hidden", open ? "false" : "true");
160                this.focusNode.setAttribute("aria-pressed", open ? "true" : "false");
161
162                this._set("open", open);
163
164                this._setCss();
165        },
166
167        _setToggleableAttr: function(/*Boolean*/ canToggle){
168                // summary:
169                //              Hook to make set("toggleable", boolean) work.
170                // canToggle: Boolean
171                //              True to allow user to open/close pane by clicking title bar.
172
173                this.focusNode.setAttribute("role", canToggle ? "button" : "heading");
174                if(canToggle){
175                        // TODO: if canToggle is switched from true to false shouldn't we remove this setting?
176                        this.focusNode.setAttribute("aria-controls", this.id+"_pane");
177                        domAttr.set(this.focusNode, "tabIndex", this.tabIndex);
178                }else{
179                        domAttr.remove(this.focusNode, "tabIndex");
180                }
181
182                this._set("toggleable", canToggle);
183
184                this._setCss();
185        },
186
187        _setContentAttr: function(/*String|DomNode|Nodelist*/ content){
188                // summary:
189                //              Hook to make set("content", ...) work.
190                //              Typically called when an href is loaded.  Our job is to make the animation smooth.
191
192                if(!this.open || !this._wipeOut || this._wipeOut.status() == "playing"){
193                        // we are currently *closing* the pane (or the pane is closed), so just let that continue
194                        this.inherited(arguments);
195                }else{
196                        if(this._wipeIn && this._wipeIn.status() == "playing"){
197                                this._wipeIn.stop();
198                        }
199
200                        // freeze container at current height so that adding new content doesn't make it jump
201                        domGeometry.setMarginBox(this.wipeNode, { h: domGeometry.getMarginBox(this.wipeNode).h });
202
203                        // add the new content (erasing the old content, if any)
204                        this.inherited(arguments);
205
206                        // call _wipeIn.play() to animate from current height to new height
207                        if(this._wipeIn){
208                                this._wipeIn.play();
209                        }else{
210                                this.hideNode.style.display = "";
211                        }
212                }
213        },
214
215        toggle: function(){
216                // summary:
217                //              Switches between opened and closed state
218                // tags:
219                //              private
220
221                this._setOpenAttr(!this.open, true);
222        },
223
224        _setCss: function(){
225                // summary:
226                //              Set the open/close css state for the TitlePane
227                // tags:
228                //              private
229
230                var node = this.titleBarNode || this.focusNode;
231                var oldCls = this._titleBarClass;
232                this._titleBarClass = "dijit" + (this.toggleable ? "" : "Fixed") + (this.open ? "Open" : "Closed");
233                domClass.replace(node, this._titleBarClass, oldCls || "");
234
235                this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
236        },
237
238        _onTitleKey: function(/*Event*/ e){
239                // summary:
240                //              Handler for when user hits a key
241                // tags:
242                //              private
243
244                if(e.charOrCode == keys.ENTER || e.charOrCode == ' '){
245                        if(this.toggleable){
246                                this.toggle();
247                        }
248                        event.stop(e);
249                }else if(e.charOrCode == keys.DOWN_ARROW && this.open){
250                        this.containerNode.focus();
251                        e.preventDefault();
252                }
253        },
254
255        _onTitleClick: function(){
256                // summary:
257                //              Handler when user clicks the title bar
258                // tags:
259                //              private
260                if(this.toggleable){
261                        this.toggle();
262                }
263        },
264
265        setTitle: function(/*String*/ title){
266                // summary:
267                //              Deprecated.  Use set('title', ...) instead.
268                // tags:
269                //              deprecated
270                kernel.deprecated("dijit.TitlePane.setTitle() is deprecated.  Use set('title', ...) instead.", "", "2.0");
271                this.set("title", title);
272        }
273});
274
275});
Note: See TracBrowser for help on using the repository browser.