The following example shows how you can add and remove children from a Flex Accordion container by using the addChild() and removeChild() methods.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/09/18/dynamically-adding-new-children-to-a-flex-accordion-container/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            import mx.containers.VBox;

            private const MAX_CHILDREN:uint = 5;

            private function accordion_addChild():void {
                if (accordion.numChildren < MAX_CHILDREN) {
                    var vbox:VBox = new VBox();
                    vbox.label = "child " + accordion.numChildren;
                    vbox.percentWidth = 100;
                    vbox.percentHeight = 100;
                    var randColor:uint = Math.random() * 0xFFFFFF;
                    vbox.setStyle("backgroundColor", randColor);
                    accordion.addChild(vbox);
                }
            }

            private function accordion_deleteChild():void {
                if (accordion.selectedChild) {
                    accordion.removeChild(accordion.selectedChild);
                }
            }
        ]]>
    </mx:Script>

    <mx:ApplicationControlBar dock="true">
        <mx:Button label="Add child"
            click="accordion_addChild();" />
        <mx:Button label="Delete child"
            click="accordion_deleteChild();" />
    </mx:ApplicationControlBar>

    <mx:Accordion id="accordion" width="240" height="160" />

</mx:Application>

View source is enabled in the following example.

 
Tagged with:
 
About The Author

Peter deHaan

Peter deHaan currently works for Adobe on the Flex SDK QA team. While not working on Flex, Flash, and ColdFusion applications, Peter enjoys making up bios and writing in 3rd person. Peter's rarely updated blog can be found at blogs.adobe.com/pdehaan/, actionscriptexamples.com, airexamples.com, and coldfusionexamples.com.

