Expanding nodes in a Flex Tree control using the openItems property

by Peter deHaan on January 15, 2008

in Tree

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.

<?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 name="Tree_openItems_test"
        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.

<?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 name="Tree_openItems_test"
        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 comments… read them below or add one }

1 Luis January 18, 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!

Reply

2 Peter deHaan January 18, 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>

Reply

3 Luis January 21, 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á

Reply

4 Craig Hollabaugh February 21, 2008 at 11:06 pm

Peter,
In this statement,

var xList:XMLList = dp..node.(hasOwnProperty("@isOpen") &amp;&amp; @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") &amp;&amp; @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

Reply

5 Stone February 26, 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!

Reply

6 Peter Pohlmann April 15, 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

Reply

7 ILIUS November 17, 2008 at 10:14 pm
private function openAllNodes():void {
    tree.openItems=dp.descendants("*")
}

Reply

8 ILIUS December 7, 2008 at 8:44 am

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

Reply

9 mdh December 15, 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.

Reply

10 Jason Swick April 3, 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.

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

You can 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

Previous post:

Next post: