Our application hasn’t looked very… applicationy up until this point. The menu area was basically a space full with “coming soon”. In this post we will address adding a menu to our HTML app and show how we can pass fire and handle menu click events.
First change I suppose, we need a menu. We will be using the YUI menu plugin MenuNav. If I am honest, it is unweildy compared to some HTML UI widgets I have used in the past, but since we are using YUI, might as well use it for everything.
We make the following changes to mainMenu.Template
<div style="width:100%" class="yui3-skin-sam"> <div id="appmenu" class="yui3-menu yui3-menu-horizontal"><!-- Bounding box --> <div class="yui3-menu-content" ><!-- Content box --> <ul> <li> <a class="yui3-menu-label" href="#file">File</a> <div id="file" class="yui3-menu"> <div class="yui3-menu-content"> <ul> <li class="yui3-menuitem" id="menuFileExit"> <a class="yui3-menuitem-content" href="#">Exit</a> </li> </ul> </div> </div> </li> </ul> </div> </div> </div>
Read the link above for more details about exactly what is going on here. The key things to notice are the id’s for the menu (appmenu) and menu item (menuFileExit), both of those will be used shortly. It is also of key importance to give the containing div the class yui3-skin-sam, as this is what brings in all of the YUI3 css and formatting. You could also add this to the <BODY> tag in editor.View.js, which we may do as we add more YUI controls. Just be aware that a parent node within the DOM needs to have this class declared.
So, that’s is our markup, lets look at the code side of things. Open up and change mainMenu.View.js
YUI.add('mainMenuView',function(Y){ Y.MainMenuView = Y.Base.create('mainMenuView', Y.View, [], { initializer:function(){ var results = Y.io('/scripts/views/templates/mainMenu.Template',{"sync":true}); // No need to compile, nothing in template but HTML // this.template = Y.Handlebars.compile(results.responseText); this.template = results.responseText; }, render:function(){ this.get('container').setHTML(this.template); var container = this.get('container'); var menu = container.one("#appmenu"); menu.plug(Y.Plugin.NodeMenuNav); //Register menu handlers var menuFileExit = container.one('#menuFileExit'); menuFileExit.on("click",function(e){ alert("Publishing"); Y.Global.fire('menu:fileExit', { msg:"Hello" }); }); var menuFileAddSpriteSheet = container.one('#menuFileAddSpriteSheet'); menuFileAddSpriteSheet.on("click", function(e){ Y.Global.fire('menu:fileAddSpriteSheet', {msg:null}); }); return this; } }); }, '0.0.1', { requires: ['view','io-base','node-menunav','event','handlebars']});
Here we changed our initializer to load synchronously as well, otherwise the basics are pretty much the same. Not that we added the ‘node-menunav’ and ‘event’ dependencies to our requires array. Otherwise the key changes are:
var menu = container.one("#appmenu"); menu.plug(Y.Plugin.NodeMenuNav);
This locates our appmenu div and plugs the NodeMenuNav into it, turning our DIV into a YUI3 style menu. Basically this is where the magic happens. Then:
var menuFileExit = container.one('#menuFileExit'); menuFileExit.on("click",function(e){ alert("Publishing"); Y.Global.fire('menu:fileExit', { msg:"Hello" }); });
Next we find our menuFileExit menu item and register an onClick handler for it. When a click occurs we fire a global event named “menu:fileExit”, with a msg of Hello. The name menu:fileExit was chosen by me and can be anything. So, when the user clicks the Exit item in the menu, this event will be fired. Let’s look at how you handle “catching” this event. Open up editor.View.js and at the bottom of the initializer() function, add the following code:
Y.Global.on('menu:fileExit', function(e){ alert(e.msg); });
Basically, this monitors for a menu:fileExit event being fired, and simple alerts the contents. This illustrates a simple way to provide a global menu which can be handled across multiple views.
Here is our project in action now:
Basically, it is exactly the same as before, but now it has a menu.
You can download the complete source code here.
Design Programming