0byt3m1n1
Path:
/
data
/
applications
/
aps.bak
/
phprojekt
/
6.0.6-0
/
standard
/
htdocs
/
htdocs
/
dojo
/
dijit
/
[
Home
]
File: _HasDropDown.js
/* Copyright (c) 2004-2010, 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._HasDropDown"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dijit._HasDropDown"] = true; dojo.provide("dijit._HasDropDown"); dojo.require("dijit._base.place"); dojo.require("dijit._Widget"); dojo.declare("dijit._HasDropDown", null, { // summary: // Mixin for widgets that need drop down ability. // _buttonNode: [protected] DomNode // The button/icon/node to click to display the drop down. // Can be set via a dojoAttachPoint assignment. // If missing, then either focusNode or domNode (if focusNode is also missing) will be used. _buttonNode: null, // _arrowWrapperNode: [protected] DomNode // Will set CSS class dijitUpArrow, dijitDownArrow, dijitRightArrow etc. on this node depending // on where the drop down is set to be positioned. // Can be set via a dojoAttachPoint assignment. // If missing, then _buttonNode will be used. _arrowWrapperNode: null, // _popupStateNode: [protected] DomNode // The node to set the popupActive class on. // Can be set via a dojoAttachPoint assignment. // If missing, then focusNode or _buttonNode (if focusNode is missing) will be used. _popupStateNode: null, // _aroundNode: [protected] DomNode // The node to display the popup around. // Can be set via a dojoAttachPoint assignment. // If missing, then domNode will be used. _aroundNode: null, // dropDown: [protected] Widget // The widget to display as a popup. This widget *must* be // defined before the startup function is called. dropDown: null, // autoWidth: [protected] Boolean // Set to true to make the drop down at least as wide as this // widget. Set to false if the drop down should just be its // default width autoWidth: true, // forceWidth: [protected] Boolean // Set to true to make the drop down exactly as wide as this // widget. Overrides autoWidth. forceWidth: false, // maxHeight: [protected] Integer // The max height for our dropdown. Set to 0 for no max height. // any dropdown taller than this will have scrollbars maxHeight: 0, // dropDownPosition: [const] String[] // This variable controls the position of the drop down. // It's an array of strings with the following values: // // * before: places drop down to the left of the target node/widget, or to the right in // the case of RTL scripts like Hebrew and Arabic // * after: places drop down to the right of the target node/widget, or to the left in // the case of RTL scripts like Hebrew and Arabic // * above: drop down goes above target node // * below: drop down goes below target node // // The list is positions is tried, in order, until a position is found where the drop down fits // within the viewport. // dropDownPosition: ["below","above"], // _stopClickEvents: Boolean // When set to false, the click events will not be stopped, in // case you want to use them in your subwidget _stopClickEvents: true, _onDropDownMouseDown: function(/*Event*/ e){ // summary: // Callback when the user mousedown's on the arrow icon if(this.disabled || this.readOnly){ return; } this._docHandler = this.connect(dojo.doc, "onmouseup", "_onDropDownMouseUp"); this.toggleDropDown(); }, _onDropDownMouseUp: function(/*Event?*/ e){ // summary: // Callback when the user lifts their mouse after mouse down on the arrow icon. // If the drop is a simple menu and the mouse is over the menu, we execute it, otherwise, we focus our // dropDown node. If the event is missing, then we are not // a mouseup event. // // This is useful for the common mouse movement pattern // with native browser <select> nodes: // 1. mouse down on the select node (probably on the arrow) // 2. move mouse to a menu item while holding down the mouse button // 3. mouse up. this selects the menu item as though the user had clicked it. if(e && this._docHandler){ this.disconnect(this._docHandler); } var dropDown = this.dropDown, overMenu = false; if(e && this._opened){ // This code deals with the corner-case when the drop down covers the original widget, // because it's so large. In that case mouse-up shouldn't select a value from the menu. // Find out if our target is somewhere in our dropdown widget, // but not over our _buttonNode (the clickable node) var c = dojo.position(this._buttonNode, true); if(!(e.pageX >= c.x && e.pageX <= c.x + c.w) || !(e.pageY >= c.y && e.pageY <= c.y + c.h)){ var t = e.target; while(t && !overMenu){ if(dojo.hasClass(t, "dijitPopup")){ overMenu = true; }else{ t = t.parentNode; } } if(overMenu){ t = e.target; if(dropDown.onItemClick){ var menuItem; while(t && !(menuItem = dijit.byNode(t))){ t = t.parentNode; } if(menuItem && menuItem.onClick && menuItem.getParent){ menuItem.getParent().onItemClick(menuItem, e); } } return; } } } if(this._opened && dropDown.focus){ // Focus the dropdown widget - do it on a delay so that we // don't steal our own focus. window.setTimeout(dojo.hitch(dropDown, "focus"), 1); } }, _onDropDownClick: function(/*Event*/ e){ // the drop down was already opened on mousedown/keydown; just need to call stopEvent() if(this._stopClickEvents){ dojo.stopEvent(e); } }, _setupDropdown: function(){ // summary: // set up nodes and connect our mouse and keypress events this._buttonNode = this._buttonNode || this.focusNode || this.domNode; this._popupStateNode = this._popupStateNode || this.focusNode || this._buttonNode; this._aroundNode = this._aroundNode || this.domNode; this.connect(this._buttonNode, "onmousedown", "_onDropDownMouseDown"); this.connect(this._buttonNode, "onclick", "_onDropDownClick"); this.connect(this._buttonNode, "onkeydown", "_onDropDownKeydown"); this.connect(this._buttonNode, "onkeyup", "_onKey"); // If we have a _setStateClass function (which happens when // we are a form widget), then we need to connect our open/close // functions to it if(this._setStateClass){ this.connect(this, "openDropDown", "_setStateClass"); this.connect(this, "closeDropDown", "_setStateClass"); } // Add a class to the "dijitDownArrowButton" type class to _buttonNode so theme can set direction of arrow // based on where drop down will normally appear var defaultPos = { "after" : this.isLeftToRight() ? "Right" : "Left", "before" : this.isLeftToRight() ? "Left" : "Right", "above" : "Up", "below" : "Down", "left" : "Left", "right" : "Right" }[this.dropDownPosition[0]] || this.dropDownPosition[0] || "Down"; dojo.addClass(this._arrowWrapperNode || this._buttonNode, "dijit" + defaultPos + "ArrowButton"); }, postCreate: function(){ this._setupDropdown(); this.inherited(arguments); }, destroyDescendants: function(){ if(this.dropDown){ // Destroy the drop down, unless it's already been destroyed. This can happen because // the drop down is a direct child of <body> even though it's logically my child. if(!this.dropDown._destroyed){ this.dropDown.destroyRecursive(); } delete this.dropDown; } this.inherited(arguments); }, _onDropDownKeydown: function(/*Event*/ e){ if(e.keyCode == dojo.keys.DOWN_ARROW || e.keyCode == dojo.keys.ENTER || e.keyCode == dojo.keys.SPACE){ e.preventDefault(); // stop IE screen jump } }, _onKey: function(/*Event*/ e){ // summary: // Callback when the user presses a key while focused on the button node if(this.disabled || this.readOnly){ return; } var d = this.dropDown; if(d && this._opened && d.handleKey){ if(d.handleKey(e) === false){ return; } } if(d && this._opened && e.keyCode == dojo.keys.ESCAPE){ this.toggleDropDown(); }else if(d && !this._opened && (e.keyCode == dojo.keys.DOWN_ARROW || e.keyCode == dojo.keys.ENTER || e.keyCode == dojo.keys.SPACE)){ this.toggleDropDown(); if(d.focus){ setTimeout(dojo.hitch(d, "focus"), 1); } } }, _onBlur: function(){ // summary: // Called magically when focus has shifted away from this widget and it's dropdown this.closeDropDown(); // don't focus on button. the user has explicitly focused on something else. this.inherited(arguments); }, isLoaded: function(){ // summary: // Returns whether or not the dropdown is loaded. This can // be overridden in order to force a call to loadDropDown(). // tags: // protected return true; }, loadDropDown: function(/* Function */ loadCallback){ // summary: // Loads the data for the dropdown, and at some point, calls // the given callback // tags: // protected loadCallback(); }, toggleDropDown: function(){ // summary: // Toggle the drop-down widget; if it is up, close it, if not, open it // tags: // protected if(this.disabled || this.readOnly){ return; } this.focus(); var dropDown = this.dropDown; if(!dropDown){ return; } if(!this._opened){ // If we aren't loaded, load it first so there isn't a flicker if(!this.isLoaded()){ this.loadDropDown(dojo.hitch(this, "openDropDown")); return; }else{ this.openDropDown(); } }else{ this.closeDropDown(); } }, openDropDown: function(){ // summary: // Opens the dropdown for this widget - it returns the // return value of dijit.popup.open // tags: // protected var dropDown = this.dropDown; var ddNode = dropDown.domNode; var self = this; // Prepare our popup's height and honor maxHeight if it exists. // TODO: isn't maxHeight dependent on the return value from dijit.popup.open(), // ie, dependent on how much space is available (BK) if(!this._preparedNode){ dijit.popup.moveOffScreen(ddNode); this._preparedNode = true; // Check if we have explicitly set width and height on the dropdown widget dom node if(ddNode.style.width){ this._explicitDDWidth = true; } if(ddNode.style.height){ this._explicitDDHeight = true; } } // Code for resizing dropdown (height limitation, or increasing width to match my width) if(this.maxHeight || this.forceWidth || this.autoWidth){ var myStyle = { display: "", visibility: "hidden" }; if(!this._explicitDDWidth){ myStyle.width = ""; } if(!this._explicitDDHeight){ myStyle.height = ""; } dojo.style(ddNode, myStyle); // Get size of drop down, and determine if vertical scroll bar needed var mb = dojo.marginBox(ddNode); var overHeight = (this.maxHeight && mb.h > this.maxHeight); dojo.style(ddNode, { overflowX: "hidden", overflowY: overHeight ? "auto" : "hidden" }); if(overHeight){ mb.h = this.maxHeight; if("w" in mb){ mb.w += 16; // room for vertical scrollbar } }else{ delete mb.h; } delete mb.t; delete mb.l; // Adjust dropdown width to match or be larger than my width if(this.forceWidth){ mb.w = this.domNode.offsetWidth; }else if(this.autoWidth){ mb.w = Math.max(mb.w, this.domNode.offsetWidth); }else{ delete mb.w; } // And finally, resize the dropdown to calculated height and width if(dojo.isFunction(dropDown.resize)){ dropDown.resize(mb); }else{ dojo.marginBox(ddNode, mb); } } var retVal = dijit.popup.open({ parent: this, popup: dropDown, around: this._aroundNode, orient: dijit.getPopupAroundAlignment((this.dropDownPosition && this.dropDownPosition.length) ? this.dropDownPosition : ["below"],this.isLeftToRight()), onExecute: function(){ self.closeDropDown(true); }, onCancel: function(){ self.closeDropDown(true); }, onClose: function(){ dojo.attr(self._popupStateNode, "popupActive", false); dojo.removeClass(self._popupStateNode, "dijitHasDropDownOpen"); self._opened = false; self.state = ""; } }); dojo.attr(this._popupStateNode, "popupActive", "true"); dojo.addClass(self._popupStateNode, "dijitHasDropDownOpen"); this._opened=true; this.state="Opened"; // TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown return retVal; }, closeDropDown: function(/*Boolean*/ focus){ // summary: // Closes the drop down on this widget // tags: // protected if(this._opened){ if(focus){ this.focus(); } dijit.popup.close(this.dropDown); this._opened = false; this.state = ""; } } } ); }