if(!dojo._hasResource["dojox.layout.RadioGroup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dojox.layout.RadioGroup"] = true; dojo.provide("dojox.layout.RadioGroup"); dojo.experimental("dojox.layout.RadioGroup"); // // dojox.layout.RadioGroup - an experimental (probably poorly named) Layout widget extending StackContainer // that accepts ContentPanes as children, and applies aesthetically pleasing responsive transition animations // attached to :hover of the Buttons created. // // FIXME: take the Buttons out of the root template, and allow layoutAlign or similar attrib to use a different // template, or build the template dynamically? // dojo.require("dijit._Widget"); dojo.require("dijit._Templated"); dojo.require("dijit._Container"); dojo.require("dijit.layout.StackContainer"); dojo.require("dojox.fx.easing"); dojo.declare("dojox.layout.RadioGroup", [dijit.layout.StackContainer,dijit._Templated], { // summary: A Container that turns its Layout Children into a single Pane and transitions between states // onHover of the button // // duration: Int // used for Fade and Slide RadioGroup's, the duration to run the transition animation. does not affect anything // in default RadioGroup duration: 750, // hasButtons: Boolean // toggles internal button making on or off hasButtons: true, // templateString: String // the template for our container templateString: '
' +'
' +'
' +'
' +'
' +'
', startup: function(){ // summary: scan the container for children, and make "tab buttons" for them this.inherited("startup",arguments); this._children = this.getChildren(); this._buttons = this._children.length; this._size = dojo.coords(this.containerNode); if(this.hasButtons){ dojo.style(this.buttonHolder,"display","block"); dojo.forEach(this._children,this._makeButton,this); } }, // private: _makeButton: function(/* DomNode */n){ // summary: creates a hover button for a child node of the RadioGroup dojo.style(n.domNode,"position","absolute"); var tmp = document.createElement('td'); this.buttonNode.appendChild(tmp); var tmpt = tmp.appendChild(document.createElement('div')); var tmpw = new dojox.layout._RadioButton({ label: n.title, page: n },tmpt); tmpw.startup(); }, // FIXME: shouldn't have to rewriting these, need to take styling out of _showChild and _hideChild // and use classes on the domNode in _transition or something similar (in StackContainer) _transition: function(/*Widget*/newWidget, /*Widget*/oldWidget){ // summary: called when StackContainer receives a selectChild call, used to transition the panes. this._showChild(newWidget); if(oldWidget){ this._hideChild(oldWidget); } // Size the new widget, in case this is the first time it's being shown, // or I have been resized since the last time it was shown. // page must be visible for resizing to work if(this.doLayout && newWidget.resize){ newWidget.resize(this._containerContentBox || this._contentBox); } }, _showChild: function(/*Widget*/ page){ // summary: show the selected child widget var children = this.getChildren(); page.isFirstChild = (page == children[0]); page.isLastChild = (page == children[children.length-1]); page.selected = true; page.domNode.style.display=""; if(page._loadCheck){ page._loadCheck(); // trigger load in ContentPane } if(page.onShow){ page.onShow(); } }, _hideChild: function(/*Widget*/ page){ // summary: hide the specified child widget page.selected=false; page.domNode.style.display="none"; if(page.onHide){ page.onHide(); } } }); dojo.declare("dojox.layout.RadioGroupFade", dojox.layout.RadioGroup, { // summary: An extension on a stock RadioGroup, that fades the panes. _hideChild: function(page){ // summary: hide the specified child widget dojo.fadeOut({ node:page.domNode, duration:this.duration, onEnd: this.inherited("_hideChild",arguments) }).play(); }, _showChild: function(page){ // summary: show the specified child widget this.inherited("_showChild",arguments); dojo.style(page.domNode,"opacity",0); dojo.fadeIn({ node:page.domNode, duration:this.duration }).play(); } }); dojo.declare("dojox.layout.RadioGroupSlide", dojox.layout.RadioGroup, { // summary: A Sliding Radio Group // description: // An extension on a stock RadioGroup widget, sliding the pane // into view from being hidden. The entry direction is randomized // on each view // // easing: dojo._Animation.easing // A hook to override the default easing of the pane slides. easing: dojox.fx.easing.easeOut, startup: function(){ // summary: on startup, set each of the panes off-screen (_showChild is called later) this.inherited("startup",arguments); dojo.forEach(this._children,this._positionChild,this); }, _positionChild: function(page){ // summary: randomly set the child out of view // description: var rA = Math.round(Math.random()); var rB = Math.round(Math.random()); dojo.style(page.domNode, rA? "top" : "left", (rB ? "-" : "") + this._size[rA?"h":"w"]+"px"); }, _showChild: function(page){ // summary: Slide in the selected child widget this.inherited("_showChild",arguments); if(this._anim && this._anim.status()=="playing"){ this._anim.gotoPercent(100,true); } this._anim = dojo.animateProperty({ node:page.domNode, properties: { // take a performance hit determinging one of these doesn't get modified // but it's better this way than an extra call to mixin in think? left: { end:0, unit:"px" }, top: { end:0, unit:"px" } }, duration:this.duration, easing:this.easing }); this._anim.play(); }, _hideChild: function(page){ // summary: reset the position of the hidden pane out of sight this.inherited("_hideChild",arguments); this._positionChild(page); } }); dojo.declare("dojox.layout._RadioButton", [dijit._Widget,dijit._Templated,dijit._Contained], { // summary: The Buttons for a RadioGroup // // description: A private widget used to manipulate the StackContainer (RadioGroup*). Don't create directly. // // label: String // the Text Label of the button label: "", // domNode to tell parent to select page: null, templateString: '
${label}
', startup: function(){ // summary: start listening to mouseOver this.connect(this.domNode,"onmouseover","_onMouse"); }, _onMouse: function(/* Event */e){ // summary: set the selected child on hover, and set our hover state class this.getParent().selectChild(this.page); this._clearSelected(); dojo.addClass(this.domNode,"dojoxRadioButtonSelected"); }, _clearSelected: function(){ // summary: remove hover state class from sibling Buttons. This is easier (and more reliable) // than setting up an additional connection to onMouseOut // FIXME: this relies on the template being [div][span]node[/span][/div] dojo.query(".dojoxRadioButtonSelected",this.domNode.parentNode.parentNode).forEach(function(n){ dojo.removeClass(n,"dojoxRadioButtonSelected"); }); } }); }