Menu

Menu models the kind of contextual menu that appears when you right-click on an application icon in a desktop environment. A Menu contains MenuItem widgets, which are bona fide menu items that may be selected, or PopupMenuItem widgets, which can provide another layer of menu items (similar to the Windows Start menu). The child of a PopupMenuItem is just another Menu. Although it would not be wise from a usability standpoint, you could theoretically embed an arbitrary number of PopupMenuItem and MenuItem dijits.

To start out, let's take a look at a simple Menu that contains only MenuItem children, as shown in Example 15-4.

Tip

By issuing a dojo.require("dijit.Menu") you also get MenuItem and PopupMenuItem.

Example 15-4. Typical Menu usage

<body class="tundra">
    <!-- right click in here to get the contextual menu -->
    <div id="context" style="background:#eee; height:300px; width:300px;"></div>

    <div dojoType="dijit.Menu" targetNodeIds="context" style="display:none">
        <div dojoType="dijit.MenuItem">foo
            <script type="dojo/method" event="onClick" args="evt">
                console.log("foo");
            </script>
        </div>
        <div dojoType="dijit.MenuItem">bar
            <script type="dojo/method" event="onClick" args="evt">
                console.log("bar");
            </script>
        </div>
        <div dojoType="dijit.MenuItem">baz
            <script type="dojo/method" event="onClick" args="evt">
                console.log("baz");
            </script>
        </div>
    </div>
</body>

Warning

Like Tooltip, the list of values passed in for Menu is a comma-separated string that does not include enclosing brackets that would be required of an ordinary JavaScript Array. A future release may very well standardize this anomaly.

As you can see, there's not much to it, and defining in markup makes matters even simpler. The one emphasized line of code that sets the display to be none is important because it may be the case that your Menu will initially be visible without this cue.

Now, suppose you wanted to make baz be a PopupMenuItem and you wanted the Menu to be contextual for the entire window. You could do it thusly:

<div dojoType="dijit.Menu" style="display:none"contextualMenuForWindow="true">
    <div dojoType="dijit.MenuItem">foo
        <script type="dojo/method" event="onClick" args="evt">
            console.log("foo");
        </script>
    </div>
    <div dojoType="dijit.MenuItem">bar
        <script type="dojo/method" event="onClick" args="evt">
            console.log("bar");
        </script>
    </div>
    <div dojoType="dijit.PopupMenuItem">
        <span>baz</span>
        <div dojoType="dijit.Menu">
          <!-- define onClick handlers as needed for each item -->
            <div dojoType="dijit.MenuItem">yabba</div>
            <div dojoType="dijit.MenuItem">dabba</div>
            <div dojoType="dijit.MenuItem">doo</div>
        </div>
    </div>
</div>

Hopefully, the only remotely tricky part about installing the PopupMenuItem was that there needed to be an explicit node set, its first child to be specific, which provides the title.

To round off this section on Menu, Table 15-6 provides a listing of the remaining API. Note that as a _Container descendant, Menu has token methods for adding, removing, and getting children, just like Toolbar and the others offer. The API for MenuItem and PopupMenuItem are shown in Table 15-7.

Table 15-6. Menu API

Name (default)

Type

Description

contextMenuForWindow

Boolean

(false)

If true, right-clicking anywhere on the window opens the menu. If false, the targetNodeIds parameter should be provided that supplies one or more nodes that can trigger the menu.

popupDelay

Integer

(500)

The number of milliseconds to wait before popping up the Menu after the click event occurs. (An interrupting click that occurs before this duration ends results in the time period resetting and starting over.)

targetNodeIds

Array

([])

A list of the node id values that support this Menu.

parentMenu

Object

(null)

A pointer to the parent Menu, if any.

addChild(/*Object*/ child, /*Integer?*/ insertIndex)

Function

Used to insert a dijit into the Menu.

getChildren( )

Function

Returns an array of the contained dijits in the Menu.

removeChild(/*Object*/ child)

Function

Used to remove a child from the Menu (removes its domNode, but does not destroy the dijit; you must call destroyRecursive( ) manually).

bindDomNode(/*String|DOMNode*/node)

Function

Attaches a Menu to a particular node. (Useful for context menus, for example.)

unBindDomNode(/*String|DOMNode*/node)

Function

Detaches a Menu from a particular node.

onClick(/*Object*/item, /*Event*/evt)

Function

Extension point designed to handle clicks.

onItemHover(/*MenuItem*/item)

Function

Called when the cursor hovers over a MenuItem.

onItemUnhover(/*MenuItem*/item)

Function

Called when the cursor ends a hover over a MenuItem.

onCancel( )

Function

Extension point for handling when the user cancels the current Menu.

onExecute( )

Function

Extension point for handling when the user executes the current Menu.

Table 15-7. MenuItem and PopupMenuItem API

Name (default)

Type

Description

label

String

The text that should appear in the MenuItem.

iconClass

String

The class to apply to make the MenuItem appear as an icon (use background-image in CSS).

disabled

Boolean

Specifying whether the MenuItem is disabled. false by default.

setDisabled(/*Boolean*/ value)

Function

Programatically control whether the MenuItem is disabled.

onClick(/*DomEvent*/ evt)

Function

Used for attaching click handlers on the MenuItem.

Get Dojo: The Definitive Guide now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.