June 24, 2010

Create a ToggleButton Menu / Bar in Flex 4

In Flex 4 you have the ability to use the mx components or the new spark components. I started a project the other day and wanted to use a ToggleButtonBar and noticed the only on available was the mx component. Spark does come with a toggle button but it is a single button. Also I wanted to be able to use the ToggleButtonBar as a vertical menu and the mx component, to my knowledge, only lays out horizontally, and extending that component to get it to layout vertical just seemed like to much of a pain.

 
After thinking about the issue for a moment I dove right in and here is the resulting code that I came up with.
 

package com.mswallace.components.menus { import flash.events.FocusEvent; import flash.events.KeyboardEvent; import flash.events.MouseEvent;  import mx.collections.ArrayCollection; import mx.collections.ArrayList; import mx.events.FlexEvent;  import spark.components.Group; import spark.components.ToggleButton;  public class ToggleMenu extends Group {  public function ToggleMenu() { super(); this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete); }  private function onCreationComplete(event:FlexEvent):void { this.addEventListener(FocusEvent.FOCUS_IN, onFocusIn); }  private function onFocusIn(event:FocusEvent):void { this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); }  private function onKeyDown(event:KeyboardEvent):void { trace(event.keyCode); }   private function createMenu():void  { if(this.numChildren > 0) this.removeAllElements();  for (var i:String in toggleButtons)  { var value:String = toggleButtons.getItemAt(int(i)) as String;  var toggleButton:ToggleButton = new ToggleButton(); toggleButton.label = value; toggleButton.id = 'bn_' + value; toggleButton.addEventListener(MouseEvent.CLICK, onClick); this.addElement(toggleButton);   }  //this is optional code to select the first item  }  private function onClick(event:MouseEvent):void { if(event.currentTarget.selected == false) { event.currentTarget.selected = true; selectedIndex = this.getChildIndex(event.currentTarget as ToggleButton); }   for(var i:int=0; i< this.numChildren; ++i ) { var button:ToggleButton = this.getElementAt(i) as ToggleButton; if(event.currentTarget != button) button.selected = false; } }  ///////// vars \\\\\\\\\\\\  //array of string values that is passed in to create the buttons private var _toggleButtons : ArrayCollection; public function get toggleButtons():ArrayCollection { return _toggleButtons; }  public function set toggleButtons( value : ArrayCollection ):void { _toggleButtons = value;  if(value != null && value.length > 0) createMenu(); }  //selected index private var _selectedIndex:int; public function get selectedIndex():int { return _selectedIndex; }  public function set selectedIndex(value:int):void { _selectedIndex = value; }    } }

 
Here is the component implemented in MXML after creating the Actionscript Class.
I only did this so that I could control the layout in mxml tags but you could also implement the layout in the Actionscript class if you like.
I tend to follow a “code behind” method when creating some of my components.
 

<?xml version="1.0" encoding="utf-8"?> <menus:ToggleMenu xmlns:menus="com.mswallace.components.menus.*" xmlns:fx="http://ns.adobe.com/mxml/2009"  xmlns:s="library://ns.adobe.com/flex/spark"  xmlns:mx="library://ns.adobe.com/flex/mx">  <menus:layout> <s:VerticalLayout /> </menus:layout> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations>  </menus:ToggleMenu>

Posted via email from Matthew Sloan Wallace

Leave a Reply

You must be logged in to post a comment.