17
Sep
07

Programmatically changing a Flex Accordion container’s selected index

The following example shows how you can change the currently selected child in an Accordion container using ActionScript by setting the accordion’s selectedIndex property.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/09/17/programmatically-changing-a-flex-accordion-containers-selected-index/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init();">

    <mx:Script>
        <![CDATA[
            private function init():void {
                slider.maximum = accordion.numChildren -1;
                slider.labels = [0, slider.maximum];
            }

            private function dataTipFunc(item:Object):String {
                return "selectedIndex = " + item.toString();
            }
        ]]>
    </mx:Script>

    <mx:ApplicationControlBar dock="true">
        <mx:Label text="selectedIndex:" />
        <mx:HSlider id="slider"
                minimum="0"
                liveDragging="true"
                snapInterval="1"
                tickInterval="1"
                change="accordion.selectedIndex = event.value;"
                dataTipFormatFunction="dataTipFunc"
                dataTipPlacement="bottom" />
    </mx:ApplicationControlBar>

    <mx:Accordion id="accordion"
            historyManagementEnabled="false"
            width="100%"
            height="100%"
            change="slider.value = event.newIndex;">
        <mx:VBox label="One" />
        <mx:VBox label="Two" />
        <mx:VBox label="Three" />
        <mx:VBox label="Four" />
        <mx:VBox label="Five" />
    </mx:Accordion>

</mx:Application>

View source is enabled in the following example.


12 Responses to “Programmatically changing a Flex Accordion container's selected index”


  1. 1 Czar Sep 18th, 2007 at 4:10 am

    It would be couuld to have live examples again…

  2. 2 peterd Sep 18th, 2007 at 9:13 am

    Sorry about that, I’ll try and upload and embed the SWFs tonight after work.

    Peter

  3. 3 max Feb 21st, 2008 at 2:15 am

    I need to set accordion into state without selected items (selectedIndex = - 1 or something doesn’t work)
    is there any solutions for this& thanks

  4. 4 Rod Mar 26th, 2008 at 10:54 am

    Max,

    I’m guessing you would something like:

    acc.selectedIndex = (acc.selectedIndex - 1);
    

    ——————

    Peter,
    Is there a way to cancel a change event or disable a header? I have 3 containers and do not want the users to leave the first container until a value has been filled out. i tried adding enabled='false' on the other two VBox’s, but the Accordion header doesn’t honor that apparently.

    thx.
    -r

  5. 5 Rod Mar 26th, 2008 at 11:01 am

    Nevermind, I got it working by referencing your getHeaderAt() example:

    Accordion.getHeaderAt(1).enabled = false;
    

    I’d like to know if there are others ways to do the same thing, but this will work for me.

    regards,
    -r

  6. 6 Keith May 9th, 2008 at 6:53 am

    I am in the same boat as Rod. I want to catch the change event and cancel the accordion slide if certain criteria have not been met. Any ideas?

  7. 7 Nick May 30th, 2008 at 10:52 am

    Hey Peter,

    I’m in the same boat as Rod Keith also lol. Can you possibly do a example on how to disable accordion index’s not allowing the user to click them to bring them up but rather click a continue or submit button in the main accordion index which loads you into the next accordion index?

    Please :)

    - Nick

  8. 8 peterd May 30th, 2008 at 2:11 pm

    Keith and Nick,

    This should disable all Accordion header mouse clicks and only allow users to change the selected child using the nested Button controls. (I say *should* since I haven’t really tested this):

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">
    
        <mx:Accordion id="acc"
                headerRenderer="comps.MyAccHeader"
                width="100%" height="100%">
            <mx:VBox id="v1" label="One">
                <mx:Button label="next" click="acc.selectedChild = v2;" />
            </mx:VBox>
            <mx:VBox id="v2" label="Two">
                <mx:Button label="prev" click="acc.selectedChild = v1;" />
                <mx:Button label="next" click="acc.selectedChild = v3;" />
            </mx:VBox>
            <mx:VBox id="v3" label="Three">
                <mx:Button label="prev" click="acc.selectedChild = v2;" />
                <mx:Button label="next" click="acc.selectedChild = v4;" />
            </mx:VBox>
            <mx:VBox id="v4" label="Four">
                <mx:Button label="prev" click="acc.selectedChild = v3;" />
                <mx:Button label="next" click="acc.selectedChild = v5;" />
            </mx:VBox>
            <mx:VBox id="v5" label="Five">
                <mx:Button label="prev" click="acc.selectedChild = v4;" />
            </mx:VBox>
        </mx:Accordion>
    
    </mx:Application>
    

    comps/MyAccHeader.as

    package comps {
        import mx.containers.accordionClasses.AccordionHeader;
    
        public class MyAccHeader extends AccordionHeader {
            public function MyAccHeader() {
                super();
                mouseEnabled = false;
            }
        }
    }
    

    And there may be better ways of doing this, but this was the first thing that came to mind.

    Hope that helps,
    Peter

  9. 9 peterd May 30th, 2008 at 2:52 pm

    As for disabling individual Accordion headers, this ActionScript should work:

    acc.getHeaderAt(0).enabled = false;
    

    Peter

  10. 10 Nick May 30th, 2008 at 4:35 pm

    Peter! Thank you sooooooooooooooooo much. Your first reply did the trick EXACTLY what I was looking for!

    OMG TY TY TY

    - Nick

  11. 11 peterd May 30th, 2008 at 5:35 pm

    Nick,

    Actually, this may be a better way of doing what you want (or, at least I think it is cool):

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">
    
        <mx:Accordion id="acc"
                headerRenderer="comps.MyAccHeader"
                width="100%" height="100%">
            <mx:VBox id="v1" label="One">
    
            </mx:VBox>
            <mx:VBox id="v2" label="Two" enabled="false">
    
            </mx:VBox>
            <mx:VBox id="v3" label="Three" enabled="false">
    
            </mx:VBox>
            <mx:VBox id="v4" label="Four">
    
            </mx:VBox>
            <mx:VBox id="v5" label="Five">
    
            </mx:VBox>
        </mx:Accordion>
    
    </mx:Application>
    

    comps/MyAccHeader.as

    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;
            }
        }
    }
    

    Now the enabled property on the VBox container should bubble up to the AccordionHeader.

    In fact, I think it is SO cool and useful that I may turn it into today’s “official”
    example (and that way it will get a nice SWF too).

    Happy Flexing!
    Peter

  12. 12 peterd May 30th, 2008 at 11:43 pm

Leave a Reply

This blog is terrible at eating HTML tags. If you plan on posting code/XML, please escape your "<" characters as "&lt;" and your ">" characters as "&gt;".