I saw this question come up on a list today and thought this was pretty handy. Plus, I think it is the first time I’ve had a chance to play with the ContextMenu and ContextMenuItem classes in Flex in quite a while.
The following example pops up a custom context menu when the user right-clicks on an item in an data grid. After selecting the custom item (“View item…”) from the context menu an Alert control is displayed showing the selected item’s properties.
Full code after the jump.
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/20/using-a-custom-context-menu-with-the-flex-datagrid-control/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
[Bindable]
private var cm:ContextMenu;
private var alert:Alert;
private function init():void {
var cmi:ContextMenuItem = new ContextMenuItem("View item...", true);
cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, contextMenuItem_menuItemSelect);
cm = new ContextMenu();
cm.hideBuiltInItems();
cm.customItems = [cmi];
cm.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelect);
}
private function contextMenu_menuSelect(evt:ContextMenuEvent):void {
dataGrid.selectedIndex = lastRollOverIndex;
}
private function contextMenuItem_menuItemSelect(evt:ContextMenuEvent):void {
var obj:Object = dataGrid.selectedItem;
alert = Alert.show("Property A: " + obj.@propertyA + "\\n" + "Property B: " + obj.@propertyB, obj.@label, Alert.OK);
}
]]>
</mx:Script>
<mx:XML id="itemsXML">
<items>
<item label="Item 1" data="i001" propertyA="Item 1.A" propertyB="Item 1.B" />
<item label="Item 2" data="i002" propertyA="Item 2.A" propertyB="Item 2.B" />
<item label="Item 3" data="i003" propertyA="Item 3.A" propertyB="Item 3.B" />
<item label="Item 4" data="i004" propertyA="Item 4.A" propertyB="Item 4.B" />
<item label="Item 5" data="i005" propertyA="Item 5.A" propertyB="Item 5.B" />
<item label="Item 6" data="i006" propertyA="Item 6.A" propertyB="Item 6.B" />
<item label="Item 7" data="i007" propertyA="Item 7.A" propertyB="Item 7.B" />
<item label="Item 8" data="i008" propertyA="Item 8.A" propertyB="Item 8.B" />
</items>
</mx:XML>
<mx:Number id="lastRollOverIndex" />
<mx:DataGrid id="dataGrid"
width="400"
dataProvider="{itemsXML.item}"
contextMenu="{cm}"
itemRollOver="lastRollOverIndex = event.rowIndex">
<mx:columns>
<mx:DataGridColumn id="labelCol"
dataField="@label"
headerText="Label:" />
<mx:DataGridColumn id="propACol"
dataField="@propertyA"
headerText="Property A:" />
<mx:DataGridColumn id="propBCol"
dataField="@propertyB"
headerText="Property B:" />
</mx:columns>
</mx:DataGrid>
<mx:Label text="{dataGrid.selectedItem.@label}" />
</mx:Application>
View source is enabled in the following example.

