Preventing users from clicking on an Accordion container’s header in Flex

The following examples show how you can prevent a user from clicking a Flex Accordion container’s header by creating a custom Accordion header renderer.

Full code after the jump.

The following example uses a custom header renderer (MyAccHeader) which sets the header’s mouseEnabled property to false, preventing the user from changing the currently selected accordion child by clicking on the header. Instead, users are forced to change the active child by clicking the next and previous buttons.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/05/30/preventing-users-from-clicking-on-an-accordion-containers-header-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            private function prevChild():void {
                accordion.selectedIndex--;
            }

            private function nextChild():void {
                accordion.selectedIndex++;
            }
        ]]>
    </mx:Script>

    <mx:Accordion id="accordion"
            headerRenderer="comps.MyAccHeader"
            width="100%" height="100%">
        <mx:VBox id="v1" label="One" width="100%" height="100%">
            <mx:VBox width="100%" height="100%">
                <mx:Label text="One" />
            </mx:VBox>
            <mx:ControlBar horizontalAlign="right" width="100%">
                <mx:Spacer width="100%" />
                <mx:Button label="next" click="nextChild();" />
            </mx:ControlBar>
        </mx:VBox>
        <mx:VBox id="v2" label="Two" width="100%" height="100%">
            <mx:VBox width="100%" height="100%">
                <mx:Label text="Two" />
            </mx:VBox>
            <mx:ControlBar width="100%">
                <mx:Button label="prev" click="prevChild();" />
                <mx:Spacer width="100%" />
                <mx:Button label="next" click="nextChild();" />
            </mx:ControlBar>
        </mx:VBox>
        <mx:VBox id="v3" label="Three" width="100%" height="100%">
            <mx:VBox width="100%" height="100%">
                <mx:Label text="Three" />
            </mx:VBox>
            <mx:ControlBar width="100%">
                <mx:Button label="prev" click="prevChild();" />
                <mx:Spacer width="100%" />
                <mx:Button label="next" click="nextChild();" />
            </mx:ControlBar>
        </mx:VBox>
        <mx:VBox id="v4" label="Four" width="100%" height="100%">
            <mx:VBox width="100%" height="100%">
                <mx:Label text="Four" />
            </mx:VBox>
            <mx:ControlBar width="100%">
                <mx:Button label="prev" click="prevChild();" />
                <mx:Spacer width="100%" />
                <mx:Button label="next" click="nextChild();" />
            </mx:ControlBar>
        </mx:VBox>
        <mx:VBox id="v5" label="Five" width="100%" height="100%">
            <mx:VBox width="100%" height="100%">
                <mx:Label text="Five" />
            </mx:VBox>
            <mx:ControlBar width="100%">
                <mx:Button label="prev" click="prevChild();" />
                <mx:Spacer width="100%" />
            </mx:ControlBar>
        </mx:VBox>
    </mx:Accordion>

</mx:Application>

comps/MyAccHeader.as

/**
 * http://blog.flexexamples.com/2008/05/30/preventing-users-from-clicking-on-an-accordion-containers-header-in-flex/
 */
package comps {
    import mx.containers.accordionClasses.AccordionHeader;

    public class MyAccHeader extends AccordionHeader {
        public function MyAccHeader() {
            super();
            mouseEnabled = false;
        }
    }
}

View source is enabled in the following example.

The following example uses a custom header renderer (MyAccHeader) which sets the header’s enabled property to the value of the container’s enabled property, allowing you to selectively disable accordion headers.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/05/30/preventing-users-from-clicking-on-an-accordion-containers-header-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            private function prevChild():void {
                accordion.selectedIndex--;
            }

            private function nextChild():void {
                accordion.selectedIndex++;
            }
        ]]>
    </mx:Script>

    <mx:Accordion id="accordion"
            headerRenderer="comps.MyAccHeader"
            width="100%"
            height="100%">
        <mx:VBox id="v1"
                label="One"
                width="100%"
                height="100%">
            <mx:Label text="One" />
        </mx:VBox>
        <mx:VBox id="v2"
                label="Two"
                width="100%"
                height="100%">
            <mx:Label text="Two" />
        </mx:VBox>
        <mx:VBox id="v3"
                label="Three"
                enabled="false"
                width="100%"
                height="100%">
            <mx:Label text="Three" />
        </mx:VBox>
        <mx:VBox id="v4"
                label="Four"
                enabled="false"
                width="100%"
                height="100%">
            <mx:Label text="Four" />
        </mx:VBox>
        <mx:VBox id="v5"
                label="Five"
                width="100%"
                height="100%">
               <mx:Label text="Five" />
        </mx:VBox>
    </mx:Accordion>

</mx:Application>

comps/MyAccHeader.as

/**
 * http://blog.flexexamples.com/2008/05/30/preventing-users-from-clicking-on-an-accordion-containers-header-in-flex/
 */
package comps {
    import mx.containers.accordionClasses.AccordionHeader;
    import mx.events.FlexEvent;

    public class MyAccHeader extends AccordionHeader {
        public function MyAccHeader() {
            super();
            addEventListener(FlexEvent.INITIALIZE, accordionHeader_initialize);
        }

        private function accordionHeader_initialize(evt:FlexEvent):void {
            enabled = data.enabled;
        }
    }
}

View source is enabled in the following example.

You can also use ActionScript to toggle an accordion header’s enabled property using the following snippet:

accordion.getHeaderAt(0).enabled = false;

5 thoughts on “Preventing users from clicking on an Accordion container’s header in Flex

  1. Thank you again Peter! This came in handy tremendously. Keep up the awesome blogging. If I could recommend something else that I would like to see is Flex and PHP examples :)

    Thanks!

    – Nick

  2. Well, you should disable the keyboard listener too, page up and page down strokes could still ruin your application.
    Still, it is a nice example of the accordion.

  3. Good call Benjamin. Do you know of a demonstration or example to show how to disable the enter, spacebar, tab, up and down arrows on the keyboard on the accordion headers? Or maybe Peter can whip up a code for that also? :)

  4. Hey Peter can you shoot me an email or show an example on how to disable the keyboard keys that I listed above? I would reaally appreciate it I can’t figure this out and I kinda need it for this project thats due soon :)

    Thanks

    – Nick

  5. Nick,

    I’ve never really tried to disable keyboard+Accordion navigation, but if you want some rough and untested code, I’d probably recommend extending the Accordion container and overriding the keyDownHandler() method:

    package comps {
        import mx.containers.Accordion;
        import flash.events.KeyboardEvent;
    
        public class MyAccordion extends Accordion {
            public function MyAccordion() {
                super();
            }
    
            override protected function keyDownHandler(evt:KeyboardEvent):void {
            }
        }
    }
    

    But, like I said, I haven’t really tested the code. So your mileage may vary.

    Peter

    UPDATE: Actually, on that note, I turned this into today’s entry. For more information, see “Disabling keyboard navigation on the Accordion container in Flex”.

Comments are closed.