PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

Dynamic Toolbar Menus with ExtJS + PHP

Note: This article was originally published at Planet PHP on 17 April 3560.
Planet PHP

In Ext JS 4 there's some handy things that come bundled with it (there's lots of stuff actually - it's a pretty large library). Recently, though, I needed to pull in navigation information from a remote source (JSON output from a PHP script). Thankfully, Ext still made this pretty easy with its Toolbar and Menu components with their listeners. Here's my example code:

Ext.create('Ext.toolbar.Toolbar', { floating: false, id: 'menuToolbar', cls: 'appMenu', height: 30, items: [], // dynamically built below listeners: { beforerender: function() { var navStore = Ext.create('Ext.data.Store', { fields: ['text'], proxy: { type: 'ajax', url: '/path/to/navigation-output', reader: { type: 'json', root: 'navigation' } }, autoLoad: true, listeners: { load: function(store,records,success,operation,opts) {var toolbar = Ext.getCmp('menuToolbar'); // First the top level items store.each(function(record) { var menu = Ext.create('Ext.menu.Menu'); Ext.each(record.raw.menu, function(item){ menu.add({ text: item.text }) }) toolbar.add({ xtype: 'button', text: record.data.text, menu: menu }); }); } } }); } } });

Then the PHP to make the output is pretty easy (slightly simplified here):

array('text' = 'Option #1', 'menu' = array(array('text' = 'Foo'), array('text' = 'Bar'), array('text' = 'Baz')))); ?

Now - a little explaination of what we're doing here:

  1. In Ext, we create a generic Toolbar object - this is what's going to contain the aobuttonsa that act as the top level menu.
  2. There's a few config options (like an ID, height and a custom class to apply) but the key is in the aolistenersa section. This is where Ext looks to for events on the objects. In our case, we're telling it to, on the aobeforerendera event, call this given inline method. This method then makes our store.
  3. For those not familiar with the ideas of aostoresa, think of them as Javascript-based database tables (kinda). They pull in data from some source or can be manually populated in memory to prevent you from having to go back and fetch the data every time you need it. in our case, we just make a basic one (Ext.data.Store) that is set up with a proxy to pull from the JSON source (our /path/to/navigation-output). With the aoautoLoada property set to aotruea it automatically pulls in the JSON as soon as it's created.
  4. You'll see that we've, once again, tapped into the aolistenersa, this time for the store. Our aoloada listener fires when the store data is completely loaded. In here is where we're going to add our elements into the Toolbar.
  5. As one of the options, we get the current store back and we use it to loop through and get each of the records. Each of these top level records is going to be one of our Toolbar buttons, each with its own menu. You can see as we loop through them, we create an aoExt.menu.Menua object adding the aotexta value to it. This menu is then appended to the button via the aomenua property on the button. The aoadda is called again on the button config and it's dropped into the Toolbar.

The fun thing about this is that it makes a reusable component that you can use across products/sites without having to hard-code the navigation options into the actual code. There's probably a simpler way to do this, but this one seemed to make the most sense to me.