Tree widget
Concept
The tree widget is for displaying trees of "things". The tree widget supports expanding and collapsing of nodes, single or multiple selections, and a flexible TreeModel interface to provide its data.
Definition
<fd:tree id="..." state="..." root-visible="true" selection="multiple|single"> <fd:tree-model type="..."/> <fd:on-selection-changed> ... </fd:on-selection-changed> <fd:on-create> ... </fd:on-create> <fd:validation> ... </fd:validation> <fd:attributes> ... </fd:attributes> </fd:tree>
All elements and attributes, except for id, are optional.
See the field widget for information on common attributes and elements.
The tree model
See the interface TreeModel. Essentially, can be a tree of any sort of objects (there is no interface for the nodes in the tree). Each parent node should be able to identify its children uniquely by means of a key (some string).
CForms ships with two implementations of TreeModel: one generic implementation (DefaultTreeModel), and one for browsing over Cocoon/Avalon sources (= filesystem-like structures).
You can set the form model in the form definition, or set it at runtime using the setModel method on the tree widget.
Source tree model
Syntax:
<fd:tree-model type="source" src="..."> <fd:fileset> <fd:include pattern="..."/> <fd:exclude pattern="..."/> </fd:fileset> <fd:dirset> <fd:include pattern="..."/> <fd:exclude pattern="..."/> </fd:dirset> </fd:tree-model>
The src attribute defines the root of the content to be browsed. For example, to browse the content of the webapp directory, specify src="context://". Of course, you can also use "file://" or other traversable sources [todo: link to some page with info about sources].
The fd:fileset and fd:dirset elements are optional. The fileset patterns are used to filter files based on their name, and the dirset patterns are used to filter directories based on their names.
There can be multiple (or none at all) fd:include and fd:exclude elements inside fd:fileset or fd:dirset. The include patterns will be evaluated first, the exclude patterns next, so the exclude patterns have higher precendence.
The patterns are wildcard patterns. They are the same as for the wildcard matcher in the sitemap, thus simply use a * as wildcard (the ** syntax makes no sense here, as the pattern is evaluated on individual names, not on full paths).
Custom models
Syntax:
<fd:tree-model type="java" class="..."/>
whereby the class attribute specifies a class implementing TreeModel. The class can implement Avalon interfaces to get the Logger, ServiceManager and Context.
Programmatically assigning a model
Here's an example of how to build a tree model programatically using the provided DefaultTreeModel in flowscript:
importClass(Packages.org.apache.cocoon.forms.formmodel.tree.DefaultTreeModel); [...] var node1 = new DefaultTreeModel.DefaultTreeNode("node 1") var node2 = new DefaultTreeModel.DefaultTreeNode("node 2") var root = new DefaultTreeModel.DefaultTreeNode("root") root.add("node1", node1); node1.add("node2", node2); var treeModel = new DefaultTreeModel(root); var treeWidget = form.getChild("mytree"); treeWidget.setModel(treeModel);
Template
For the display of a tree widget, three special template elements are available:
- ft:tree: global element to insert a tree widget in the template. This also inserts two hidden fields, ":path" and ":action" to communicate a node action to the server, see below.
- ft:tree-nodes: the template to be executed for each tree node.
- ft:tree-children: used inside ft:tree-nodes to recursively apply the ft:tree-nodes template to the child nodes.
A very rough example is:
<ft:tree id="mytree"> <div> <ft:tree-nodes> <div> ${treeNode.node.data} </div> <ft:tree-children/> </ft:tree-nodes> </div> </ft:tree>
This example just shows the typical structural rendering, but doesn't contain any styling and javascript actions to trigger expansion and collapsion of nodes.
Inside ft:tree you have access to two variables:
- treeWidget, just a synonym for the normal "widget" variable that is available in the template of each widget.
- treeNode, provides access to the current tree node being rendered. More specifically it is a TreeWalker instance. Its node property gives access to the actual tree node.
Tree node actions
An action can be executed on a certain node in the tree. The available actions are:
- expand
- collapse
- toggle-collapse
- select
- unselect
- toggle-select
To execute an action, set the hidden field named tree-widget-full-name + ":action" to one of the actions listed above. The node on which the action is applied is specified in the hidden field named tree-widget-full-name + ":path". The node is specified as a slash-separated path of node keys. In the template you can access this easily with treeNode.path.
A more functional template
For a complete example of a tree template, see e.g. the file_explorer_template.xml file in the CForms samples. From there, you can "steal" the styling and the javascript to perform tree node actions.
API notes
See the API docs of the tree widgets for more information on how to access e.g. the selected nodes.
Errors and Improvements? If you see any errors or potential improvements in this document please help us: View, Edit or comment on the latest development version (registration required).