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.
dijit._HasDropDown._arrowWrapperNode
tags: protected
type
DomNode
summary
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.
dijit._HasDropDown._popupStateNode
tags: protected
type
DomNode
summary
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.
dijit._HasDropDown._aroundNode
tags: protected
type
DomNode
summary
The node to display the popup around.
Can be set via a dojoAttachPoint assignment.
If missing, then domNode will be used.
dijit._HasDropDown.dropDown
tags: protected
type
Widget
summary
The widget to display as a popup. This widget *must* be
defined before the startup function is called.
dijit._HasDropDown.autoWidth
tags: protected
type
Boolean
summary
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
dijit._HasDropDown.forceWidth
tags: protected
type
Boolean
summary
Set to true to make the drop down exactly as wide as this
widget. Overrides autoWidth.
dijit._HasDropDown.maxHeight
tags: protected
type
Integer
summary
The max height for our dropdown.
Any dropdown taller than this will have scrollbars.
Set to 0 for no max height, or -1 to limit height to available space in viewport
dijit._HasDropDown.dropDownPosition
tags: const
type
String[
summary
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.
dijit._HasDropDown._stopClickEvents
type
Boolean
summary
When set to false, the click events will not be stopped, in
case you want to use them in your subwidget
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 && dropDown.autoFocus !== false){ // 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); }
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.
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. // Any dropdown taller than this will have scrollbars. // Set to 0 for no max height, or -1 to limit height to available space in viewport 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
_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
// 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");
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 even though it's logically my child. if(!this.dropDown._destroyed){ this.dropDown.destroyRecursive(); } delete this.dropDown; } this.inherited(arguments);
var d = this.dropDown, target = e.target; if(d && this._opened && d.handleKey){ if(d.handleKey(e) === false){ /* false return code means that the drop down handled the key */ dojo.stopEvent(e); return; } } if(d && this._opened && e.charOrCode == dojo.keys.ESCAPE){ this.closeDropDown(); dojo.stopEvent(e); }else if(!this._opened && (e.charOrCode == dojo.keys.DOWN_ARROW || ( (e.charOrCode == dojo.keys.ENTER || e.charOrCode == " ") && //ignore enter and space if the event is for a text input ((target.tagName || "").toLowerCase() !== 'input' || (target.type && target.type.toLowerCase() !== 'text'))))){ // Toggle the drop down, but wait until keyup so that the drop down doesn't // get a stray keyup event, or in the case of key-repeat (because user held // down key for too long), stray keydown events this._toggleOnKeyUp = true; dojo.stopEvent(e); }
summary
Callback when the user presses a key while focused on the button node
if(this._toggleOnKeyUp){ delete this._toggleOnKeyUp; this.toggleDropDown(); var d = this.dropDown; // drop down may not exist until toggleDropDown() call if(d && d.focus){ setTimeout(dojo.hitch(d, "focus"), 1); } }
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. // Any dropdown taller than this will have scrollbars. // Set to 0 for no max height, or -1 to limit height to available space in viewport 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
_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
Loads the data for the dropdown, and at some point, calls
the given callback. This is basically a callback when the
user presses the down arrow button to open the drop down.
if(this.disabled || this.readOnly){ 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(); }
summary
Callback when the user presses the down arrow button or presses
the down arrow key to open/close the drop down.
Toggle the drop-down widget; if it is up, close it, if not, open it
// 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){ 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);
// Figure out maximum height allowed (if there is a height restriction) var maxHeight = this.maxHeight; if(maxHeight == -1){ // limit height to space available in viewport either above or below my domNode // (whichever side has more room) var viewport = dojo.window.getBox(), position = dojo.position(aroundNode, false); maxHeight = Math.floor(Math.max(position.y, viewport.h - (position.y + position.h))); }
// Attach dropDown to DOM and make make visibility:hidden rather than display:none // so we call startup() and also get the size if(dropDown.startup && !dropDown._started){ dropDown.startup(); }
dijit.popup.moveOffScreen(dropDown); // Get size of drop down, and determine if vertical scroll bar needed var mb = dojo._getMarginSize(ddNode); var overHeight = (maxHeight && mb.h > maxHeight); dojo.style(ddNode, { overflowX: "hidden", overflowY: overHeight ? "auto" : "hidden" }); if(overHeight){ mb.h = maxHeight; if("w" in mb){ mb.w += 16; // room for vertical scrollbar } }else{ delete mb.h; }
// Adjust dropdown width to match or be larger than my width if(this.forceWidth){ mb.w = aroundNode.offsetWidth; }else if(this.autoWidth){ mb.w = Math.max(mb.w, aroundNode.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); } }