Skip to content

April 11, 2011

4

An enhanced version of Ext.ux.menu.StoreMenu

by Joe Kuan

The StoreMenu is a dynamic menu using ExtJS Store class to retrieve and expand the menu items from the server side. It is a very useful utility class. For usage and technical detail, you can refer to the forum. However, there are a number of areas I think it can be improved which are

  1. menu item’s handler function should not necessary return from the server side.
  2. since it is extended from Ext.menu.Menu which should be also capable of adding buttons as well as loading & add menu items from the Store.
  3. related to no.2, if the StoreMenu handles both menu buttons & dynamic menu items, the users should be able to assign where (offset) dynamic items to expand in respective to the static items.
  4. Dis/Enable to load from Store every time when the menu is expanded.

Download

You can download this from github.

1. Menu button’s handler function

According to the usage of StoreMenu, the handler function is returned from the server side. In my humble opinion, I think this is not necessary:

  • Writing PHP to output Javascript code is cumbersome
  • Difficult to debug
  • Since the menu items are from the same storage which implies they are likely to share the same domains but simply with different id values. If that is the case, a single body of handler function code should be sufficient for all these menu items.

For this version of StoreMenu, users can define a single handler function on the client side for all the menu buttons. Assume the server returns the following JSON string:

[ {
    text: 'item 0',
    id: 'menu_item,0'
   }, {
    text: 'item 1',
    id: 'menu_item,1',
    handler: 'function(button) { alert("menu handler from server side (1)"); }'
   }, {
    text: 'item 2',
    id: 'menu_item,2'
}]

The id field will be instantiated as ExtJS Component’s id field. Then we can define a handler function to extract the id value. The handler function can be either defined with config

var storeMenu = new Ext.ux.menu.StoreMenu({
    ....
    itemsHandler: function(button) {
      var but_id = button.getId();
      var idArr = but_id.split(',', 2);
      var itemId = idArr[1];
      alert('From itemsHandler: menuitem_' + itemId);
    },
    ...
});

Or by function call,

storeMenu.setItemsHandler(
   function(button) {
      .....
   }
);

Here is a screenshot of handler assigned by setItemsHandler.

Specific handler function

If one of the items requires specific handler, then you can either output the javascript code from the server side (like in the original version). This will override the handler definition assigned by setItemsHandler. Or use switch statement on the client handler method to switch between id or other properties values.

Note that: since the menu items (Ext.Button) are created from whatever configurations returned from the server side. You can add your own property values.

2 & 3, Buttons and StoreMenu items

Since the StoreMenu class is extended from Ext.menu.Menu which can contain various type of components, therefore the StoreMenu should be able to. The original implementation removes all the entries inside the StoreMenu object when the internal Store object is loaded, (removeAll method). I have changed the StoreMenu, so that it only removes items from the internal Store when reloading.

On using with other components, you can assign where the dynamic menus starting to display. The following shows you how to make StoreMenu working with other components:

var storeMenu = new Ext.ux.menu.StoreMenu({
   ....
});
storeMenu.add({ text: 'Add bookmark', ... });
storeMenu.add({ text: 'Edit bookmarks', ... });
storeMenu.add('-');
// Set the Store items to appear after the separator
storeMenu.setOffset(3);

Here is a screenshot of a single StoreMenu

The default offset value is 0, ie menu items from the store will appear before other components.

4. Automatic reload

You can enable or disable to reload the menu items every time when the StoreMenu is expanded. Default is false

var storeMenu = new Ext.ux.menu.StoreMenu({
   ...,
   autoReload: true,
});
Advertisements
4 Comments Post a comment
  1. Jun 23 2011

    Thanks for good modification. I had a problem when using two instances of menu from the same store (each had items with the same “id” values). It looks that changing name of “id” key to anything else helped – I’ve changed it to “info”.

    Reply
  2. Gloria
    Aug 19 2011

    Hola, podrias enviar un ejemplo es que no he podido implementar el widget.
    Gracias.

    Reply
    • Joe Kuan
      Aug 19 2011

      lo siento, estoy de vacaciones esta semana. Voy a tratar de crear un ejemplo algún tiempo la próxima semana

      Reply
  3. Andres
    Jun 5 2012

    Podrias mandar el ejemplo que no funciona la implementacion .

    MIl gracias

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments

%d bloggers like this: