diff options
Diffstat (limited to 'includes/js/dijit/layout/AccordionContainer.js')
-rw-r--r-- | includes/js/dijit/layout/AccordionContainer.js | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/includes/js/dijit/layout/AccordionContainer.js b/includes/js/dijit/layout/AccordionContainer.js new file mode 100644 index 0000000..12f8945 --- /dev/null +++ b/includes/js/dijit/layout/AccordionContainer.js @@ -0,0 +1,229 @@ +if(!dojo._hasResource["dijit.layout.AccordionContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.layout.AccordionContainer"] = true; +dojo.provide("dijit.layout.AccordionContainer"); + +dojo.require("dojo.fx"); + +dojo.require("dijit._Container"); +dojo.require("dijit._Templated"); +dojo.require("dijit.layout.StackContainer"); +dojo.require("dijit.layout.ContentPane"); + +dojo.declare( + "dijit.layout.AccordionContainer", + dijit.layout.StackContainer, + { + // summary: + // Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time, + // and switching between panes is visualized by sliding the other panes up/down. + // example: + // | <div dojoType="dijit.layout.AccordionContainer"> + // | <div dojoType="dijit.layout.AccordionPane" title="pane 1"> + // | <div dojoType="dijit.layout.ContentPane">...</div> + // | </div> + // | <div dojoType="dijit.layout.AccordionPane" title="pane 2"> + // | <p>This is some text</p> + // || ... + // | </div> + // + // duration: Integer + // Amount of time (in ms) it takes to slide panes + duration: 250, + + _verticalSpace: 0, + + postCreate: function(){ + this.domNode.style.overflow="hidden"; + this.inherited("postCreate",arguments); + dijit.setWaiRole(this.domNode, "tablist"); + dojo.addClass(this.domNode,"dijitAccordionContainer"); + }, + + startup: function(){ + if(this._started){ return; } + this.inherited("startup",arguments); + if(this.selectedChildWidget){ + var style = this.selectedChildWidget.containerNode.style; + style.display = ""; + style.overflow = "auto"; + this.selectedChildWidget._setSelectedState(true); + } + }, + + layout: function(){ + // summary: + // Set the height of the open pane based on what room remains + + // get cumulative height of all the title bars, and figure out which pane is open + var totalCollapsedHeight = 0; + var openPane = this.selectedChildWidget; + dojo.forEach(this.getChildren(), function(child){ + totalCollapsedHeight += child.getTitleHeight(); + }); + var mySize = this._contentBox; + this._verticalSpace = (mySize.h - totalCollapsedHeight); + if(openPane){ + openPane.containerNode.style.height = this._verticalSpace + "px"; +/*** +TODO: this is wrong. probably you wanted to call resize on the SplitContainer +inside the AccordionPane?? + if(openPane.resize){ + openPane.resize({h: this._verticalSpace}); + } +***/ + } + }, + + _setupChild: function(/*Widget*/ page){ + // Summary: prepare the given child + return page; + }, + + _transition: function(/*Widget?*/newWidget, /*Widget?*/oldWidget){ +//TODO: should be able to replace this with calls to slideIn/slideOut + if(this._inTransition){ return; } + this._inTransition = true; + var animations = []; + var paneHeight = this._verticalSpace; + if(newWidget){ + newWidget.setSelected(true); + var newContents = newWidget.containerNode; + newContents.style.display = ""; + + animations.push(dojo.animateProperty({ + node: newContents, + duration: this.duration, + properties: { + height: { start: "1", end: paneHeight } + }, + onEnd: function(){ + newContents.style.overflow = "auto"; + } + })); + } + if(oldWidget){ + oldWidget.setSelected(false); + var oldContents = oldWidget.containerNode; + oldContents.style.overflow = "hidden"; + animations.push(dojo.animateProperty({ + node: oldContents, + duration: this.duration, + properties: { + height: { start: paneHeight, end: "1" } + }, + onEnd: function(){ + oldContents.style.display = "none"; + } + })); + } + + this._inTransition = false; + + dojo.fx.combine(animations).play(); + }, + + // note: we are treating the container as controller here + _onKeyPress: function(/*Event*/ e){ + if(this.disabled || e.altKey || !(e._dijitWidget || e.ctrlKey)){ return; } + var k = dojo.keys; + var fromTitle = e._dijitWidget; + switch(e.keyCode){ + case k.LEFT_ARROW: + case k.UP_ARROW: + if (fromTitle){ + this._adjacent(false)._onTitleClick(); + dojo.stopEvent(e); + } + break; + case k.PAGE_UP: + if (e.ctrlKey){ + this._adjacent(false)._onTitleClick(); + dojo.stopEvent(e); + } + break; + case k.RIGHT_ARROW: + case k.DOWN_ARROW: + if (fromTitle){ + this._adjacent(true)._onTitleClick(); + dojo.stopEvent(e); + } + break; + case k.PAGE_DOWN: + if (e.ctrlKey){ + this._adjacent(true)._onTitleClick(); + dojo.stopEvent(e); + } + break; + default: + if(e.ctrlKey && e.keyCode == k.TAB){ + this._adjacent(e._dijitWidget, !e.shiftKey)._onTitleClick(); + dojo.stopEvent(e); + } + + } + } + } +); + +dojo.declare("dijit.layout.AccordionPane", + [dijit.layout.ContentPane, dijit._Templated, dijit._Contained], + { + // summary: + // AccordionPane is a ContentPane with a title that may contain another widget. + // Nested layout widgets, such as SplitContainer, are not supported at this time. + // example: + // | see dijit.layout.AccordionContainer + + 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\">▲</div\n\t\t><div class='arrowTextDown' waiRole=\"presentation\">▼</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", + + postCreate: function(){ + this.inherited("postCreate",arguments) + dojo.setSelectable(this.titleNode, false); + this.setSelected(this.selected); + }, + + getTitleHeight: function(){ + // summary: returns the height of the title dom node + return dojo.marginBox(this.titleNode).h; // Integer + }, + + _onTitleClick: function(){ + // summary: callback when someone clicks my title + var parent = this.getParent(); + if(!parent._inTransition){ + parent.selectChild(this); + dijit.focus(this.focusNode); + } + }, + + _onTitleKeyPress: function(/*Event*/ evt){ + evt._dijitWidget = this; + return this.getParent()._onKeyPress(evt); + }, + + _setSelectedState: function(/*Boolean*/ isSelected){ + this.selected = isSelected; + dojo[(isSelected ? "addClass" : "removeClass")](this.titleNode,"dijitAccordionTitle-selected"); + this.focusNode.setAttribute("tabIndex", isSelected ? "0" : "-1"); + }, + + _handleFocus: function(/*Event*/e){ + // summary: handle the blur and focus state of this widget + dojo[(e.type=="focus" ? "addClass" : "removeClass")](this.focusNode,"dijitAccordionFocused"); + }, + + setSelected: function(/*Boolean*/ isSelected){ + // summary: change the selected state on this pane + this._setSelectedState(isSelected); + if(isSelected){ + this.onSelected(); + this._loadCheck(true); // if href specified, trigger load + } + }, + + onSelected: function(){ + // summary: called when this pane is selected + } +}); + +} |