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

by Peter deHaan on May 30, 2008

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;

{ 3 comments… read them below or add one }

Nick June 2, 2008 at 2:15 pm

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

Reply

Nick June 10, 2008 at 6:49 pm

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

Reply

peterd June 10, 2008 at 7:02 pm

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”.

Reply

Leave a Comment

Sorry, this blog is terrible at eating HTML comments.
If you're pasting any HTML/XML/MXML code, you need to convert your < characters to &lt; and your > characters to &gt; .

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: