Ext JS - Learning Center

Tutorial:Ext Menu Widget

From Learn About the Ext JavaScript Library

Jump to: navigation, search
Summary: A look at how to use the Ext Menu widget.
Author: Tommy Maintz
Published: March 11, 2007
Ext Version: 1.1
Languages: en.png Englishcn.png Chinese

In this tutorial we will have a closer look at the Ext Menu widget. We assume you already read the Introduction to Ext tutorial. If not, you might want to begin reading that first. The Menu widget is one of the latest additions to the Ext library. It consists of several classes, which together will make it able to build a menu with just a small block of code.

Contents

Let's Get Started

First you should download the files coming with this tutorial. You can get the zip file here. The zip file contains four files: ExtMenu.html, ExtMenu.js, ExtMenu.css and list-items.gif. Unzip all four files into a folder directly under the folder where Ext is installed (for example, if Ext is at "C:\code\Ext\v1.0," create a new folder under "v1.0" called "menututorial"). We will use these files to build a page containing different types of menus. Double click ExtMenu.html to open the page in your default web browser. You should get a message telling you that everything is configured correctly. If you get a javascript error, please follow the instructions on that page to get it working.

Now we are ready to open ExtMenu.js in your favorite IDE or text editor and take a look at it:

Ext.onReady(function() {
    alert('You have Ext configured correctly!');
});

In the Introduction to Ext tutorial we discussed the Ext.onReady() method and why we should use it.

A Basic Menu

Let's start immediately with adding the code to build a basic menu. Afterwards we will discuss the different concepts and components used in the code. Add the following to the onReady function:

var menu = new Ext.menu.Menu({
    id: 'basicMenu',
    items: [{
            text: 'An item',
            handler: clickHandler
        },
        new Ext.menu.Item({
            text: 'Another item',
            handler: clickHandler
        }),
        '-',
        new Ext.menu.CheckItem({
            text: 'A check item',
            checkHandler: checkHandler
        }),
        new Ext.menu.CheckItem({
            text: 'Another check item',
            checkHandler: checkHandler
        })
    ]
});
 
var tb = new Ext.Toolbar('toolbar', [{
        text:'Our first Menu',
        menu: menu  // assign our menu to this button
    }
]);
 
function clickHandler() {
    alert('Clicked on a menu item');
}
 
 function checkHandler() {
    alert('Checked a menu item');
}

Ok, so let's have a closer look at what is happening here. First we are assigning a new Menu class to the variable 'menu'. The Menu constructor expects an object literal as parameter. We remember this pattern from the Introduction to Ext tutorial. This object literal contains all the properties we want the menu to have. The first property we assign is the menus id. We can use this id to get a reference to the menu later.

The Different Types of Items

The second property named 'items' is probably the most important one. If you look at the syntax you will see that we pass an array as value to this property. The array is filled with all the items we want the menu to have. In our example we filled it with six of them. But what's up with the different syntax we used for the items? The first one is an object literal. It contains different name/value pairs we can use to configure the item. The underlying Ext library will create a new Item object using this object literal as it's configuration by default. The second item in the array is an Item object we created ourself. Then there is a separator, and last two are check items. This shows how dynamically all the Ext widgets work. The following lists all the available items you could fill the array with:

{text: 'Foo'}                       // Ext converts this to a standard Menu Item 
                                    // using this object as the config
'Straight Text'                     // text or raw html shown in the menu (just 
                                    // text so no event handlers or other options)
'-'                                 // creates a separator
new Ext.menu.Item({text: 'Foo'})    // creates a standard Menu Item (same as {text: 'Foo'})
new Ext.menu.CheckItem()            // creates a check item
new Ext.menu.DateItem()             // creates a date picker inside the menu
new Ext.menu.ColorItem()            // creates a color picker
new Ext.menu.BaseItem('my-div')     // you can add any element by id

Item Properties

What types of properties does an Item expect? In our example we see two of them being used:

text: 'An item',
handler: clickHandler

