Using a custom context menu with the Flex DataGrid control

by Peter deHaan on August 20, 2007

in ContextMenu, ContextMenuItem, DataGrid

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.

View MXML

<?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 }

1 Bruce August 21, 2007 at 7:43 am

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.

Reply

2 peterd August 22, 2007 at 9:22 am

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

Reply

3 Charly August 26, 2007 at 4:31 am

Thanks for that…the rightClick doesn’t function / react on Mac OSX Safari 3 Beta.

Best regards
Charly

Reply

4 Ruslan Balkin August 27, 2007 at 9:16 am

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?

Reply

5 Matthias October 8, 2007 at 8:30 am

Is it possible to implement an itemeditor not directly in the datagrid but over it (like a modal window)?

Reply

6 prashant October 24, 2007 at 6:23 am

Good , Can we create right click option on a image then at runtime user can cut copy paste the image …..

Reply

7 Posin November 13, 2007 at 1:32 am

Great post, i find good stuff here about flex, which i find very good to me.
thanks

Reply

8 Imran patel November 13, 2007 at 2:38 am

Pls give details about custom view

Reply

9 Ramila ramchandani November 13, 2007 at 2:39 am

THe COde is too good for me…
thanks

Reply

10 Sonam Jain November 13, 2007 at 2:46 am

thanks….
great coding in flex

Reply

11 Susrut Mishra November 16, 2007 at 1:52 pm

Can we totally remove the default menu containing the settings and about flash player items?

Reply

12 peterd November 16, 2007 at 2:00 pm

Susrut Mishra,

No, sorry.

Peter

Reply

13 Dipak December 3, 2007 at 7:32 pm

Thank you,

Was wondering how we can extend this with more menu items…

regards,
Dipak

Reply

14 Dipak December 3, 2007 at 8:29 pm

No worries, got it figured out…

Reply

15 Tomislav December 15, 2007 at 4:43 am

nice and simple. thnx for sharing.

Reply

16 Yev December 16, 2007 at 5:03 pm

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″

Reply

17 Thomas January 6, 2008 at 3:25 am

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

Reply

18 Posin January 9, 2008 at 12:26 am

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

Reply

19 peterd January 9, 2008 at 1:04 am

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

Reply

20 Website Development India January 9, 2008 at 3:06 am

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

Reply

21 Yev Belman January 23, 2008 at 9:51 pm

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”

Reply

22 vijith February 6, 2008 at 9:27 pm

how can we put an icon in to context menu

Reply

23 hsTed February 24, 2008 at 11:27 am

nice example. this helped a lot!

Reply

24 Ravi March 11, 2008 at 7:30 am

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?

Reply

25 peterd March 11, 2008 at 2:05 pm

Ravi,

I believe the addSubmenu() method is for AIR applications only.

Peter

Reply

26 sanpat April 7, 2008 at 6:44 am

if we can not remove default context menus like “setting..” its a main problem

Reply

27 Chucuán April 14, 2008 at 10:24 am

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.

Reply

28 Guru April 17, 2008 at 2:33 am

Good work.found it very useful. But did any one try putting more than one options in the context menu?

Reply

29 Art Van Ronk June 5, 2008 at 9:57 am

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.

Reply

30 Mark July 2, 2008 at 2:57 pm

What this line is for?
cm.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelect);

Reply

31 Ryan August 21, 2008 at 1:59 pm

I read that the ContextMenu API does not support submenus. They actually said that was its biggest drawback.

Reply

32 Adrien October 1, 2008 at 9:10 am

Is it possible to put an icon next the ContextMenuItem?
Usually it’as V to show the option is activated.

thanks

Adrien

Reply

33 OutSkiing October 14, 2008 at 5:17 pm

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.

Reply

34 dhileep November 14, 2008 at 4:15 am

Many thanks for your code

Reply

35 kannan March 10, 2009 at 5:21 pm

This example was really good.

Thanks for posting

Reply

36 Flex Freelancer March 27, 2009 at 1:40 pm

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.

Reply

37 RajPrabha April 26, 2009 at 12:12 am

Great example.
But it is not working in air
Anybody having solution for this?

Reply

38 RajPrabha April 26, 2009 at 1:07 am

Try this Rahul..It’s working

Reply

39 RajPrabha April 26, 2009 at 9:49 pm

Sorry..forgot to send the link
http://kuvempu.wordpress.com/context-menu-in-air/
Try this

Reply

40 om June 30, 2009 at 2:34 am

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 ?

Reply

41 Sean July 14, 2009 at 10:25 am

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:

private function init():void {
            var cmiView:ContextMenuItem = new ContextMenuItem("View Member Information...", true);
            cmiView.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, cmiViewRecord);
            var cmiEdit:ContextMenuItem = new ContextMenuItem("Edit Member Information...", true);
            cmiEdit.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, cmiEditRecord);
 
            cm = new ContextMenu();
            cm.hideBuiltInItems();
            cm.customItems = [cmiView,cmiEdit];
            cm.addEventListener(ContextMenuEvent.MENU_SELECT, contextMenu_menuSelect);
}
 
private function cmiEditRecord(event:ContextMenuEvent):void {
        	var theSource:String = "MemberProfile.cfm?ID=" +     
                                    resultsArray[memberGrid.selectedIndex].MEMBER_ID;
        	var urlToNav:URLRequest = new URLRequest(theSource);
        	navigateToURL(urlToNav,"_self");
}
 
private function cmiViewRecord(event:ContextMenuEvent):void {
        	Application.application.showMemberView(resultsArray[memberGrid.selectedIndex].MEMBER_ID);
 }
 
private function contextMenu_menuSelect(evt:ContextMenuEvent):void {
            memberGrid.selectedIndex = lastRollOverIndex;
}

And of course my grid

Thanks again for your generosity

Reply

42 sam November 16, 2009 at 1:31 am

is it possible to customize the right click menu of an application not a grid?
Thanks

Reply

43 sam November 16, 2009 at 1:39 am

don’t bother found it, i had to add contextMenu=”{cm}” to the application instead of the grid

Reply

44 SenorPlankton November 19, 2009 at 6:36 am

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.

Reply

45 oluwaseun December 8, 2009 at 4:36 am

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.

Reply

46 oliver December 13, 2009 at 7:42 am

a really simple and good working solutionfor this problem … once more thanx

Reply

47 Tim Romano December 15, 2009 at 6:21 am

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.

Reply

48 Peter deHaan December 15, 2009 at 6:57 am

@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

Reply

Leave a Comment

Sorry, this blog is terrible at eating HTML comments.
If you're pasting any HTML/XML/MXML code, you need to convert your < characters to &lt; and your > characters to &gt; .

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: