Opened 10 years ago
Closed 8 years ago
#9826 closed enhancement (wontfix)
Allow menu to operate as a drop down
Reported by: | craigm | Owned by: | |
---|---|---|---|
Priority: | high | Milestone: | future |
Component: | Dijit | Version: | 1.3.2 |
Keywords: | Menu DropDown drop down DropDownMenu | Cc: | |
Blocked By: | Blocking: |
Description
At the moment a plain Menu widget's _openMyself() function has 2 methods of determining the x/y coordinates at where it should display itself. A right click will trigger the menu at the cursor, otherwise it appears at 10 pixel offset from the top left position of the target node. I'd like to propose an enhancement to the base Menu widget that allows it to operate as a drop down to its attached node, similar to the functionality of the DropDownButton?, but without the need for the button.
My use case for this particular enhancement is that I have some navigation images at the top of my page and mouse over event for these images triggers the menu which should appear as a drop down. This means that the menu needs to position itself at the bottom left corner of the image that fired the mouse over event. I have already modified the Menu.js file in my project to achieve this but would like to see it added to dojo.
Original code in Menu._openMySelf():
var x,y; if(dojo.isSafari || this._contextMenuWithMouse){ x=e.pageX; y=e.pageY; }else{ // otherwise open near e.target var coords = dojo.coords(e.target, true); x = coords.x + 10; y = coords.y + 10; }
Modified version:
var x,y; if (this.openUnderTarget) { var coords = dojo.coords(e.target, true); var targetHeight = e.target.offsetHeight; x = coords.x; y = coords.y + targetHeight; } else if(dojo.isSafari || this._contextMenuWithMouse){ x=e.pageX; y=e.pageY; }else{ // otherwise open near e.target var coords = dojo.coords(e.target, true); x = coords.x + 10; y = coords.y + 10; }
I'll try to attach a screenshot and patch.
Attachments (2)
Change History (8)
Changed 10 years ago by
Attachment: | example.JPG added |
---|
comment:1 Changed 10 years ago by
Dijit tries to keep widgets separate from popup/dropdown functionality. Note how _Calendar is just a plain-old widget but you can use it as a drop down by calling dijit.popup.open().
Menu was a bit of an exception because Menu's can be attached to existing nodes as context menus, but if you want to make thean image spawn a drop down why not just call dijit.popup.open() ?
comment:2 Changed 10 years ago by
Bill,
That did occur to me but I didn't want to duplicate the code for the onExecute and onCancel handlers, in addition to the focus and blur stuff after dijit.popup.open is called.
Maybe a good compromise would be to break this function down into 2 separate functions. Add a new function that returns something like {x: TheXCoord, y: TheYCoord} and functions the same as the current if/else block in the trunk. This function could be called something like _getPopupLocation(). _openMySelf would call this function to find the location of the popup and I can override this function with my own version that attaches it to a DOM node.
_getPopupLocation: function(/*Event*/ e) { // summary: // Internal function for determining the x/y coordinate // at which the menu should appear // tags: // private // Get coordinates. // if we are opening the menu with the mouse or on safari open // the menu at the mouse cursor // (Safari does not have a keyboard command to open the context menu // and we don't currently have a reliable way to determine // _contextMenuWithMouse on Safari) var x,y; if(dojo.isSafari || this._contextMenuWithMouse){ x=e.pageX; y=e.pageY; }else{ // otherwise open near e.target var coords = dojo.coords(e.target, true); x = coords.x + 10; y = coords.y + 10; } return {x: x, y: y}; }, _openMyself: function(/*Event*/ e){ // summary: // Internal function for opening myself when the user // does a right-click or something similar // tags: // private if(this.leftClickToOpen&&e.button>0){ return; } dojo.stopEvent(e); var popupLoc = this._getPopupLocation(e); var self=this; var savedFocus = dijit.getFocus(this); function closeAndRestoreFocus(){ // user has clicked on a menu or popup dijit.focus(savedFocus); dijit.popup.close(self); } dijit.popup.open({ popup: this, x: popupLoc.x, y: popupLoc.y, onExecute: closeAndRestoreFocus, onCancel: closeAndRestoreFocus, orient: this.isLeftToRight() ? 'L' : 'R' }); this.focus(); this._onBlur = function(){ this.inherited('_onBlur', arguments); // Usually the parent closes the child widget but if this is a context // menu then there is no parent dijit.popup.close(this); // don't try to restore focus; user has clicked another part of the screen // and set focus there }; },
comment:3 Changed 10 years ago by
Milestone: | 1.4 → 1.5 |
---|
comment:4 Changed 9 years ago by
Milestone: | 1.5 → 1.6 |
---|
comment:5 Changed 9 years ago by
Milestone: | 1.6 → future |
---|
comment:6 Changed 8 years ago by
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Sorry, I don't want to add any (more) special code to menu. If dijit.popup.open() is too hard to use maybe the signature could be simplified.
Menu opening at bottom left corner of image that was moused over