Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / guides / tree / README.md
1 # Trees
2 ______________________________________________
3
4 The {@link Ext.tree.Panel Tree Panel} Component is one of the most versatile Components in Ext JS and is an excellent tool for displaying heirarchical data in an application.  Tree Panel extends from the same class as {@link Ext.grid.Panel Grid Panel}, so all of the benefits of Grid Panels - features, extensions, and plugins can also be used on Tree Panels. Things like columns, column resizing, dragging and dropping, renderers, sorting and filtering can be expected to work similarly for both components.
5
6 Let's start by creating a very simple Tree.
7
8     @example
9     Ext.create('Ext.tree.Panel', {
10         renderTo: Ext.getBody(),
11         title: 'Simple Tree',
12         width: 150,
13         height: 150,
14         root: {
15             text: 'Root',
16             expanded: true,
17             children: [
18                 {
19                     text: 'Child 1',
20                     leaf: true
21                 },
22                 {
23                     text: 'Child 2',
24                     leaf: true
25                 },
26                 {
27                     text: 'Child 3',
28                     expanded: true,
29                     children: [
30                         {
31                             text: 'Grandchild',
32                             leaf: true
33                         }
34                     ]
35                 }
36             ]
37         }
38     });
39
40 This Tree Panel renders itself to the document body.  We defined a root node that is expanded by default. The root node has three children, the first two of which are leaf nodes which means they cannot have any children.  The third node is not a leaf node and has has one child leaf node.  The `text` property is used as the node's text label. See [Simple Tree](guides/tree/examples/simple_tree/index.html) for a live demo.
41
42 Internally a Tree Panel stores its data in a {@link Ext.data.TreeStore TreeStore}. The above example uses the {@link Ext.tree.Panel#root root} config as a shortcut for configuring a store.  If we were to configure the store separately, the code would look something like this:
43
44     var store = Ext.create('Ext.data.TreeStore', {
45         root: {
46             text: 'Root',
47             expanded: true,
48             children: [
49                 {
50                     text: 'Child 1',
51                     leaf: true
52                 },
53                 {
54                     text: 'Child 2',
55                     leaf: true
56                 },
57                 ...
58             ]
59         }
60     });
61
62     Ext.create('Ext.tree.Panel', {
63         title: 'Simple Tree',
64         store: store,
65         ...
66     });
67
68 For more on {@link Ext.data.Store Store}s see the [Data Guide](#/guide/data).
69
70
71 ## The Node Interface
72 In the above examples we set a couple of different properties on tree nodes. But what are nodes exactly? As mentioned before, the Tree Panel is bound to a {@link Ext.data.TreeStore TreeStore}. A Store in Ext JS manages a collection of {@link Ext.data.Model Model} instances. Tree nodes are simply Model instances that are decorated with a {@link Ext.data.NodeInterface NodeInterface}.  Decorating a Model with a NodeInterface gives the Model the fields, methods and properties that are required for it to be used in a tree.  The following is a screenshot that shows the structure of a node in the developer tools.
73
74 {@img nodeinterface.png A model instance decorated with the NodeInterface}
75
76 In order to see the full set of fields, methods and properties available on nodes, see the API documentation for the {@link Ext.data.NodeInterface NodeInterface} class.
77
78 ## Visually changing your tree
79 Let's try something simple. When you set the {@link Ext.tree.Panel#useArrows useArrows} configuration to true, the Tree Panel hides the lines and uses arrows as expand and collapse icons.
80
81 {@img arrows.png Arrows}
82
83 Setting the {@link Ext.tree.Panel#rootVisible rootVisible} property to false visually removes the root node. By doing this, the root node will automatically be expanded. The following image shows the same tree with `rootVisible` set to false and {@link Ext.tree.Panel#lines lines} set to false.
84
85 {@img root-lines.png Root not visible and no lines}
86
87 ## Multiple columns
88 Since {@link Ext.tree.Panel Tree Panel} extends from the same base class as {@link Ext.grid.Panel Grid Panel} adding more columns is very easy to do.
89
90     @example
91     var tree = Ext.create('Ext.tree.Panel', {
92         renderTo: Ext.getBody(),
93         title: 'TreeGrid',
94         width: 300,
95         height: 150,
96         fields: ['name', 'description'],
97         columns: [{
98             xtype: 'treecolumn',
99             text: 'Name',
100             dataIndex: 'name',
101             width: 150,
102             sortable: true
103         }, {
104             text: 'Description',
105             dataIndex: 'description',
106             flex: 1,
107             sortable: true
108         }],
109         root: {
110             name: 'Root',
111             description: 'Root description',
112             expanded: true,
113             children: [{
114                 name: 'Child 1',
115                 description: 'Description 1',
116                 leaf: true
117             }, {
118                 name: 'Child 2',
119                 description: 'Description 2',
120                 leaf: true
121             }]
122         }
123     });
124
125 The {@link Ext.tree.Panel#columns columns} configuration expects an array of {@link Ext.grid.column.Column} configurations just like a {@link Ext.grid.Panel Grid Panel} would have.  The only difference is that a Tree Panel requires at least one column with an xtype of 'treecolumn'.  This type of column has tree-specific visual effects like depth, lines and expand and collapse icons. A typical Tree Panel would have only one 'treecolumn'.
126
127 The `fields` configuration is passed on to the Model that the internally created Store uses (See the [Data Guide](#/guide/data) for more information on {@link Ext.data.Model Model}s). Notice how the {@link Ext.grid.column.Column#dataIndex dataIndex} configurations on the columns map to the fields we specified - name and description.
128
129 It is also worth noting that when columns are not defined, the tree will automatically create one single `treecolumn` with a `dataIndex` set to 'text'. It also hides the headers on the tree. To show this header when using only a single column set the `hideHeaders` configuration to 'false'.
130
131 ## Adding nodes to the tree
132
133 The root node for the Tree Panel does not have to be specified in the initial configuration.  We can always add it later:
134
135     var tree = Ext.create('Ext.tree.Panel');
136     tree.setRootNode({
137         text: 'Root',
138         expanded: true,
139         children: [{
140             text: 'Child 1',
141             leaf: true
142         }, {
143             text: 'Child 2',
144             leaf: true
145         }]
146     });
147
148 Although this is useful for very small trees with only a few static nodes, most Tree Panels will contain many more nodes. So let's take a look at how we can programmatically add new nodes to the tree.
149
150     var root = tree.getRootNode();
151
152     var parent = root.appendChild({
153         text: 'Parent 1'
154     });
155
156     parent.appendChild({
157         text: 'Child 3',
158         leaf: true
159     });
160
161     parent.expand();
162
163 Every node that is not a leaf node has an {@link Ext.data.NodeInterface#appendChild appendChild} method which accepts a Node, or a config object for a Node as its first parameter, and returns the Node that was appended. The above example also calls the {@link Ext.data.NodeInterface#expand expand} method to expand the newly created parent.
164
165 {@img append-children.png Appending to the tree}
166
167 Also useful is the ability to define children inline when creating the new parent nodes. The following code gives us the same result.
168
169     var parent = root.appendChild({
170         text: 'Parent 1',
171         expanded: true,
172         children: [{
173             text: 'Child 3',
174             leaf: true
175         }]
176     });
177
178 Sometimes we want to insert a node into a specific location in the tree instead of appending it. Besides the `appendChild` method, {@link Ext.data.NodeInterface} also provides {@link Ext.data.NodeInterface#insertBefore insertBefore} and {@link Ext.data.NodeInterface#insertChild insertChild} methods.
179
180     var child = parent.insertChild(0, {
181         text: 'Child 2.5',
182         leaf: true
183     });
184
185     parent.insertBefore({
186         text: 'Child 2.75',
187         leaf: true
188     }, child.nextSibling);
189
190 The `insertChild` method expects an index at which the child will be inserted. The `insertBefore` method expects a reference node. The new node will be inserted before the reference node.
191
192 {@img insert-children.png Inserting children into the tree}
193
194 NodeInterface also provides several more properties on nodes that can be used to reference other nodes.
195
196 * {@link Ext.data.NodeInterface#nextSibling nextSibling}
197 * {@link Ext.data.NodeInterface#previousSibling previousSibling}
198 * {@link Ext.data.NodeInterface#parentNode parentNode}
199 * {@link Ext.data.NodeInterface#lastChild lastChild}
200 * {@link Ext.data.NodeInterface#firstChild firstChild}
201 * {@link Ext.data.NodeInterface#childNodes childNodes}