Changeset 8423
- Timestamp:
- 05/04/07 09:40:19 (21 months ago)
- Location:
- dijit/trunk
- Files:
-
- 1 added
- 3 copied
-
layout/AccordionContainer.js (copied) (copied from trunk/src/widget/AccordionContainer.js) (9 diffs)
-
layout/templates (added)
-
layout/templates/AccordionPane.html (copied) (copied from trunk/src/widget/templates/AccordionPane.html) (1 diff)
-
tests/layout/test_AccordionContainer.html (copied) (copied from trunk/tests/widget/test_AccordionContainer.html) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
dijit/trunk/layout/AccordionContainer.js
r7821 r8423 1 dojo.provide("dojo.widget.AccordionContainer"); 2 3 dojo.require("dojo.widget.*"); 4 dojo.require("dojo.html.*"); 5 dojo.require("dojo.lfx.html"); 6 dojo.require("dojo.html.selection"); 7 dojo.require("dojo.widget.html.layout"); 8 dojo.require("dojo.widget.PageContainer"); 9 dojo.require("dojo.html.iframe"); 10 11 1 dojo.provide("dijit.layout.AccordionContainer"); 2 3 dojo.require("dojo.fx"); 4 dojo.require("dijit.base.Widget"); 5 dojo.require("dijit.base.Layout"); 6 dojo.require("dijit.base.Showable"); 7 dojo.require("dijit.layout.PageContainer"); 8 dojo.require("dijit.util.BackgroundIframe"); 9 dojo.require("dijit.base.TemplatedWidget"); 12 10 /** 13 11 * description … … 40 38 * 41 39 * usage 42 * <div dojoType=" AccordionContainer">43 * <div dojoType=" ContentPane" label="pane 1">...</div>40 * <div dojoType="dijit.layout.AccordionContainer"> 41 * <div dojoType="dijit.layout.ContentPane" label="pane 1">...</div> 44 42 * ... 45 43 * </div> … … 48 46 * * this widget should extend PageContainer 49 47 */ 50 dojo.widget.defineWidget( 51 "dojo.widget.AccordionContainer", 52 dojo.widget.HtmlWidget, 48 49 dojo.declare( 50 "dijit.layout.AccordionContainer", 51 [dijit.base.Widget, dijit.base.Layout, dijit.base.Showable], 53 52 { 53 54 54 // summary: 55 55 // Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time, 56 56 // and switching between panes is visualized by sliding the other panes up/down. 57 58 isContainer: true,59 57 60 58 // labelNodeClass: String … … 70 68 duration: 250, 71 69 72 fillInTemplate: function(){ 70 postCreate: function(){ 71 dijit.layout.AccordionContainer.superclass.postCreate.apply(this, arguments); 73 72 with(this.domNode.style){ 74 73 // position must be either relative or absolute … … 80 79 }, 81 80 82 addChild: function( /*Widget*/widget){81 addChild: function(widget){ 83 82 var child = this._addChild(widget); 84 83 this._setSizes(); … … 86 85 }, 87 86 88 _addChild: function( /*Widget*/widget){87 _addChild: function(widget){ 89 88 // summary 90 89 // Internal call to add child, used during postCreate() and by the real addChild() call 91 if (widget.widgetType != "AccordionPane") { 92 var wrapper=dojo.widget.createWidget("AccordionPane",{label: widget.label, selected: widget.selected, labelNodeClass: this.labelNodeClass, containerNodeClass: this.containerNodeClass, allowCollapse: this.allowCollapse }); 90 91 if(widget.declaredClass != "dijit.layout.AccordionPane"){ 92 // create a node that will be promoted to an accordionpane 93 var refNode = document.createElement("span"); 94 this.domNode.appendChild(refNode); 95 var wrapper = new dijit.layout.AccordionPane({label: widget.label, 96 selected: widget.selected, labelNodeClass: this.labelNodeClass, 97 containerNodeClass: this.containerNodeClass, allowCollapse: this.allowCollapse }, refNode); 93 98 wrapper.addChild(widget); 94 this.addWidgetAsDirectChild(wrapper); 95 this.registerChild(wrapper, this.children.length); 99 this.domNode.appendChild(wrapper.domNode); 96 100 return wrapper; // Widget 97 } else { 98 dojo.html.addClass(widget.containerNode, this.containerNodeClass); 99 dojo.html.addClass(widget.labelNode, this.labelNodeClass); 100 this.addWidgetAsDirectChild(widget); 101 this.registerChild(widget, this.children.length); 101 }else{ 102 dojo.addClass(widget.containerNode, this.containerNodeClass); 103 dojo.addClass(widget.labelNode, this.labelNodeClass); 104 dojo.place(widget.domNode, this.domNode, "last"); 102 105 return widget; // Widget 103 106 } 104 107 }, 105 106 postCreate: function() { 107 var tmpChildren = this.children; 108 this.children=[]; 109 dojo.html.removeChildren(this.domNode); 110 dojo.lang.forEach(tmpChildren, dojo.lang.hitch(this,"_addChild")); 111 this._setSizes(); 112 }, 113 114 removeChild: function(/*Widget*/ widget) { 115 dojo.widget.AccordionContainer.superclass.removeChild.call(this, widget); 108 109 layout: function(){ 110 var tmpChildren = this.getChildren(); 111 112 // PORT: move to utility class 113 var _removeChildren = function(node){ 114 var count = node.childNodes.length; 115 while(node.hasChildNodes()){ 116 node.removeChild(node.firstChild); 117 } 118 return count; // int 119 }; 120 _removeChildren(this.domNode); 121 dojo.forEach(tmpChildren, dojo.hitch(this,"_addChild")); 122 this._setSizes(); 123 }, 124 125 removeChild: function(widget){ 126 dijit.layout.AccordionContainer.superclass.removeChild.call(this, widget); 116 127 this._setSizes(); 117 128 }, … … 121 132 }, 122 133 123 _setSizes: function() {134 _setSizes: function(){ 124 135 // summary 125 136 // Set panes' size/position based on my size, and the current open node. … … 128 139 var totalCollapsedHeight = 0; 129 140 var openIdx = 0; 130 dojo. lang.forEach(this.children, function(child, idx){141 dojo.forEach(this.getChildren(), function(child, idx){ 131 142 totalCollapsedHeight += child.getLabelHeight(); 132 143 if(child.selected){ openIdx=idx; } 133 144 }); 134 135 145 // size and position each pane 136 var mySize =dojo.html.getContentBox(this.domNode);146 var mySize = dojo.contentBox(this.domNode); 137 147 var y = 0; 138 dojo. lang.forEach(this.children, function(child, idx){148 dojo.forEach(this.getChildren(), function(child, idx){ 139 149 var childCollapsedHeight = child.getLabelHeight(); 140 child.resizeTo(mySize.width, mySize.height-totalCollapsedHeight+childCollapsedHeight); 141 child.domNode.style.zIndex=idx+1; 142 child.domNode.style.position="absolute"; 143 child.domNode.style.top = y+"px"; 144 y += (idx==openIdx) ? dojo.html.getBorderBox(child.domNode).height : childCollapsedHeight; 150 child.resize({w: mySize.w, h: mySize.h -totalCollapsedHeight+childCollapsedHeight}); 151 var style = child.domNode.style; 152 style.zIndex=idx+1; 153 style.position="absolute"; 154 style.top = y+"px"; 155 // TODO: REVISIT: PORT: was getBorderBox, now is marginBox ? 156 y += (idx==openIdx) ? dojo.marginBox(child.domNode).h : childCollapsedHeight; 145 157 }); 146 158 }, 147 159 148 selectChild: function( /*Widget*/page){160 selectChild: function(page){ 149 161 // summary 150 162 // close the current page and select a new one 151 dojo.lang.forEach(this.children, function(child){child.setSelected(child==page);}); 152 163 dojo.forEach(this.getChildren(), function(child){child.setSelected(child==page);}); 153 164 // slide each pane that needs to be moved 154 165 var y = 0; 155 166 var anims = []; 156 dojo. lang.forEach(this.children, function(child, idx){167 dojo.forEach(this.getChildren(), function(child, idx){ 157 168 if(child.domNode.style.top != (y+"px")){ 158 anims.push(dojo.lfx.html.slideTo(child.domNode, {top: y, left: 0}, this.duration)); 159 } 160 y += child.selected ? dojo.html.getBorderBox(child.domNode).height : child.getLabelHeight(); 169 anims.push(dojo.fx.slideTo({node: child.domNode, 170 top: y, left: 0, duration: this.duration})); 171 } 172 // TODO: REVISIT: PORT: was getBorderBox, now is marginBox ? 173 y += child.selected ? dojo.marginBox(child.domNode).h : child.getLabelHeight(); 161 174 }, this); 162 dojo.lfx.combine(anims).play(); 163 }, 164 focusNextLabel: function(/*Widget*/ page){ 165 var bFound = false; 166 dojo.lang.forEach(this.children, function(child, idx){ 167 if(child==page){ 168 bFound = true; 169 child.setFocus(false); 170 }else{ 171 if(bFound){ 172 child.setFocus(true); 173 bFound = false; 174 } 175 } 176 }, this); 177 }, 178 179 focusPreviousLabel: function(/*Widget*/ page){ 180 var nPrevious = null; 181 dojo.lang.forEach(this.children, function(child, idx){ 182 if(child==page){ 183 child.setFocus(false); 184 if(nPrevious){ 185 nPrevious.setFocus(true); 186 } 187 } 188 nPrevious = child; 189 }, this); 190 } 191 } 192 ); 193 194 195 dojo.widget.defineWidget( 196 "dojo.widget.AccordionPane", 197 dojo.widget.HtmlWidget, 175 dojo.fx.combine(anims).play(); 176 } 177 } 178 ); 179 180 dojo.declare( 181 "dijit.layout.AccordionPane", 182 [dijit.base.Widget, dijit.base.TemplatedWidget, dijit.base.Showable, 183 dijit.base.Layout, dijit.base.Contained], 198 184 { 199 185 // summary … … 220 206 selected: false, 221 207 222 templatePath: dojo.uri.moduleUri("dojo.widget", "templates/AccordionPane.html"), 223 templateCssPath: dojo.uri.moduleUri("dojo.widget", "templates/AccordionPane.css"), 224 225 isContainer: true, 226 227 fillInTemplate: function() { 228 dojo.html.addClass(this.domNode, this["class"]); 229 dojo.widget.AccordionPane.superclass.fillInTemplate.call(this); 230 //dojo.html.disableSelection(this.labelNode); 208 templatePath: dojo.moduleUrl("dijit.layout", "templates/AccordionPane.html"), 209 210 postCreate: function(){ 211 dijit.layout.AccordionPane.superclass.postCreate.apply(this, arguments); 212 dojo.addClass(this.domNode, this["class"]); 213 dijit._disableSelection(this.labelNode); 231 214 this.setSelected(this.selected); 232 215 233 216 // Prevent IE bleed-through problem 234 this.bgIframe = new d ojo.html.BackgroundIframe(this.domNode);235 }, 236 237 setLabel: function(/*String*/ label) {217 this.bgIframe = new dijit.util.BackgroundIframe(this.domNode); 218 }, 219 220 setLabel: function(/*String*/ label){ 238 221 // summary: set the title of the node 239 222 this.labelNode.innerHTML=label; 240 223 }, 241 224 242 resizeTo: function(width, height){ 243 dojo.html.setMarginBox(this.domNode, {width: width, height: height}); 225 onResized: function(){ 244 226 var children = [ 245 227 {domNode: this.labelNode, layoutAlign: "top"}, 246 228 {domNode: this.containerNode, layoutAlign: "client"} 247 229 ]; 248 dojo.widget.html.layout(this.domNode, children); 249 var childSize = dojo.html.getContentBox(this.containerNode); 250 this.children[0].resizeTo(childSize.width, childSize.height); 251 }, 252 253 getLabelHeight: function() { 230 dijit.base.Layout.layoutChildren(this.domNode, children); 231 var childSize = dojo.contentBox(this.containerNode); 232 var child = this.getChildren()[0]; 233 if(child && child.resize){ 234 child.resize(childSize); 235 } 236 }, 237 238 getLabelHeight: function(){ 254 239 // summary: returns the height of the title dom node 255 return dojo. html.getMarginBox(this.labelNode).height; // Integer256 }, 257 258 onLabelClick: function() {240 return dojo.marginBox(this.labelNode).h; // Integer 241 }, 242 243 onLabelClick: function(){ 259 244 // summary: callback when someone clicks my label 260 this.parent.selectChild(this); 261 }, 262 onLabelKey: function(/*Event*/ e) { 263 // summary: callback when someone presses a key while focus is on my label 264 var k = dojo.event.browser.keys; 265 switch(e.key){ 266 case " ": 267 this.onLabelClick(); 268 dojo.event.browser.stopEvent(e); 269 return; 270 case k.KEY_LEFT_ARROW: 271 this.parent.focusPreviousLabel(this); 272 dojo.event.browser.stopEvent(e); 273 return; 274 case k.KEY_RIGHT_ARROW: 275 this.parent.focusNextLabel(this); 276 dojo.event.browser.stopEvent(e); 277 return; 278 } 279 }, 280 281 onFocus: function(/*Event*/ e){dojo.debug((this["class"]+"-focused")); 282 dojo.html.addClass(this.domNode, this["class"]+"-focused"); 283 this.onLabelClick(); 284 }, 285 286 onBlur: function(/*Event*/ e){ 287 dojo.html.removeClass(this.domNode, this["class"]+"-focused"); 288 289 }, 290 291 setFocus: function(/*Boolean*/ isFocused){ 292 if(isFocused){ 293 this.labelNode.focus(); 294 } 295 }, 296 245 this.getParent().selectChild(this); 246 }, 297 247 298 248 setSelected: function(/*Boolean*/ isSelected){ 299 249 this.selected=isSelected; 300 (isSelected ? dojo. html.addClass : dojo.html.removeClass)(this.domNode, this["class"]+"-selected");301 this.labelNode.tabIndex = isSelected ? 0 : -1; 250 (isSelected ? dojo.addClass : dojo.removeClass)(this.domNode, this["class"]+"-selected"); 251 302 252 // make sure child is showing (lazy load), and also that onShow()/onHide() is called 303 var child = this. children[0];253 var child = this.getChildren()[0]; 304 254 if(child){ 305 255 if(isSelected){ 306 if(!child.isShowing()){ 256 if(child.isShowing()){ 257 child.onShow(); 258 }else{ 307 259 child.show(); 308 }else{309 child.onShow();310 260 } 311 261 }else{ 262 // #1969 - Firefox has a display glitch, force child to hide 263 // only the titlepane will get the slide animation 264 if(child.isShowing()){ 265 child.hide(); 266 } 312 267 child.onHide(); 313 268 } -
dijit/trunk/layout/templates/AccordionPane.html
r7821 r8423 1 <div dojoAttachPoint="domNode" waiRole="tabcontainer">2 <div dojoAttachPoint="labelNode" dojoAttachEvent="onclick: onLabelClick ; onkey: onLabelKey; onFocus; onBlur;" tabindex="0" waiRole="tab" class="${this.labelNodeClass}">${this.label}</div>3 <div dojoAttachPoint="containerNode" style="overflow: hidden;" class="${this.containerNodeClass}" waiRole="tabpanel"></div>1 <div dojoAttachPoint="domNode"> 2 <div dojoAttachPoint="labelNode" dojoAttachEvent="onclick: onLabelClick" class="${this.labelNodeClass}">${this.label}</div> 3 <div dojoAttachPoint="containerNode" style="overflow: hidden;" class="${this.containerNodeClass}"></div> 4 4 </div> -
dijit/trunk/tests/layout/test_AccordionContainer.html
r7388 r8423 5 5 6 6 <title>Accordion Widget Demo</title> 7 7 <style> 8 @import "../../../dojo/resources/dojo.css"; 9 @import "../../themes/tundra/tundra.css"; 10 @import "css/dijitTests.css"; 11 </style> 8 12 <script type="text/javascript"> 9 13 var djConfig = {isDebug: true }; 10 14 </script> 11 <script type="text/javascript" src="../../ dojo.js"></script>15 <script type="text/javascript" src="../../../dojo/dojo.js"></script> 12 16 <script type="text/javascript"> 13 dojo.require("dojo.widget.*"); 14 dojo.require("dojo.widget.AccordionContainer"); 15 dojo.require("dojo.widget.ContentPane"); 16 dojo.require("dojo.widget.TreeV3"); 17 dojo.require("dojo.widget.TreeBasicControllerV3"); 18 dojo.require("dojo.widget.SplitContainer"); 17 dojo.require("dijit.layout.AccordionContainer"); 18 dojo.require("dijit.layout.ContentPane"); 19 // dojo.require("dojo.widget.TreeV3"); 20 // dojo.require("dojo.widget.TreeBasicControllerV3"); 21 dojo.require("dijit.layout.SplitContainer"); 22 // dojo.require("dijit.form.ComboBox"); 23 dojo.require("dijit.form.Button"); 24 dojo.require("dijit.util.parser"); // scan page for widgets and instantiate them 19 25 </script> 20 26 … … 23 29 var accordion; 24 30 25 function init() { 26 accordion = dojo.widget.createWidget("AccordionContainer", null, 27 dojo.byId("accordionShell")); 31 function init(){ 32 accordion = new dijit.layout.AccordionContainer({}, dojo.byId("accordionShell")); 28 33 var label=["pane 1", "pane 2", "pane 3"]; 29 for(i=0; i<label.length; ++i) { 30 var content = dojo.widget.createWidget("ContentPane", {label: label[i], selected: i==1}); 34 for(i=0; i<label.length; ++i){ 35 // add a node that will be promoted to the content widget 36 var refNode = document.createElement("span"); 37 document.body.appendChild(refNode); 38 var content = new dijit.layout.ContentPane({label: label[i], selected: i==1}, refNode); 31 39 content.setContent("this is " + label[i]); 32 dojo.debug("adding content pane " + content.widgetId);40 console.debug("adding content pane " + content.widgetId); 33 41 accordion.addChild(content); 34 42 } 43 accordion.layout(); 35 44 accordion.onResized(); 36 45 } … … 38 47 39 48 function destroyChildren(){ 40 accordion.destroy Children();49 accordion.destroyDescendants(); 41 50 } 42 51 </script> … … 49 58 <p>HTML before</p> 50 59 51 <div dojoType=" AccordionContainer" duration="200" labelNodeClass="label" containerNodeClass="accBody"60 <div dojoType="dijit.layout.AccordionContainer" duration="200" labelNodeClass="label" containerNodeClass="accBody" 52 61 style="float: left; margin-right: 30px; width: 400px; height: 300px; overflow: hidden" 53 62 > 54 <div dojoType="ContentPane" selected="true" label="Pane 1 (tree, select box)" style="overflow: scroll;"55 onShow="dojo.debug('pane 1 shown');" onHide="dojo.debug('pane 1 hidden');" >63 <div dojoType="dijit.layout.ContentPane" selected="true" label="Pane 1 (tree, select box)" style="overflow: scroll;" 64 onShow="console.debug('pane 1 shown');" onHide="console.debug('pane 1 hidden');" > 56 65 57 <divdojoType="TreeBasicControllerV3" widgetId="controller"></div>66 <div zdojoType="TreeBasicControllerV3" widgetId="controller"></div> 58 67 59 <divdojoType="TreeV3" listeners="controller" toggle="fade">60 <divdojoType="TreeNodeV3" title="Item 1">61 <divdojoType="TreeNodeV3" title="Item 1.1"><br/></div>62 <divdojoType="TreeNodeV3" title="Item 1.2">63 <divdojoType="TreeNodeV3" title="Item 1.2.1"></div>64 <divdojoType="TreeNodeV3" title="Item 1.2.2"></div>65 </div>66 <divdojoType="TreeNodeV3" title="Item 1.3">67 <divdojoType="TreeNodeV3" title="Item 1.3.1"></div>68 <divdojoType="TreeNodeV3" title="Item 1.3.2"></div>69 </div>70 <divdojoType="TreeNodeV3" title="Item 1.4">71 <divdojoType="TreeNodeV3" title="Item 1.4.1"></div>72 </div>73 </div>74 </div>68 <div zdojoType="TreeV3" listeners="controller" toggle="fade"> 69 <div zdojoType="TreeNodeV3" title="Item 1"> 70 <div zdojoType="TreeNodeV3" title="Item 1.1"><br/></div> 71 <div zdojoType="TreeNodeV3" title="Item 1.2"> 72 <div zdojoType="TreeNodeV3" title="Item 1.2.1"></div> 73 <div zdojoType="TreeNodeV3" title="Item 1.2.2"></div> 74 </div> 75 <div zdojoType="TreeNodeV3" title="Item 1.3"> 76 <div zdojoType="TreeNodeV3" title="Item 1.3.1"></div> 77 <div zdojoType="TreeNodeV3" title="Item 1.3.2"></div> 78 </div> 79 <div zdojoType="TreeNodeV3" title="Item 1.4"> 80 <div zdojoType="TreeNodeV3" title="Item 1.4.1"></div> 81 </div> 82 </div> 83 </div> 75 84 76 85 <br> … … 81 90 </select> 82 91 83 <p>84 Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin85 suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.86 Nulla facilisi. Cras venenatis urna et magna. Aenean magna mauris,87 bibendum sit amet, semper quis, aliquet nec, sapien. Aliquam88 aliquam odio quis erat. Etiam est nisi, condimentum non, lacinia89 ac, vehicula laoreet, elit. Sed interdum augue sit amet quam90 dapibus semper. Nulla facilisi. Pellentesque lobortis erat nec91 quam.92 </p>93 <p>94 Sed arcu magna, molestie at, fringilla in, sodales eu, elit.95