How to Add a Facebook Style Sliding Menu in Sencha Touch

6 min read

Originally published May 16, 2014

Sliding menus in mobile applications have been popularised by Facebook's addition of a sliding menu to their mobile app. Although Facebook has since moved away from the sliding menu approach as the main form of navigation, in favour of a tabbed approach, the popularity of the sliding menu remains.

I've been a big fan of using Swarnendu's (one of the experts I was fortunate enough to interview for my beginners guide) 'Slide navigation with Sencha Touch', and this is what I primarily used in the past. Sencha have since come out with their own menu class that makes it a lot easier to implement, as well as providing some nice additional features such as the ability to swipe to close the menu and easily dock the menu to any side of the screen.

In this post, we're going to take a look at how to implement the 'Ext.Menu' class.

Getting Started with Slide Navigation

As always, it's a good idea to take a look at the documentation for the class. Here you will find a simple example, and the first thing you will probably notice is that this menu is using buttons for its items. Buttons are the default type for the menu but we are not limited to using just buttons, in this example we're going to build a sliding menu that uses a list.

Below you will find the entire code for the 'Main' view that we are creating the menu in. I'm showing you this now so you can see how everything pieces together and then we'll talk about it bit by bit.

Ext.define('example.view.Main', {
  extend: 'Ext.Container',
  requires: ['Ext.Menu', 'Ext.dataview.List'],
  xtype: 'main',
  config: {
    layout: 'card',
    items: [
      {
        xtype: 'toolbar',
        docked: 'top',
        title: 'Sliding Menu',
        items: [
          {
            xtype: 'button',
            iconCls: 'list',
            ui: 'plain',
            handler: function () {
              if (Ext.Viewport.getMenus().left.isHidden()) {
                Ext.Viewport.showMenu('left');
              } else {
                Ext.Viewport.hideMenu('left');
              }
            },
          },
        ],
      },
    ],
    listeners: {
      initialize: function () {
        Ext.Viewport.setMenu(this.createMenu('left'), {
          side: 'left',
          reveal: true,
        });
      },
    },
  },
  createMenu: function (side) {
    var items = [
      {
        xtype: 'list',
        itemTpl: '{title}',
        width: 200,
        height: '100%',
        scrollable: false,
        data: [
          { title: 'Item 1' },
          { title: 'Item 2' },
          { title: 'Item 3' },
          { title: 'Item 4' },
        ],
      },
    ];
    return Ext.create('Ext.Menu', {
      style: 'padding: 0',
      items: items,
    });
  },
});

First, you have to make sure to require the 'Ext.Menu' class with:

requires: ['Ext.Menu', 'Ext.dataview.List'],

Although we can do this directly within the setMenu function, we create a separate 'createMenu' function which defines our menu as follows:

createMenu: function(side){
    var items = [
        {
            xtype: 'list',
            itemTpl: '{title}',
            width: 200,
            height: '100%',
            scrollable: false,
            data: [
                {title: 'Item 1'},
                {title: 'Item 2'},
                {title: 'Item 3'},
                {title: 'Item 4'}
            ]
        }
    ];
    return Ext.create('Ext.Menu', {
        style: 'padding: 0',
        items: items
    });
}

Here you can see that we're specifying one menu item, which is a list. This list then contains four records which we are using as menu items. Since the list is acting as the menu items, we don't want to allow users to scroll it (or, perhaps you do!) so we can just set the scrollable option to false. There is a little configuration required here to make the list play nice with the menu, but you should be able to customise it however you see fit. If you change the width value for example the menu will expand or shrink to fit the contents.

Since our 'createMenu' function creates and returns a new menu, we make use of this when our view is initialised. The 'initialize' function will run when the view is created, so the following code will be triggered immediately:

Ext.Viewport.setMenu(this.createMenu('left'), {
  side: 'left',
  reveal: true,
});

which calls our 'createMenu' function and tells it to set the menu on the left side. Additionally, you could also set it on the right, top, or bottom.

Now that we've added the menu, all that's left to do is control when to show and hide it. To do this, we can add a button to the toolbar to toggle the visibility of the menu:

items: [
    {
        xtype: 'toolbar',
        docked: 'top',
        title: 'Sliding Menu',
        items: [
            {
                xtype: 'button',
                iconCls: 'list',
                ui: 'plain',
                handler: function(){

                    if(Ext.Viewport.getMenus().left.isHidden())
                    {
                        Ext.Viewport.showMenu('left');
                    }
                    else
                    {
                        Ext.Viewport.hideMenu('left');
                    }
                }
            }
        ]
     }

Here we're checking if the left menu is hidden, if it is we want to show the menu, otherwise we want to hide it.

With the addition of the Ext.Menu class, it is now very easy to create your own sliding menus. As always, if you have any questions or comments please feel free to leave them in the comments below.