/public/javascripts/dojo/release/dojo/dijit/layout/AccordionContainer.js
http://enginey.googlecode.com/ · JavaScript · 265 lines · 184 code · 32 blank · 49 comment · 19 complexity · 9aa52551eff13a9fb9a86c15be5d2f81 MD5 · raw file
- /*
- Copyright (c) 2004-2008, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
- */
-
-
- 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: dijit.defaultDuration,
-
- _verticalSpace: 0,
-
- baseClass: "dijitAccordionContainer",
-
- postCreate: function(){
- this.domNode.style.overflow = "hidden";
- this.inherited(arguments);
- dijit.setWaiRole(this.domNode, "tablist");
- },
-
- startup: function(){
- if(this._started){ return; }
- this.inherited(arguments);
- if(this.selectedChildWidget){
- var style = this.selectedChildWidget.containerNode.style;
- style.display = "";
- style.overflow = "auto";
- this.selectedChildWidget._setSelectedState(true);
- }
- },
-
- _getTargetHeight: function(/* Node */ node){
- // summary:
- // For the given node, returns the height that should be
- // set to achieve our vertical space (subtract any padding
- // we may have)
- var cs = dojo.getComputedStyle(node);
- return Math.max(this._verticalSpace - dojo._getPadBorderExtents(node, cs).h, 0);
- },
-
- 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._getTargetHeight(openPane.containerNode) + "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 = "";
- paneHeight = this._getTargetHeight(newWidget.containerNode)
- 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";
- paneHeight = this._getTargetHeight(oldWidget.containerNode);
- 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.charOrCode){
- 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.charOrCode === 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 waiRole=\"presentation\"\r\n\t><div dojoAttachPoint='titleNode,focusNode' dojoAttachEvent='ondijitclick:_onTitleClick,onkeypress:_onTitleKeyPress,onfocus:_handleFocus,onblur:_handleFocus,onmouseenter:_onTitleEnter,onmouseleave:_onTitleLeave'\r\n\t\tclass='dijitAccordionTitle' wairole=\"tab\" waiState=\"expanded-false\"\r\n\t\t><span class='dijitInline dijitAccordionArrow' waiRole=\"presentation\"></span\r\n\t\t><span class='arrowTextUp' waiRole=\"presentation\">+</span\r\n\t\t><span class='arrowTextDown' waiRole=\"presentation\">-</span\r\n\t\t><span waiRole=\"presentation\" dojoAttachPoint='titleTextNode' class='dijitAccordionText'></span></div\r\n\t><div waiRole=\"presentation\"><div dojoAttachPoint='containerNode' style='overflow: hidden; height: 1px; display: none'\r\n\t\tclass='dijitAccordionBody' wairole=\"tabpanel\"\r\n\t></div></div>\r\n</div>\r\n",
- attributeMap: dojo.mixin(dojo.clone(dijit.layout.ContentPane.prototype.attributeMap), {
- title: {node: "titleTextNode", type: "innerHTML" }
- }),
-
- baseClass: "dijitAccordionPane",
-
- postCreate: function(){
- this.inherited(arguments)
- dojo.setSelectable(this.titleNode, false);
- this.setSelected(this.selected);
- dojo.attr(this.titleTextNode, "id", this.domNode.id+"_title");
- dijit.setWaiState(this.focusNode, "labelledby", dojo.attr(this.titleTextNode, "id"));
- },
-
- 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);
- }
- },
-
- _onTitleEnter: function(){
- // summary: callback when someone hovers over my title
- dojo.addClass(this.focusNode, "dijitAccordionTitle-hover");
- },
-
- _onTitleLeave: function(){
- // summary: callback when someone stops hovering over my title
- dojo.removeClass(this.focusNode, "dijitAccordionTitle-hover");
- },
-
- _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");
- dijit.setWaiState(this.focusNode, "expanded", isSelected);
- 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(); // if href specified, trigger load
- }
- },
-
- onSelected: function(){
- // summary: called when this pane is selected
- }
- });
-
- }