Detecting when a user opens or closes a Tree control in Flex

The following example shows you how you can listen for when the user opens or closes a node in a Flex Tree control by listening for the itemOpen and itemClose events to be dispatched.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/11/28/detecting-when-a-user-opens-or-closes-a-tree-control-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="horizontal"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            import mx.events.CollectionEvent;
            import mx.events.CollectionEventKind;
            import mx.events.TreeEvent;

            private function tree_itemOpen(evt:TreeEvent):void {
                arrColl.addItem({type:evt.type, label:evt.item.@label});
            }

            private function tree_itemClose(evt:TreeEvent):void {
                arrColl.addItem({type:evt.type, label:evt.item.@label});
            }

            private function arrColl_collectionChange(evt:CollectionEvent):void {
                switch (evt.kind) {
                    case CollectionEventKind.ADD:
                        callLater(autoScroll);
                        break;
                }
            }

            private function autoScroll():void {
                dataGrid.verticalScrollPosition = dataGrid.maxVerticalScrollPosition;
            }
        ]]>
    </mx:Script>

    <mx:ArrayCollection id="arrColl"
            collectionChange="arrColl_collectionChange(event);" />

    <mx:XMLListCollection id="xmlListColl">
        <mx:source>
            <mx:XMLList>
                <node label="One">
                    <node label="One.1">
                        <node label="One.1.1">
                            <node label="One.1.1.1">
                                <node label="One.1.1.1.1" />
                            </node>
                        </node>
                    </node>
                    <node label="One.2" />
                    <node label="One.3" />
                </node>
                <node label="Two">
                    <node label="Two.1" />
                    <node label="Two.2" />
                    <node label="Two.3" />
                </node>
            </mx:XMLList>
        </mx:source>
    </mx:XMLListCollection>

    <mx:Tree id="tree"
            dataProvider="{xmlListColl}"
            labelField="@label"
            width="350"
            rowCount="6"
            showScrollTips="true"
            itemOpen="tree_itemOpen(event);"
            itemClose="tree_itemClose(event);" />

    <mx:DataGrid id="dataGrid"
            dataProvider="{arrColl}"
            verticalScrollPolicy="on"
            width="100%"
            height="{tree.height}">
        <mx:columns>
            <mx:DataGridColumn dataField="type" />
            <mx:DataGridColumn dataField="label" />
        </mx:columns>
    </mx:DataGrid>

</mx:Application>

View source is enabled in the following example.

There is also a third event you can listen for to monitor when a node is opened or closed, the itemOpening event. According to the Flex 3 Tree class documentation the differences between the three events are:

itemClose — Dispatched when a branch is closed or collapsed.
itemOpen — Dispatched when a branch is opened or expanded.
itemOpening — Dispatched when a branch open or close is initiated.

The following example shows how you can use the itemOpening event to determine if the Tree node was opened or closed by checking the opening property of the TreeEvent object.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/11/28/detecting-when-a-user-opens-or-closes-a-tree-control-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="horizontal"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            import mx.events.CollectionEvent;
            import mx.events.CollectionEventKind;
            import mx.events.TreeEvent;

            private function tree_itemOpening(evt:TreeEvent):void {
                arrColl.addItem({type:evt.type, label:evt.item.@label, opening:evt.opening});
            }

            private function arrColl_collectionChange(evt:CollectionEvent):void {
                switch (evt.kind) {
                    case CollectionEventKind.ADD:
                        callLater(autoScroll);
                        break;
                }
            }

            private function autoScroll():void {
                dataGrid.verticalScrollPosition = dataGrid.maxVerticalScrollPosition;
            }
        ]]>
    </mx:Script>

    <mx:ArrayCollection id="arrColl"
            collectionChange="arrColl_collectionChange(event);" />

    <mx:XMLListCollection id="xmlListColl">
        <mx:source>
            <mx:XMLList>
                <node label="One">
                    <node label="One.1">
                        <node label="One.1.1">
                            <node label="One.1.1.1">
                                <node label="One.1.1.1.1" />
                            </node>
                        </node>
                    </node>
                    <node label="One.2" />
                    <node label="One.3" />
                </node>
                <node label="Two">
                    <node label="Two.1" />
                    <node label="Two.2" />
                    <node label="Two.3" />
                </node>
            </mx:XMLList>
        </mx:source>
    </mx:XMLListCollection>

    <mx:Tree id="tree"
            dataProvider="{xmlListColl}"
            labelField="@label"
            width="250"
            rowCount="6"
            showScrollTips="true"
            itemOpening="tree_itemOpening(event);" />

    <mx:DataGrid id="dataGrid"
            dataProvider="{arrColl}"
            verticalScrollPolicy="on"
            width="100%"
            height="{tree.height}">
        <mx:columns>
            <mx:DataGridColumn dataField="type" />
            <mx:DataGridColumn dataField="label" />
            <mx:DataGridColumn dataField="opening" />
        </mx:columns>
    </mx:DataGrid>

</mx:Application>

View source is enabled in the following example.

0 thoughts on “Detecting when a user opens or closes a Tree control in Flex

  1. Great post! I have a question along these lines that maybe you have run up against? I am trying to load a large amount of data into a tree, but only want to load the top-level nodes and then, when a user expands a node, go get that node’s data from the server. This would allow the tree to load much faster (I think) since it would not need to pull all the data back at once, just one node at a time. Have you seen this done before? Any suggestions would be appreciated.