Disabling individual buttons on a Flex ButtonBar control

The following example shows how you can disable individual buttons on a ButtonBar control in Flex by using the getChildAt() method and enabled property on the returned button instance.

Full code after the jump.

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/01/10/disabling-individual-buttons-on-a-flex-buttonbar-control/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">
 
    <mx:Style>
        ButtonBar {
            buttonStyleName: myCustomButtonStyleName;
        }
 
        .myCustomButtonStyleName {
            cornerRadius: 0;
        }
    </mx:Style>
 
    <mx:Script>
        <![CDATA[
            import mx.controls.buttonBarClasses.ButtonBarButton;
 
            private function toggleButton(idx:uint, selected:Boolean):void {
                var b3:ButtonBarButton = buttonBar.getChildAt(idx) as ButtonBarButton;
                b3.enabled = selected;
            }
        ]]>
    </mx:Script>
 
    <mx:Array id="arr">
        <mx:Object label="Button" />
        <mx:Object label="ButtonBar" />
        <mx:Object label="ColorPicker" />
        <mx:Object label="ComboBox" />
    </mx:Array>
 
    <mx:ApplicationControlBar dock="true">
        <mx:Form styleName="plain">
            <mx:FormItem label="Button enabled:">
                <mx:CheckBox id="ch1"
                        selected="true"
                        click="toggleButton(0, ch1.selected);" />
            </mx:FormItem>
            <mx:FormItem label="ButtonBar enabled:">
                <mx:CheckBox id="ch2"
                        selected="true"
                        click="toggleButton(1, ch2.selected);" />
            </mx:FormItem>
            <mx:FormItem label="ColorPicker enabled:">
                <mx:CheckBox id="ch3"
                        selected="true"
                        click="toggleButton(2, ch3.selected);" />
            </mx:FormItem>
            <mx:FormItem label="ComboBox enabled:">
                <mx:CheckBox id="ch4"
                        selected="true"
                        click="toggleButton(3, ch4.selected);" />
            </mx:FormItem>
        </mx:Form>
    </mx:ApplicationControlBar>
 
    <mx:ButtonBar id="buttonBar"
            dataProvider="{arr}"
            itemClick="lbl.text = event.label;" />
 
    <mx:Label id="lbl" />
 
</mx:Application>

View source is enabled in the following example.

22 thoughts on “Disabling individual buttons on a Flex ButtonBar control

  1. Hi,

    I really found this website as a valuable resource but I think since you add the search functionality it is hard to find what you are looking for. I liked it much more in its previous version where you listed all the control and you could pick the example that illustrate this particular control. Right now when I am searching for combobox for example I am getting a lot of non-relevant examples.

    I appreciate your effort

  2. Hi,

    the example works great. Is there a way to enable/disable items within the building phase of the component? I tried this but without any results …

    var buttonBarItemsArr:Array = [
     
       {label:'item1', enabled:false},
       {label:'item2', enabled:true}
    ];
     
    myButtonBar.dataProvider = buttonBarItemsArr;

    Thanks Hagen

  3. Hagen,

    Not that I know of (but that isn’t saying much — you’d have better luck asking on FlexCoders). There may be a way to extend the ButtonBar class and add this functionality in somewhere.

    You could do this if you were using a ViewStack as a data provider though:

    <mx:ButtonBar id="buttonBar2" dataProvider="{viewStack}" />
    <mx:ViewStack id="viewStack">
        <mx:VBox label="One" />
        <mx:VBox label="Two" enabled="false" />
        <mx:VBox label="Three" enabled="false" />
        <mx:VBox label="Four" />
    </mx:ViewStack>

    Feel free to file a bug/enhancement request in the public Flex bug base though (http://bugs.adobe.com/flex/). Heck, if you post the bug number here, I’ll vote for the bug. :)

    Peter

  4. Hi Peter,

    thanks for moving the bug at bugs.adobe.com! It was my first report, so i’m not so familar with the adobe-interface.

    Putting all the good staff together, i have build up a smal ‘Customised ButtonBar Example’. Using a extended version of the ButtonBar component and custom events the user are able to enable/disable ButtonBar ‘childs’. You can find the application and the source code here:

    http://www.newbit.org/flexexamples/CustomButtonBarExample/bin/CustomButtonBarExample.html

    Ok, that’s it.

    Hagen

  5. Another way to change the ButtonBar within the Building phase is to have a function that is called when a ViewStack is created and changed (this assumes that the ButtonBar is being used with a ViewStack).

    This code will change the currently selected button background to black and all other buttons to white when the ViewStack is created and every time the ViewStack changes:

    private function toggleButton():void {
       var colorArray:Array=["black", "black"];
       var whiteArray:Array=["white", "white"];
     
       for each(var i:Object in vsMainButtonBar.getChildren()){
           i.setStyle("fillColors", whiteArray);
       }
     
       var b3:ButtonBarButton = vsTeachButtonBar.getChildAt(vsTeach.selectedIndex) as ButtonBarButton;
       b3.setStyle("fillColors", colorArray);
    }
  6. Here it is again (didn’t escape the mxml code last time):

    <mx:ButtonBar dataProvider="{vsMain}" id="vsMainButtonBar"/>
    <mx:ViewStack id="vsMain" change="toggleButton();" creationComplete="toggleMainButton();">
    
  7. FYI, I was trying to do disbale a single button in my button bar by calling an init() function on my App’s creation complete event. When I do that I get an error that the index is out of bounds.

    So then I tried to call that code on my buttonBar’s creation complete event. No error, but my button isn’t disabled as desired.

    However, the updateComplete event seems to do the trick. If I call my code to disable my button on the ButtonBar’s updateComplete, then my single button is disabled. Also, calling that code from another test button also works as it does in your example.

    Finally, while the ButtonBarButton is a valid class, it doesn’t come up via auto completion in the Flex 3 IDE. Is this a bug or is this one of those classes that Adobe doesn’t intend for the user to touch? Just curious.

    Thx for the info. Once again your blog as taught me even more Flex trickery and made my apps better!

  8. Hello, the very good example! One question, I could disable all the fields of text that is inside a Canvas using getChildAt? Thanks for your help!

  9. Rodrigo,

    How about something like the following (just add/remove whatever controls you want to enable/disable to the switch statement):

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
     
        <mx:Script>
            <![CDATA[
                import mx.core.UIComponent;
                import flash.utils.getQualifiedClassName;
     
                protected function btn_clickHandler(evt:MouseEvent):void {
                    var uic:UIComponent;
                    var idx:uint;
                    var len:uint = cnvs.numChildren;
                    for (idx=0; idx<len; idx++) {
                        uic = cnvs.getChildAt(idx) as UIComponent;
                        switch (getQualifiedClassName(uic)) {
                            case "mx.controls::Label":
                            case "mx.controls::Text":
                            case "mx.controls::TextArea":
                            case "mx.controls::TextInput":
                                uic.enabled = !uic.enabled;
                                break;
                        }
                    }
                }
            ]]>
        </mx:Script>
     
        <mx:VBox id="cnvs">
            <mx:TextInput id="ti" text="TextInput" />
            <mx:TextArea id="ta" text="TextArea" />
            <mx:DateField id="df" selectedDate="{new Date()}" />
            <mx:Label id="lbl" text="Label" />
            <mx:Text id="txt" text="Text" />
            <mx:ColorPicker id="cp" />
        </mx:VBox>
        <mx:Button id="btn" click="btn_clickHandler(event);" />
     
    </mx:Application>

    Peter

  10. Hi Peter,

    Is there a way to replace the button-component in the buttonbar with a new button-class (one that’s created in catalyst)?

Comments are closed.