Create a Context Menu with Dojo and Dijit

By  on  
Dojo Context Menu

Context menus, used in the right type of web application, can be invaluable.  They provide shortcut methods to different functionality within the application and, with just a right click, they are readily available.  Dojo's Dijit frameworks provides an easy way to create stylish, flexible context menus in just minutes.

The Dojo JavaScript

/* require necessary classes */
dojo.require('dijit.Menu');
dojo.require('dijit.MenuSeparator');
dojo.require('dijit.MenuItem');
dojo.require('dijit.PopupMenuItem');

The above requires the necessary widget classes that will be used in the context menu.

The Context Menu HTML

<-- menu container -->
<div dojoType="dijit.Menu" id="submenu1" contextMenuForWindow="true" style="display:none;">

	<-- enabled menu item -->
	<div dojoType="dijit.MenuItem" id="enabledItem" onClick="Clicked enabled item!">Enabled Item</div>
	
	<-- disabled menu item -->
	<div dojoType="dijit.MenuItem" disabled="true">Disabled Item</div>
	
	<-- separator -->
	<div dojoType="dijit.MenuSeparator"></div>
	
	<-- menu items with icons -->
	<div dojoType="dijit.MenuItem" iconClass="dijitIconCut"
		onClick="alert('Cutting!')">Cut</div>
	<div dojoType="dijit.MenuItem" iconClass="dijitIconCopy"
		onClick="alert('not actually copying anything, just a test!')">Copy</div>
	
	<div dojoType="dijit.MenuSeparator"></div>
	
	<-- nested popup menus with items -->
	<div dojoType="dijit.PopupMenuItem">
		<span>Enabled Submenu</span>
		<div dojoType="dijit.Menu" id="submenu2">
			<div dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</div>
			<div dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</div>
			<div dojoType="dijit.PopupMenuItem">
				<span>Deeper Submenu</span>
				<div dojoType="dijit.Menu" id="submenu4">
					<div dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 1!')">Sub-sub-menu Item One</div>
					<div dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 2!')">Sub-sub-menu Item Two</div>
				</div>
			</div>
		</div>
	</div>
	
	<-- popup menu with disabled item -->
	<div dojoType="dijit.PopupMenuItem" disabled="true">
		<span>Disabled Submenu</span>
		<div dojoType="dijit.Menu" id="submenu3" style="display: none;">
			<div dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</div>
			<div dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</div>
		</div>
	</div>
</div>

The menu is based on a system of nested DIV elements.  The top element is a dijit.Menu widget with child dijit.MenuItem widgets.  You may also add a dijit.MenuSeparator widget or a dijit.PopupMenuItem widget with child dijit.MenuItem widgets to create a popup menu.  You may disable menu items with "disabled='true'" declaratively or by using JavaScript:

dijit.byId('enabledItem').attr('disabled','true');

So simple! Context menus may also be created programmatically, but the declarative method of widget creation speeds up development.

This is just another way that Dojo's Dijit framework allows you to quickly create a functional UI widget in minutes!

Recent Features

  • By
    Create a CSS Cube

    CSS cubes really showcase what CSS has become over the years, evolving from simple color and dimension directives to a language capable of creating deep, creative visuals.  Add animation and you've got something really neat.  Unfortunately each CSS cube tutorial I've read is a bit...

  • By
    Responsive Images: The Ultimate Guide

    Chances are that any Web designers using our Ghostlab browser testing app, which allows seamless testing across all devices simultaneously, will have worked with responsive design in some shape or form. And as today's websites and devices become ever more varied, a plethora of responsive images...

Incredible Demos

  • By
    jQuery Random Link Color Animations

    We all know that we can set a link's :hover color, but what if we want to add a bit more dynamism and flair? jQuery allows you to not only animate to a specified color, but also allows you to animate to a random color. The...

  • By
    Printing MooTools Accordion Items

    Sometimes we're presented with unforeseen problems when it comes to our JavaScript effects. In this case, I'm talking about printing jQuery and MooTools accordions. Each "closed" accordion content element has its height set to 0 which means it will be hidden when the...

Discussion

  1. Tim

    Looks smooth! Can’t wait for mootools Art to do this kind of stuff.

  2. Hi David, thanks for the look at dojo’s context menu capability. The problem I’m having is I can’t seem to find any hooks to make the menu actually contextual.

    If I create a table with 100 records in it, and then want a context menu that will contain links specific to the record I right click on, I would have to create a div based menu for each and every record on the page. That’s a lot of overhead for something that should be relatively simple.

    I would say that this should be accomplished by only nesting certain parameters/attributes in each row, only creating a single div menu structure and then passing those attributes to the menu each time it’s invoked.

    From what I’ve seen this is not possible with Dojo, but I would REALLY like to be proven wrong!

    • Michael Holly

      Kevin

      I worked out some of the context menu stuff. In the oncontextmenu I call a doEvt(event) function. In that function I set a var equal to the e.target value. This is the object that got clicked on. My problem is that I have set my context menus up with following line…

      pMenu = new dijit.Menu({ targetNodeIds: [“reportpage”] });

      Unfortunately this only seems to work with the initial reportpage and none after that. Not sure what I am going to do. I would like to use this Menu but I may have to roll my own.

    • Michael Holly

      After further examination it appears that the use of the domNodeId as the driver for where the context menu pops up is difficult. Does this scale for a page with 4000 records? I would think doing a dojo query and passing the result should power the dijit.Menu constructor. That way all the records could have a particular styling and also the same context menu behavior tied by just a css name. Having to pass an array of unique DOM ids makes this constructor difficult to use.

    • You could set up a system of event delegation and connect the node that’s clicked when as its clicked. That saves the need to connect to multiple or create many menus.

  3. Miguel

    How can you use the functionality of another dijit in a right click? For example selecting a row right a right click within an Enhanced grid? How do I find the method within enchancedgrid that does the selecting? Does that go in the declaration of the new Menu object?

  4. lemon

    April 5 2016, chrome 49.0.2623.110 (64-bit), mac osx 10.11;
    Does not work.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!