15
Jan
08

Expanding nodes in a Flex Tree control using the openItems property

The following example shows how you can open nodes in a Tree control in Flex by setting the openItems property to an XMLList or Array object.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/01/15/expanding-nodes-in-a-flex-tree-control-using-the-openitems-property/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            private function openAllNodes():void {
                tree.openItems = dp..node;
            }

            private function closeAllNodes():void {
                tree.openItems = [];
            }
        ]]>
    </mx:Script>

    <mx:XML id="dp">
        <root>
            <node label="Parent 1">
                <node label="Child 1" />
                <node label="Child 2">
                    <node label="Grandchild 1" />
                    <node label="Grandchild 2" />
                </node>
                <node label="Child 3" />
                <node label="Child 4" />
            </node>
        </root>
    </mx:XML>

    <mx:ApplicationControlBar dock="true">
        <mx:Button label="Open all nodes" click="openAllNodes();" />
        <mx:Button label="Close all nodes" click="closeAllNodes();" />
    </mx:ApplicationControlBar>

    <mx:Tree id="tree"
            dataProvider="{dp}"
            showRoot="false"
            labelField="@label"
            width="200" />

</mx:Application>

View source is enabled in the following example.

You can tweak the previous E4X statement by only returning nodes that have children: dp..node.(children().length() > 0);.

The following example uses a bit more of a complex E4X statement to find data provider XML nodes with a specific attribute, “isOpen”, and only opens those nodes.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/01/15/expanding-nodes-in-a-flex-tree-control-using-the-openitems-property/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            private function openSomeNodes():void {
                var xList:XMLList = dp..node.(hasOwnProperty("@isOpen") && @isOpen == "true");
                tree.openItems = xList;
            }

            private function closeAllNodes():void {
                tree.openItems = [];
            }
        ]]>
    </mx:Script>

    <mx:XML id="dp">
        <root>
            <node label="Parent 1" isOpen="true">
                <node label="Child 1" />
                <node label="Child 2">
                    <node label="Grandchild 1" />
                    <node label="Grandchild 2" />
                </node>
                <node label="Child 3" />
                <node label="Child 4" isOpen="true">
                    <node label="Grandchild 3">
                        <node label="Great-grandchild 1" />
                        <node label="Great-grandchild 2" />
                        <node label="Great-grandchild 3" />
                        <node label="Great-grandchild 4">
                            <node label="Great-great-grandchild 1" />
                        </node>
                        <node label="Grandchild 1" />
                    </node>
                    <node label="Grandchild 4" />
                </node>
                <node label="Child 5" />
            </node>
        </root>
    </mx:XML>

    <mx:ApplicationControlBar dock="true">
        <mx:Button label="Open some nodes" click="openSomeNodes();" />
        <mx:Button label="Close all nodes" click="closeAllNodes();" />
    </mx:ApplicationControlBar>

    <mx:Tree id="tree"
            dataProvider="{dp}"
            showRoot="false"
            labelField="@label"
            width="300" />

</mx:Application>

View source is enabled in the following example.


