TreeGrid Component

Overview

Applications often need to display information in a grid format while also allowing a parent/child relationship between grid rows. The TreeGrid component supports this concept by making some assumptions about the model passed to the dataProvider for the Grid. All objects in the dataProvider must implement the interface org.osflex.ITreeGridNode. This interface allows metadata about the tree state to be derived from the data model.

Demo

The TreeGrid in action you can find there. If you haven't installed Adobe Flex Player 9 you can see the screenshot of the component.

Downloading

You can download the current version here.

Quick start

If you have an existing model object that you want to display in a TreeGrid the first step is to implement the ITreeGridNode interface on the object. You can either implement the interface on the object directly or create a wrapper object that extends the model object. Then you should add a list of root objects to the ArrayCollection and assign it to the dataProvider property of the TreeGrid. But if you want to use all features of the TreeGrid you should use the TreeGridDataProvider or your own implementation of the ITreeGridDataProvider. Now the ITreeDataProvider allows you to use sorting but in the future a functionality will be gained.

Model Object
package org.osflex.example {
    
    import mx.collections.ArrayCollection;
    
    /**
     * Simple model object
     */
    public class ModelObject {
        
        /** Collection that holds children */

        protected var childData:ArrayCollection = new ArrayCollection();
        
        /** 'Name' field */
        public var name:String;
        
        /** 'Description' field */

        public var description:String;
        
        /** Extra data field */
        public var data1:String;
        
        /**
         * Create an instance of the object.

         */
        public function ModelObject(name:String, desc:String, data1:String) {
            this.name = name;
            this.description = desc;
            this.data1 = data1;
        }
    }
}	

Wrapper Object
package org.osflex.example {
    
    import mx.collections.ArrayCollection;
    import mx.collections.ICollectionView;
    
    import org.osflex.ITreeGridNode;
    import org.osflex.TreeGridNodeHelper;

    public class TreeGridObject extends ModelObject implements ITreeGridNode {
        
        /** Helper class for keeping up with state info */
        protected var helper:TreeGridNodeHelper = new TreeGridNodeHelper();
        
        /**
         * Create the wrapper object.
         */
        public function TreeGridObject(name:String, desc:String, data1:String) {
            super(name, desc, data1);
        }
        
        /**
         * Add a child node.
         */
        public function addChild(child:TreeGridObject):void {
            childData.addItem(child);
            child.indentLevel = this.indentLevel + 1;
        }
        
        //
        // Methods required by the ITreeGridNode interface.
        //
        public function toggleOpen():void {
            helper.toggleOpen();
        }
        
        public function get open():Boolean {
            return helper.open;
        }
        
        public function get children():ICollectionView {
            return childData;
        }
        
        public function get indentLevel():Number {
            return helper.indentLevel;
        }
        
        public function set indentLevel(level:Number):void {
            helper.indentLevel = level;
        }
    }
}
	

Note that the org.osflex.TreeGridNodeHelper object can be used to simplify the wrapper class.

If the model object cannot implements interface (if it obtained from RemoteService or another way) you can use TreeGridNodeProxy object that is the Proxy pattern.

Proxy Object
    // Create mock model objects for example
    var entityObject1: EntityObject = new EntityObject("Entity 1", "Entity 1 level node", 100);  
    var entityObject1_1: EntityObject = new EntityObject("Entity 1-1", "Entity 1-1 level node", 100);
    // Create proxy node for each model object
    var node1: TreeGridNodeProxy = new TreeGridNodeProxy(entityObject1);
    var node1_1: TreeGridNodeProxy = new TreeGridNodeProxy(entityObject1_1);
    // node1_1 is a child for node1
    node1.addChild(node1_1);    
    

MXML

MXML for the TreeGrid is similar to a normal grid with the exception of the column that contains the expand/contract icons. A custom cell renderer is configured for that column using the org.osflex.TreeGridCellRenderer class.

MXML Example
<osflex:TreeGrid width="100%" height="100%" sortableColumns="false" dataProvider="{exampleData}">
    <osflex:columns>
        <mx:DataGridColumn headerText="Name"
            dataField="name" width="100"
            showDataTips="true" dataTipField="name">
            <mx:itemRenderer>
                <mx:Component>
                    <osflex:TreeGridCellRenderer indentPixels="15"/> 
                </mx:Component>
            </mx:itemRenderer>
        </mx:DataGridColumn>
        <mx:DataGridColumn headerText="Description" 
            dataField="description" width="200"/>
        <mx:DataGridColumn headerText="Other Data" 
            dataField="data1" width="75"/>
    </osflex:columns>
</osflex:TreeGrid>

You can find all examples in file osflex.example-{version}.zip.