19 Responses to Dynamically adding new children to a Flex Accordion container

  1. Samus_ says:

    hello, citing from http://livedocs.adobe.com/flex/201/langref/mx/states/RemoveChild.html

    “The RemoveChild class removes a child display object, such as a component, from a container as part of a view state. The child is only removed from the display list, it is not deleted.”

    this will surely lead to memory leaking problems, and also forces me to reset the control’s contents each time they’re shown, how can I destroy a component?

  2. Samuel Neff says:

    Samus,

    The component is destroyed just like any other class–when it is not accessible from the application (when all references are destroyed). Having a parent is a reference so being on the display list by definition keeps something alive. Having a reference to the component such as an instance variable also could keep it alive.

    In the above example, however, the component is created as a function-local variable and added to the accordion. No other reference is kept so in this situation, the component is eligible for garbage collection when it’s removed from the display list.

    HTH,

    Sam

  3. Samus_ says:

    hi thanks for the reply! yes reading a little more seems that objects are destroyed when there’s no other reference to them, that reminds me of files in a unix filesystem; is quite tricky to me honestly I didn’t expected something like that because this forces me to keep track of references to the objects and it seems that event listeners also apply as references, perhaps you could suggest me some design patterns that are better to deal with this situation (I’m more used to the C approach and never worked in Java). I’m most worried about leaking memory because I left some references somewhere else :/ also I’ve found an interesting article about the garbage collectos itself here: http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html c’ya!

  4. Samus_ says:

    UPDATE: I’ve checked again that link and the links suggested there, there is a way to add the listeners as “weak references” that are ignored by the garbage collector; very interesting, that solves half of my problem of lost references.
    check it here: http://www.adobe.com/devnet/flashplayer/articles/resource_management.html and here: http://www.gskinner.com/blog/archives/2006/07/as3_weakly_refe.html

  5. danny says:

    hey, what if I wanted to put the add and remove functions into there own class? when i do that, it says that “accordian.addchild…” is undefined. I’m trying to learn how to make my code more modular, and if someone could explain this it would be very helpful. thanks!

  6. djrogi says:

    on a dynamically created accordion like this, how would you create a DataGrid that pulls from live data? Been working on it for about 3 days now, and get stumped by adding a child under a child.

    Awesome examples they are a huge help to new Flex-ers

  7. PaulH says:

    peter,

    what about the contents of the remaining children? i’ve got an accordion setup in mxml that i reconfigure by deleting children. what i’m seeing is the contents of the remaining children (all List) aren’t getting rendered until the user changes the selectedIndex. i’ve tried pretty much all the tricks i know to get the List contents to render after deleting the child (creationPolicy, etc.) but no luck.

    any ideas?

    ps: i guess no need to keep repeating how much we love this blog, but what the heck, “we love this blog” ;-)

  8. peterd says:

    PaulH,

    Apart from setting the creationPolicy property, I don’t have any other immediate ideas. And you tried setting the creationPolicy to “all”, or setting it to “auto” then “all”?

    If you think it is a bug, file it at http://bugs.adobe.com/flex/ and solicit a few votes and then somebody at Adobe can take a look.

    Peter

  9. Kirk says:

    Paul:

    Will the same code work to dynamically add a tab to a tabnavigator container?

    Kirk

  10. peterd says:

    Kirk,

    The same general code should work for TabNavigator:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application name="TabNavigator_addChild_test"
            xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">
    
        <mx:Script>
            <![CDATA[
                import mx.containers.HBox;
    
                private function addChildButton_click(evt:MouseEvent):void {
                    var box:HBox = new HBox();
                    box.label = "Child " + tabNavigator.numChildren;
                    box.percentWidth = 100;
                    box.percentHeight = 100;
                    box.setStyle("backgroundColor", int(Math.random() * 0xFFFFFF));
                    tabNavigator.addChild(box);
                }
    
                private function removeChildButton_click(evt:MouseEvent):void {
                    if (tabNavigator.selectedChild != null) {
                        tabNavigator.removeChild(tabNavigator.selectedChild);
                    }
                }
    
                private function removeAllChildrenButton_click(evt:MouseEvent):void {
                    tabNavigator.removeAllChildren();
                }
            ]]>
        </mx:Script>
    
        <mx:ApplicationControlBar dock="true">
            <mx:Button id="addChildButton"
                    label="Add child"
                    click="addChildButton_click(event);" />
            <mx:Button id="removeChildButton"
                    label="Remove child"
                    click="removeChildButton_click(event);" />
            <mx:Button id="removeAllChildrenButton"
                    label="Remove all children"
                    click="removeAllChildrenButton_click(event);" />
        </mx:ApplicationControlBar>
    
        <mx:TabNavigator id="tabNavigator"
                width="100%"
                height="100%" />
    
    </mx:Application>
    

    Peter

  11. jm says:

    Hi

    I have an application with a viewStack to separate my screens.
    Everything works fine in the first screen, but in the second one, i
    cannot call an ActionScript function in the show event of a VBox
    container

    I am assuming that when the second view is activated the show event of
    the inner elements is called, but apparently i am mistaken. The
    creationComplete event is valid for the first screen because it is
    called when the application starts, but not for the second screen
    elements because they are already created

    Please help

  12. Jose says:

    Hi,

    I need to add to a child from other children already created.

    Example:

    acGrupos.selectedChild.addChild(cmb1);

    The idea is that this new child is within the selected.

    Thanks

  13. Michael says:

    is there a way to assign a unique “id” to each of the new children? And if this is possible, how would you reference those children later in the program with their unique ids?

  14. Nicolas says:

    Navigating away to another state does not destroy the Accordion. When I come back again it is appending new children instead of starting from an empty accordion. Bizar? I was always under the impression that leaving a state removes that screen.
    (maybe that was what was meant by Garbage collection)
    Is there a way to rest the accordion so that it is empty?

    • Nicolas says:

      Solved!

      //Removes all previous children from accordion
      var numChildren:Number = accordion.numChildren
      for(var i:Number=0; i<numChildren; i++){
      		accordion.removeChildAt(i);
      }
  15. Nicolas says:

    Interesting. This only works if you countdown like removing items off a stack otherwise it causes an error. I didn’t notice it until I had more than two items.
    It makes sense now. As the number of children decreases the indexes change.

    //Removes all previous children from accordion
    var numChildren:Number = accordion.numChildren
    for(var i:Number=numChildren - 1; i > -1; i--){
    	accordion.removeChildAt(i);
    }
    • Peter deHaan says:

      @Nicolas,

      Kind of makes sense. If you have two children and then you call accordion.removeChildAt(0);, then you’re left with one child, which moves to the 0 position. So when you call accordion.removeChildAt(1); you’d get an error since the child formerly at 1 has moved to 0. You could either go in reverse like your example, or you could probably just do a loop and always remove the child at the 0 position. Or, you may be able to just set the Accordion container’s data provider to an empty array and remove all the children at once.

      Peter

  16. Igor says:

    Has anyone noticed that when clicking on the header and animation run, right border of Accordion flickers, I came to the conclusion that this is due to the fact that in AS code we use the properties percentHeigth and percentWidth, if you add child in MXML, then this is no flicker.

  17. Gajendra S V says:

    I want add button to dynamically added accordion please inform me how to add?

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Anti-Spam Protection by WP-SpamFree