10 Responses to “Expanding nodes in a Flex Tree control using the openItems property”


  1. 1 Luis Jan 18th, 2008 at 1:31 am

    Hi Peter, Firt of all. Congratulations for the blog. It´s one of the best Fex Resources i found.

    Lets talk about this post and see if you or other reader can help me.

    Imagine that my tree is embedded into a panel. (You can see my flex page about sanish accounting software in this comment link. Section “El Plan de Cuentas)

    If i use your system to open all nodes, the content of the tree will go own from the content of the panl, but the panel is not showing me the scroll bar. Otherwise, expanding tree nodes 1 by 1 the panel show the scrolling bar when the size is not enough.

    Thanks and great Job!

  2. 2 peterd Jan 18th, 2008 at 7:10 am

    Luis,

    I can’t seem to reproduce the issue. Using the code from the code from the example above (second example, the first example doesn’t have enough data to cause scroll bars to appear), the scrollbars are displaying when I expand the nodes. I even created a bigger data set (code below) and the scrollbars appear correctly also.

    Also, you could try explicitly setting the verticalScrollPolicy property to “on” for the Tree and see if that fixes the issue.

    I’m using Flex 3 SDK Version 191831. Are you using Flex 2.0.1 or the Flex 3 beta?

    If you think it is a bug, can you file a bug report at http://bugs.adobe.com/flex/ and include your source code (or a simple test case showing the behavior) and myself or somebody else can take a look at it.

    Thanks,
    Peter

    <?xml version="1.0" encoding="utf-8"?>
    <!-- http://blog.flexexamples.com/2008/01/15/expanding-nodes-in-a-flex-tree-control-using-the-openitems-property/ –>
    <mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
            layout=”vertical”
            verticalAlign=”middle”
            backgroundColor=”white”>
    
        <mx:Script>
            <![CDATA[
                import mx.utils.ObjectUtil;
    
                private function openAll():void {
                    var items:XMLList = xmlDP..node.(children().length() > 0);
                    tree.openItems = items;
                }
    
                private function closeAll():void {
                    tree.openItems = [];
                }
            ]]>
        </mx:Script>
    
        <mx:XML id=”xmlDP”>
            <root>
                <node label=”American League”>
                    <node label=”West”>
                        <node label=”Los Angeles” />
                        <node label=”Seattle” />
                        <node label=”Oakland” />
                        <node label=”Texas” />
                    </node>
                    <node label=”Central”>
                        <node label=”Cleveland” />
                        <node label=”Detroit” />
                        <node label=”Minnesota” />
                        <node label=”Chicago” />
                        <node label=”Kansas City” />
                    </node>
                    <node label=”East”>
                        <node label=”Boston” />
                        <node label=”New York” />
                        <node label=”Toronto” />
                        <node label=”Baltimore” />
                        <node label=”Tampa Bay” />
                    </node>
                </node>
                <node label=”National League”>
                    <node label=”West”>
                        <node label=”Arizona” />
                        <node label=”Colorado” />
                        <node label=”San Diego” />
                        <node label=”Los Angeles” />
                        <node label=”San Francisco” />
                    </node>
                    <node label=”Central”>
                        <node label=”Chicago” />
                        <node label=”Milwaukee” />
                        <node label=”St. Louis” />
                        <node label=”Houston” />
                        <node label=”Cincinnati” />
                        <node label=”Pittsburgh” />
                    </node>
                    <node label=”East”>
                        <node label=”Philadelphia” />
                        <node label=”New York” />
                        <node label=”Atlanta” />
                        <node label=”Washington” />
                        <node label=”Florida” />
                    </node>
                </node>
            </root>
        </mx:XML>
    
        <mx:ApplicationControlBar dock=”true”>
            <mx:Button label=”Open all” click=”openAll();” />
            <mx:Button label=”Close All” click=”closeAll();” />
        </mx:ApplicationControlBar>
    
        <mx:Tree id=”tree”
                dataProvider=”{xmlDP}”
                labelField=”@label”
                showRoot=”false”
                width=”300″
                height=”100%”
                verticalScrollPolicy=”auto” />
    
    </mx:Application>
    
  3. 3 Luis Jan 21st, 2008 at 2:10 am

    Hi Peter.

    Are you sure that this last code of your response is working? When i copy into my Flex Builder 3 (Milestone 3 Beta 2) and execute it via Internet Explorer, if i click “Open All” button, Washington and Florida dont show and the scrollbars also dont show, so you have reproduced my problem perfectly with this example!!

    I can´t find a solution for now. I also set the verticalScrollPolicy to “on” but dont work. If i can find a solution, ill tell you.

    Thanks and sorry for my poor english

    Luis Alcalá

  4. 4 Craig Hollabaugh Feb 21st, 2008 at 11:06 pm

    Peter,
    In this statement,

    var xList:XMLList = dp..node.(hasOwnProperty(”@isOpen”) && @isOpen == “true”)

    you use the ‘..’ e4x operator to look for node elements with @isOpen attribute and @isOpen is true.

    If your XML elements were not but a collection with different localnames, how could you find all elements with @isOpen attributes

    var xList:XMLList = dp..(hasOwnProperty(”@isOpen”) && @isOpen == “true”)

    doesn’t compile. I’ve tried all sorts of things but can’t figure out the e4x equivalent to xpath’s ‘//*[@attr]’

    Thanks,
    Craig

  5. 5 Stone Feb 26th, 2008 at 10:26 pm

    It seems in Flex SDK 2.0.1, the vertical scrollbar will not be updated when the openItems is changed. Does anyone know how to fix this?

    You can reproduce the problem by just compile the second sample in Flex SDK 2.0.1 and click “Open some nodes”, and the vertical scrollbar will not show!

  6. 6 Peter Pohlmann Apr 15th, 2008 at 7:47 am

    hello all,

    first of all a big respect for this blog.

    Got also problems with the vertical scrolling….

    Here is nice tutorial for a tree with amfPHP (http://www.sephiroth.it/tutorials/fl…fphp/index.php)

    i’ve used it for my app, but running into some trouble now, with the scrollbars, what i really didn’t expect!!

    here you can see the app and the source code:
    http://www.rootop.de/testing/TestTree.html

    it’s all german, so when you click on Enomis -> Einzelstoffe->Obst , then there appears a scrollbar for a short time and then disappears again, even if there are more branches… it really makes me mad.. i tried serveral function like..

    //scroll always to bottom, otherwise, only the items are shown, that are in the visible area
    tree.verticalScrollPosition=tree.maxVerticalScroll Position;

    tree.invalidateList();

    tree.validateNow();

    but nothing really works. the general problem is, that i don’t know when flex display the scrollbar and when not. because in some cases it works.
    so, if there is a solution or a workaround, i would be very happy. thanks in advance. kind regards, peter

  7. 7 ILIUS Nov 17th, 2008 at 10:14 pm
    private function openAllNodes():void {
        tree.openItems=dp.descendants("*")
    }
    
  8. 8 ILIUS Dec 7th, 2008 at 8:44 am

    How can i close all nodes except one i’ve just opened? Kind of accordion.

  9. 9 mdh Dec 15th, 2008 at 2:37 pm

    Thanks for this post! It helped me solve an issue I didn’t think I was ever going to figure out.

  10. 10 Jason Swick Apr 3rd, 2009 at 12:10 pm

    I have a tree that the dataprovider changes, and using methods such as tree.openItems = tree.dataProvider; would open only the top level, and tree.dataProvider().descendants(); would open everything EXCEPT the top level. what I finally came up with is tree.openItems = tree.dataProvider[0].parent().descendants(); and that opens everything.

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;".




Badge Farm

  • Powered by Redoable 1.2
  • Cornify
  • Feeds burnt by Feedburner
  • Feed