{ 48 comments… read them below or add one }
Thanks for posting this. When I copied your code into a Flex Builder MXML project and run it in FireFox I get a weird behavior. When I right click on a grid item, the item that is selected in the Alert box is the next item below the one I right-clicked on. This page works fine in FireFox, but when I just run the example code in FireFox from Flex Builder I get the strange behavior. I’m using FireFox 2.
Bruce,
Are you using Flex 2 or Flex 3? (and if Flex 2, which Hotfix (if any) are you using)
I only tested on Flex 3, so maybe there is a slight difference between the two versions.
Peter
Thanks for that…the rightClick doesn’t function / react on Mac OSX Safari 3 Beta.
Best regards
Charly
Peter,
nice idea to use {cm} in MXML designer, we were used to install the custom item from AS code :-)
But we could not deal with Right-Click menu for hyper-links AT ALL. If you use a textarea with a hyper-link, hyperlink context menu always contains 3 items: “Copy link”, “Open link”, “Open link in a new window”.
Haven’t you managed to add custom items there?
Is it possible to implement an itemeditor not directly in the datagrid but over it (like a modal window)?
Good , Can we create right click option on a image then at runtime user can cut copy paste the image …..
Great post, i find good stuff here about flex, which i find very good to me.
thanks
Pls give details about custom view
THe COde is too good for me…
thanks
thanks….
great coding in flex
Can we totally remove the default menu containing the settings and about flash player items?
Susrut Mishra,
No, sorry.
Peter
Thank you,
Was wondering how we can extend this with more menu items…
regards,
Dipak
No worries, got it figured out…
nice and simple. thnx for sharing.
I ran into the same issue with Flex2, wrong item being selected when right-clicking. This seem to have fixed it:
itemRollOver=”lastRollOverIndex = event.rowIndex – 1″
hello,
when i’m trying to implement your code exactly as showed here, i get a strange bug.
When i right click in my datagrid, the context menu appears but there is no MENU_SELECT event triggerd ( I’ve wrote a trace in the contextMenu_menuSelect function ) my last row index number changes on itemRollovers but because the MENU_SELECT seems not to be triggerd, my selected index does not change.
the strange thing is that when i click on ”view item” he suddenly shows the trace but it doesn’t make sense for me because it should only trigger the MENU_ITEM_SELECT event
here is the code i use maybe i’m doing something wrong
var cmi:ContextMenuItem = new ContextMenuItem(“View item”, true);
cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, contextMenuItem_menuItemSelect);
cmLibrary = new ContextMenu();
cmLibrary.hideBuiltInItems();
cmLibrary.customItems = [cmi];
cmLibrary.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelect);
private function contextMenu_menuSelect(evt:ContextMenuEvent):void {
trace(“right clicked”);
Library.selectedIndex = lastRollOverIndex;
}
private function contextMenuItem_menuItemSelect(evt:ContextMenuEvent):void {
var obj:Object = Library.selectedItem;
trace(obj.artist);
}
NOTE: even when i put the MENU_ITEM_EVENT listener in comments: the MENU_SELECT event is being triggerd when i click on View Item
Can anyone help out?
grtz Thomas
Can we create right click option on a image then at runtime user can cut copy paste the image pls any specify me soon.
thanks
Posin,
I don’t believe you can. You should be able to create a custom context menu item for an Image control, and then you could copy the URL of an image to the system clip board, but I don’t believe you can copy the actual image/pixels. Of course, I could very well be wrong, so you may want to ask on a high-traffic list like FlashCoders or FlexCoders and see if anybody else has attempted something like this before.
Sorry,
Peter
This page works fine in FireFox, but when I just run the example code in FireFox from Flex Builder I get the strange behavior so what can i do for that pls send me detials. thanks
I tried to add a few context menu items today, found out that names: “Open” and “Delete” are not allowed.
link to a work around: http://polygeek.com/373_adobeflash_flash-context-menu-doesnt-allow-delete
“appending a no break space to the end of the word”
how can we put an icon in to context menu
nice example. this helped a lot!
Hi,
Has anyone tried adding a submenu to the ContextMenu added on the data Grid? The flex-3 documentation mentions a function ‘addSubmenu’ in the ContextMenu class, using which it is possible to implement nested contextmenus in flex. But, the problem here is that the flex-3 builder does not support that class yet.
I am currently using Demo version of Flex-3. Would purchasing the license and then executing the same code fix the problem?
Ravi,
I believe the
addSubmenu()method is for AIR applications only.Peter
if we can not remove default context menus like “setting..” its a main problem
Great job Bruce,
Is there a way to remove
*Settings and
*About Flash Player
If there is please let me know…
It wood look more simple on the application.
Regards.
Good work.found it very useful. But did any one try putting more than one options in the context menu?
I’ve been working on my first serious flex app. I can’t tell you how many times my googling has lead me to your blog, and how helpful it has been. You’re my hero.
What this line is for?
cm.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelect);
I read that the ContextMenu API does not support submenus. They actually said that was its biggest drawback.
Is it possible to put an icon next the ContextMenuItem?
Usually it’as V to show the option is activated.
thanks
Adrien
Great post!
Not being able to remove Settings …, About .. and the all-important Download this vidio … are major drawbacks, not to mention having control over formatting of the menu.
Right click support is Flex’s biggest weakness IMO. Has anyone noticed that if the user left clicks a control such as a spinner, then right clicks at the same time, the program can no longer capture the MouseUp event on the left mouse button? The spinner keeps spinning as if you still had the left click button depressed even if you let go of the mouse. I have found no good way to prevent this (and am not fond of putting an opaque html layer over the entire Flex application).
It makes no sence that right click handling is restricted to Adobe Air.
Even JavaScript allows us to capture the right click event.
Many thanks for your code
This example was really good.
Thanks for posting
Hello,
I am trying this code in AIR, it does not work.
But it works in a Flex(web) application.
Can U suggest me what to do different in the case of an AIR application.
thnks,
Rahul.
Great example.
But it is not working in air
Anybody having solution for this?
Try this Rahul..It’s working
Sorry..forgot to send the link
http://kuvempu.wordpress.com/context-menu-in-air/
Try this
This does not work in Air.
If the context menu is opened and the user right-clicks on an other item, the item is not selected as the itemRollOver event is not dispatched :(
Anyone has a solution to this problem ?
Nice work Peter, I implemented it without any problem. Having said that – I originally had a double click event that opened a TitleWindow. I needed another event handler so I implemented the ContextMenu with a “View” and “Edit” event. Both of these work fine; however I lost my doubleClick event on the grid itself. Any suggestions?
My Syntax:
And of course my grid
Thanks again for your generosity
is it possible to customize the right click menu of an application not a grid?
Thanks
don’t bother found it, i had to add contextMenu=”{cm}” to the application instead of the grid
A good example, thanks.
A couple of points though -
1. To make this work in an AIR app, you need to assign the context menu to the grid programmatically, eg: by adding <code>dataGrid.contextMenu = cm;</code> to the end of the init() function.
2. It might make more sense to read the data from <code>dataGrid.dataProvider[lastRollOverIndex]</code>, rather than setting the datagrid’s index every time you right click.
When a user double-clicks a row, the row should be replaced by a vbox that displays the detail of the row selected and this should be done at the point of the row selected i.e. inline. Has anyone any idea how I could get this done.
a really simple and good working solutionfor this problem … once more thanx
There are different capabilities regarding custom context menus in AIR apps versus browser-deployed Flex apps. AIR actually has some very serious limitations that the browser-deployed Flex apps do not have. Ironic that the browser app would be “richer” in this respect than the AIR app, but it is documented. Flex browser-based apps have limits on the number of custom items in the context-menu.. AIR apps are limited as to which controls can have a custom context menu in the first place. As of FB3, in AIR the component to which the custom context-menu is being attached must be top-level. This limitation makes custom context-menu support in AIR almost useless, IMO.
@Tim Romano,
Feel free to file a bug/enhancement request at http://bugs.adobe.com/flex/ if you think the AIR behavior should be changed. Or, you can also file Adobe AIR bugs/enhancements at https://www.adobe.com/cfusion/mmform/index.cfm?name=wishform and select “Adobe AIR” from the drop down menu.
Peter