(I figured this question had more to do with the Dojo event system rather than the Menu widget, so I'm posting it here, but if I should be asking this to the Dijit forum, please advise.)
I'm using a context menu to let users manipulate the selected element. For that, I'm using the event system by referring to Event Object section of the Book of Dojo.
As a simple example, when a user right-clicks on an item and selects "Delete Item" from the context menu, I want to hide the selected item. To do so I need to find out the ID of the selected element.
I wrote the following code, and hideItem() function is receiving an event object for sure, but I cannot get the ID value from the target element. The alert statement in hideItem() gives me an empty string, contrary to my expectations that I would receive either "divItem_a" or "divItem_b".
Could someone please advise how I can get the right values?
Event Test
@import "./scripts/dojo/resources/dojo.css";
@import "./scripts/dijit/themes/tundra/tundra.css";
@import "./scripts/dijit/themes/tundra/tundra_rtl.css";
.item {border: 1px solid gray; width: 142px; height: 14px;}
a
b
Add Item
Delete Item
Any suggestions would be very much appreciated.
Thank you,
Sari

The event.target is pointing at a TD element???
I dug into the problem a little more, and have new findings.
1) I made the test program to show event.target.tagName instead of element.id, and it gave me "TD" as the result, whereas I expected to get "DIV" as the result.
2) I made the test program as simple as possible, removing table tags and other unnecessary div elements, and event.target.tagName is still giving me "TD". Since I no longer have any TD elements, I don't know where this is coming from.
It seems that somehow hideItem() (my event handler function) is receiving an unexpected event object. That is why I can't get the element ID from event.target.
Am I using the event system the right way?
The code that I made as simple as possible now looks like as follows:
Event Test @import "./scripts/dojo/resources/dojo.css"; @import "./scripts/dijit/themes/tundra/tundra.css"; @import "./scripts/dijit/themes/tundra/tundra_rtl.css"; .item {border: 1px solid gray; width: 142px; height: 14px;}a
b
Delete Item
Any suggestions and insights would be very much appreciated.
Thank you,
Sari
Ⅰ have a workaround but....
I think I found a workaround (though I still can't figure out the right way).
I added a function that puts the ID in a global variable -
function rememberSelected(event) { selectedId = event.target.id; }I then used the onmousedown event to call the new function. This function gets called before the menu pops up.
I'm sure there is a right way to do this, though, so any suggestions on how to do this the right way would be very much appreciated.
Thank you,
Sari
There doesn't appear to be
There doesn't appear to be any built-in way to do what you want. Not having a stored reference to the node that was clicked on to generate the context menu definitely makes the Menu widget incomplete.
By connecting to the "oncontextmenu" event, I was able to dynamically create the onClick function for the miDelete menu item. This can easily be done for any other menu items at the same time.
'item_a',
'item_b'
);
dojo.addOnLoad(function() {
var menu = dijit.byId('cMenu');
for (i=0; i < targets.length; i++) {
dojo.connect(dojo.byId(targets[i]), 'oncontextmenu', null,
function (e) {
dojo.stopEvent(e);
dijit.byId('miDelete').onClick =
function() {
e.target.parentNode.removeChild(e.target);
//e.target.innerHTML = "";
}
}
);
menu.bindDomNode(targets[i]);
}
});
<div id="item_b">Item B</div>
<div dojoType="dijit.Menu" id="cMenu" contextMenuForWindow="false" style="display: none;">
<div dojoType="dijit.MenuItem" id="miDelete">Delete Item</div>
</div>
Hope this helps..
Matt
Dirty fix
Sari: I believe that what you get on the event handler is in fact the dijit object that triggered the event (you are getting a this "pointer" into the menuItem).
Anyway, I had the same need to detect what is the DOM node that was clicked by the user to open up the menu, and finally got it to work, by doing this:
I modified in dojo.dijit.Menu.js the funcion _openMyself, around the lines 239, and 245 like this:
self.targetNode = e.target; // <---- Added this line
var savedFocus = dijit.getFocus(this);
function closeAndRestoreFocus(){
// user has clicked on a menu or popup
dijit.focus(savedFocus);
dijit.popup.close(self);
self.targetNode = null; // <---- Added this line
}
With those 2 lines in place, I can do this in the onExecute callback for any menu :
var tgt = this.targetNode; // <---- This is the DOM Node the user clicked to open the menu!
.
.
.
}
Hope that helps
Thank you!
Matt, gnunezr,
Thank you both for shedding light on the problem.
Both of your techniques look more effective and versatile than the workaround I came up with that uses onmousedown, and I'll definitely try them as soon as I'm done with another problem I'm working on now.
Just wanted to take a moment to thank you both for your help.
Thank you,
Sari