Here, we'll see more features of trees.
The tree element is also used to create hierarchical lists, like that found in a file manager or a browser's bookmarks list. The tree view has a number of functions which specify the hierarchy of the items in a tree. Each item in the tree has a level starting at 0. The topmost items in the tree will have a level of 0, the children of those items will have a level of 1, the children below that will have a level of 2, and so on. The tree will query the view for the level of each item in order to determine how to draw the rows.
The tree will draw the open and close icons to open and close a parent item as well as lines connecting the children to their parents. The tree will also handle drawing the rows with the right level of indenting. However, the view will need to make sure it keeps track of the level of the rows as necessary. This can sometimes be quite tricky, but fortunately, the built-in content tree view does all of the hard work for us.
To create a set of nested rows, all we need to do is add a second
treechildren element inside the parent
treeitem. You can then add items inside that to specify the child rows of an item. Don't put the inner
treechildren element inside the
treerow as this won't work.
You can repeat this process to create deeply nested trees. Essentially, a
treeitem element can contain either single rows which are declared with the
treerow element or a set of rows which are declared with the
There are two other things you need to do to make sure the hierarchy works properly. First, you need to mark the
treeitem element that has children as a container. You do this by adding the
container attribute to it as follows:
<treeitem container="true" />
This allows the user to click on the row that corresponds to the
treeitem to expand and collapse the inner rows. You can have the child rows initially displayed by adding the
open attribute. When the user expands and collapses the parent, the view's toggleOpenState function will be called to toggle the item between open and closed. For a content tree view, this will set the
open attribute to reflect the current state.
The second change is that you must put the
primary attribute on the first column. This causes a small triangle or plus sign to appear before the cells in that column to indicate the cells that can be expanded. In addition, child rows are indented. Note also that the user cannot hide the primary column using the drop down to the right of the columns.
Example hierarchical tree
The following is a simple example:
<tree rows="6"> <treecols> <treecol id="firstname" label="First Name" primary="true" flex="3" /> <treecol id="lastname" label="Last Name" flex="7" /> </treecols> <treechildren> <treeitem container="true" open="true"> <treerow> <treecell label="Guys" /> </treerow> <treechildren> <treeitem> <treerow> <treecell label="Bob" /> <treecell label="Carpenter" /> </treerow> </treeitem> <treeitem> <treerow> <treecell label="Jerry" /> <treecell label="Hodge" /> </treerow> </treeitem> </treechildren> </treeitem> </treechildren> </tree>
This has created a hierarchical tree. As can be seen in the image, a small plus or minus sign (often called a twisty) has appeared next to the first row, indicating that it contains child rows. By clicking the row, the user can open and close the list. The child rows are indented. Notice how the Guys row only needs one column as it is a placeholder item for its children.
You can nest rows deeper as well. Remember that you must use the
container attribute on rows which contain child rows. The simple presence of child rows isn't sufficient to indicate this, as you may have a container that has no children but should still be treated like a container. For example, a directory with no files in it should still be treated like a container whereas a file should not.
More about Tree Columns
One additional attribute you can add to the tree is
enableColumnDrag. (Note the mixed case.) If set to
true, the user may drag the column headers around to rearrange the order of the columns.
A user will also likely want to change the column widths. You can do this by placing a
splitter element in between each
treecol element. A small notch will appear in between each column header which the user may drag to change the width of a column. You can use the style class
tree-splitter to hide the notch, although the column may still be resized.
You can set the
true to have the column hidden by default. The user can choose to show the column by selecting it from the drop-down on the end of the header row.
Remembering State of Columns
As with all elements, the
persist attribute can be used to save the state of the columns in-between sessions. (That feature will see in the later section). Thus, once the user has decided on a column layout they like, it will automatically be saved for next time. You will need to save a number of attributes as indicated in the example below:
<tree enableColumnDrag="true" flex="1"> <treecols> <treecol id="runner" label="Runner" flex="2" persist="width ordinal hidden" /> <splitter class="tree-splitter" /> <treecol id="city" label="Home City" flex="2" persist="width ordinal hidden" /> <splitter class="tree-splitter" /> <treecol id="starttime" label="Start Time" flex="1" persist="width ordinal hidden" /> <splitter class="tree-splitter" /> <treecol id="endtime" label="End Time" flex="1" persist="width ordinal hidden" /> </treecols> <treechildren> <treeitem> <treerow> <treecell label="Joshua Granville" /> <treecell label="Vancouver" /> <treecell label="7:06:00" /> <treecell label="9:10:26" /> </treerow> </treeitem> <treeitem> <treerow> <treecell label="Robert Valhalla" /> <treecell label="Seattle" /> <treecell label="7:08:00" /> <treecell label="9:15:51" /> </treerow> </treeitem> </treechildren> </tree>
Three attributes of the columns must be persisted,
widthattribute to save the column widths,
ordinalattribute which holds the position of the column,
- and the attribute which holds whether the column is hidden or visible.
Next, we'll find out to get and set the selection for trees.