The first one is the text the item contains, and the second one is the event handler function used when the user clicks on the item. In our case these are the functions clickHandler() and checkHandler() wich we define at the end of our code. It just shows the user a simple alert() with a message saying they clicked on a menu item (as if they didn't know). In real projects you would probably want to do something more useful, but this shows you the concept.

Other usefull properties are:

cls: 'a-class-name' ,    // style the item or change the icon via CSS
icon: 'url',             // set the icon url without CSS
group: 'group name',     // only available for radio items to ensure only one...
                         // option in the group can be checked

For a complete list of the properties the items can have, check out the <a href="/docs">Menu Item Documentation</a>.

Placing the Menu in the UI

So, we created a Menu object containing two basic items. But where do we want our menu to be in the page? A menu can be assigned to different places inside a UI. This is exactly why the Ext library is so powerful. Every widget is split into several classes to create an extemely dynamic object orientated structure. This means that we can use the menu we just made for multiple purposes. We can assign the menu to a button inside a toolbar. Or we could use the same menu to show up when the user clicks on a button anywhere in the page. We could also use the menu as a context menu for other widgets in the Ext library, for example as a context menu in the grid or tree components.

In our case we are assigning the menu to a toolbar. This is done like this:

var tb = new Ext.Toolbar('toolbar', [{
        text:'Our first Menu',
        menu: menu  // assign our menu to this button
    }
]);

The Ext.Toolbar constructor expects two parameters, the first one being the container in which the toolbar will be created. In the ExtMenu.html file there already is a div element with the id 'toolbar'. This is the only actual markup we need to create a complete Toolbar with Menu's assigned to it. The second parameter is an array containing all the buttons in the toolbar. For now, we will only use one button. As you can see, a button is defined by putting another object literal inside the array. This object literal can contain different properties aswell. Here is a list of some of the properties a button object literal can have:

cls: 'a-class-name'  ,      // style the button or change the icon via CSS
icon: 'url',                // set the icon url without CSS
text:'Our first Menu',      // the text on the button
menu: menu                  // assign our menu to this button (can also be...
                            // a menu id or menu object config blob)

Different Ways of Assigning the Menu

In the previous section we saw how to assign the menu to the toolbar button. The comment says something about different types of assigning the menu. Let's go further into the details of this. So, the menu property can be assigned in different ways. You can pass it the menu object, the id of an already created menu, or a complete menu object config blob! You should really try to learn these different ways of building the menu, cause it works like this for almost every widget in the Ext library. The following piece of code shows you how to create the menu in our example in a completely different, but functionally similar way using a menu object config blob. We added two submenus, one containing a DateItem, the other a ColorItem, to the menu. Also note that in the event handling functions we get passed two parameters we can use to find out more things about the event and item or menu clicked on! If you like you can add the code to our examples onReady function to check it out yourself!

var dateMenu = new Ext.menu.DateMenu({
    handler : function(datepicker, date){
        alert('Date Selected', 'You chose: '+ date.format('M j, Y'));
    }
});
 
var colorMenu = new Ext.menu.Menu({
    id: 'colorMenu', // the menu's id we use later to assign as submenu
    items: [
        new Ext.menu.ColorItem({
            selectHandler: function(colorpicker, color){
                alert('Color Selected', 'You chose: ' + color);
            }
        })
    ]
});
 
var tb = new Ext.Toolbar('toolbar', [{
        text:'Our first Menu',
        menu: {
            id: 'basicMenu',
            items: [{
                    text: 'An item',
                    handler: clickHandler
                }, {
                    text: 'Another item',
                    handler: clickHandler
                },
                '-',
                new Ext.menu.CheckItem({
                    text: 'A check item',
                    checkHandler: checkHandler
                }),
                new Ext.menu.CheckItem({
                    text: 'Another check item',
                    checkHandler: checkHandler
                }),
                '-', {
                    text: 'DateMenu as submenu',
                    menu: dateMenu, // assign the dateMenu object by reference
                    handler: date
                }, {
                    text: 'Submenu with ColorItem',
                    menu: 'colorMenu' // assign the colorMenu object by id
                }
            ]
        }
    }
]);
 
function clickHandler(item, e) {
    alert('Clicked on the menu item: ' + item.text);
}
 
function checkHandler(item, e) {
    alert('Checked the item: ' + item.text);
}

Note: look at the different methods used to add the submenus! Also check out the event handling functions and the anonymous functions used for the ColorItem and DateMenu.

More Practices

Ok, so we created a Menu, added items to it, and assigned it to a button in a Toolbar. We looked at multiple methods and syntaxes to create our menu. Our page looks something like this now:

Image:ToolbarWithMenus.gif

But earlier we said a menu could be used in different places in your UI. So how does that work, you might ask. We will now show you more things you can do using Toolbars, MenuButtons, context menu's, including usefull methods for dynamically adding stuff to our component.

A MenuButton

Here we assign the menu to a MenuButton. Try to add this in our page!

new Ext.MenuButton('menubutton', {text:'Menu Button 1', menu: dateMenu});

Dynamically Adding Buttons with Menus to a Toolbar

Here we add two buttons to our Toolbar. A seperator, and an icon-only button with a quicktip. Try if you can manage to do this. We added the used .gif to the zip

Ext.QuickTips.init();
 
tb.add('-', {
    icon: 'list-items.gif', // icons can also be specified inline
    cls: 'x-btn-icon',      // the class for a button with an icon
    tooltip: '&lt;b&gt;Quick Tips&lt;/b&gt;&lt;br /&gt;Icon-only button with tooltip'
});

More Handy Stuff

Some more snippets. Read the comments carefully!

// Menus have a rich api for
// adding and removing elements dynamically
 
menu.addSeparator(); //dynamically add a separator to a menu.
 
var item = menu.add({
    text: 'Dynamically added Item'
});
 
// items support full Observable API
item.on('click', onItemClick);
 
// items can easily be looked up
menu.add({
    text: 'Disabled Item',
    id: 'disableMe'    // <-- Items can also have an id for easy lookup
    // disabled: true   // <-- allowed but for sake of example we use long way below
});
 
// access items by id or index
menu.items.get('disableMe').disable();

If you need to call a javaScript function with a parameter use the createDelegate to pass the parameters

Example:

var ratesMenu = new Ext.menu.Menu({});
ratesMenu.add({text:'FCL Rates',tooltip:'FCL',handler:display_report.createDelegate(this, ['fclrates'])});
ratesMenu.add({text:'LCL Rates',handler:display_report.createDelegate(this, ['lclrates'])});
 
// ...
 
function display_report(report) {
    alert(report);
}

It took me a while and thanks to Joseph aka Saki I was able to figure it out -- I thought this is something rather basic many others probably struggle with as well - I hope this helps

Screencast

A look at how to use the Ext Menu widget. This tutorial was contributed by Ext community member Tommy Maintz. Watch Now.

What's Next?

Now that you've had a look at how the Menu component works, there are many resources available to help you really dive deeper into the menus

  • This page was last modified 18:39, 2 October 2007.
  • This page has been accessed 27,521 times.