Global Navigation Made Easy with Event Listening
From Gaia Framework Wiki
Contents |
Overview
This lesson demonstrates how to use the power of the Gaia event engine to build a global navigation for your site. Make sure you read the Events and Hijacking documentation first.
Global navigation typically enables users to go to the primary pages of a site and also displays the current section the user is viewing.
One of the challenges Flash developers face with global navigation is if the site is told to go to a different page without using the buttons in the global navigation. The global navigation still needs to display what page is currently selected. Additionally, if a user deep links into the site to a specific page, the global navigation needs to set the selected state of the button for the current section, as well.
Without Gaia, the techniques for doing this are varied, but most of them require hooking into the global navigation clip from elsewhere, either through global references, global functions, watchers or explicit listeners. It's definitely not fun or easy.
Using the Gaia event system makes handling this functionality easy and simple to code because Gaia handles most of the work for you.
Site XML
Here is the site.xml for the example site for this lesson.
<site title="Gaia Framework Site: %PAGE%" menu="true">
<page id="index" src="index.swf">
<page id="nav" src="nav.swf" depth="top">
<page id="home" title="Home" src="home.swf" menu="true" />
<page id="services" title="Services" src="services.swf" menu="true" />
<page id="contact" title="Contact" src="contact.swf" menu="true" />
</page>
</page>
</site>
Navigation Page
I need a button for each of the main pages on the site. Each of these buttons has three states, up, over and selected. For this example, I'm using a MovieClip symbol with three frames labeled "_up", "_over" and "selected".
Let's take a look at the constructor for the NavPage Class.
AS2
public function NavPage()
{
super();
_alpha = 0;
initButtons();
}
AS3
public function NavPage()
{
super();
alpha = 0;
initButtons();
}
In the constructor of the NavPage class, I call initButtons() which is explained below.
Coding The Buttons
The function called initButtons() sets up the button code.
On each of the buttons I assign a "branch" attribute, which is the valid branch associated with each button. I also create an Array of the buttons and assign an onRelease method for each one that calls Gaia.api.goto() with the button's branch property.
Finally, I set an afterGoto Gaia Event listener and call updateButtonStates(Gaia.api.getCurrentBranch()) which will be explained below.
AS2
private var buttons:Array;
public var BTN_Home:MovieClip;
public var BTN_Services:MovieClip;
public var BTN_Contact:MovieClip;
//
public function initButtons():Void
{
BTN_Home.branch = "index/nav/home";
BTN_Services.branch = "index/nav/services";
BTN_Contact.branch = "index/nav/contact";
buttons = [BTN_Home, BTN_Services, BTN_Contact];
var i:Number = buttons.length;
while (i--)
{
buttons[i].onRelease = function()
{
Gaia.api.goto(this.branch);
};
}
Gaia.api.afterGoto(Delegate.create(this, onAfterGoto));
updateButtonStates(Gaia.api.getCurrentBranch());
}
In AS3, it's identical, with the exception of how you handle the button click (you use a MouseEvent.CLICK listener), and setting buttonMode = true.
AS3
private var buttons:Array;
public var BTN_Home:MovieClip;
public var BTN_Services:MovieClip;
public var BTN_Contact:MovieClip;
//
public function initButtons():void
{
BTN_Home.branch = "index/nav/home";
BTN_Services.branch = "index/nav/services";
BTN_Contact.branch = "index/nav/contact";
buttons = [BTN_Home, BTN_Services, BTN_Contact];
var i:int = buttons.length;
while (i--)
{
buttons[i].buttonMode = true;
buttons[i].mouseChildren = false;
buttons[i].addEventListener(MouseEvent.CLICK, onClick);
}
Gaia.api.afterGoto(onAfterGoto);
updateButtonStates(Gaia.api.getCurrentBranch());
}
private function onClick(event:MouseEvent):void
{
Gaia.api.goto(MovieClip(event.target).branch);
}
Notice that there is no code on the buttons themselves that sets them to selected and deselects the others when you click them. This is because the onAfterGoto event listener handles that for us whether it originates here, from the browser, or another button elsewhere in the site, including the right-click menu navigation.
The onAfterGoto Listener
Here is the onAfterGoto listener function, which calls the updateButtonStates function, passing the event.validBranch. They're nearly identical in AS2 and AS3, except AS3 uses int instead of Number.
AS2
private function onAfterGoto(event:GaiaEvent):Void
{
updateButtonStates(event.validBranch);
}
private function updateButtonStates(branch:String):Void
{
var i:Number = buttons.length;
while (i--)
{
var btn:MovieClip = buttons[i];
if (branch != btn.branch)
{
btn.enabled = true;
btn.gotoAndStop("_up");
}
else
{
btn.gotoAndStop("selected");
btn.enabled = false;
}
}
}
AS3
private function onAfterGoto(event:GaiaEvent):void
{
updateButtonStates(event.validBranch);
}
private function updateButtonStates(branch:String):void
{
var i:int = buttons.length;
while (i--)
{
var btn:MovieClip = buttons[i];
if (branch != btn.branch)
{
btn.enabled = true;
btn.gotoAndStop("_up");
}
else
{
btn.gotoAndStop("selected");
btn.enabled = false;
}
}
}
When the afterGoto event occurs, the event parameter contains a property called validBranch. We pass this branch to the updateButtonStates function. This also happens at the end of the initButtons() function, passing the current branch of the site, so the buttons are immediately set to the proper state when you deeplink into the site.
In updateButtonStates(), we iterate through the buttons array and compare each button's branch with the branch passed. If it is not a match, we enable the button and set it back to its "_up" frame. If it is a match, we send the button to its "selected" frame and disable it.
You can test this functionality by clicking the buttons, using the right-click menu, or using the back/forward buttons in the browser. You will see the buttons select and deselect as you navigate through the site.
Conclusion
That's all there is to it. Whenever a navigation event occurs, the global navigation manages itself simply by listening to the afterGoto event from Gaia. It doesn't matter where the navigation event originated, the afterGoto listener ensures that the event is always handled correctly.
This simple technique can be built upon for global navigation which is more complicated, such as a tree-menu with subsections. What you do in your listener function is up to you.
This is just one way that Gaia's events save coding time and turn challenging tasks into trivial ones.
Example Files
The exact code used to create these buttons is just an example. There are other ways of setting button branches on each button, and how you code your buttons exactly is up to you. This example, created with Gaia 3.1.9, has a working project which you can import into your Gaia panel and launch to see it working.
AS3: NavLessonAS3.zip
AS2: NavLessonAS2.zip

