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>