TitlePane.js 9.1 KB

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