Last updated April 22, 2009 16:33, by Jason Lee
==<sc:tree> - A YUI Tree Wrapper==
__TOC__
This component will allow you to create an expandable tree containing arbitrary components. The tree can be used in one of two ways: facet-based or <code>UIComponent</code>-based.
=== UIComponent-based Approach ===
The <code>UIComponent</code>-based form of usage is via nested <code>UIComponent</code>s, <code>sc:treeNode</code>, which currently supports <code>label</code> and <code>expanded</code> attributes. Each <code>sc:treeNode</code> must have either the <code>label</code> attribute, or a <code>f:facet</code> named label. If <code>exanded</code> is set to true, that node (and every node above it in its hierarchy) will be rendered expanded. Below is a simple example of this form:
<textarea name="code" class="xml"><nowiki>
<sc:tree>
<sc:treeNode id="ui1" expanded="true" label="Node 1">
<sc:treeNode label="Node 1-1"/>
<sc:treeNode label="Node 1-2"/>
</sc:treeNode>
<sc:treeNode label="Node 2">
<sc:treeNode label="Node 2-1"/>
<sc:treeNode label="Node 2-2"/>
</sc:treeNode>
<sc:treeNode label="Node 3">
<sc:treeNode label="Node 3-1"/>
<sc:treeNode label="Node 3-2">
<sc:treeNode label="Node 3-2-1" expanded="true"/>
</sc:treeNode>
</sc:treeNode>
</sc:tree>
</nowiki></textarea>
This will render as:
[[image:treeuicomponent.png]]
=== Facet-based Approach ===
The facet-based approach allows the application author to define "templates" for an application-specific node type using a facet whose name is the type. The application model data is then passed to the component using the <code>value</code> attribute, which must be a <code>List<ITreeNode</code>, as show below:
<textarea name="code" class="xml"><nowiki>
<sc:tree value="#{testBean.newTree}" var="item">
<f:facet name="file">
<h:panelGroup>
<h:outputText value="#{item.name}"/>
</h:panelGroup>
</f:facet>
<f:facet name="dir">
<h:panelGroup>
<h:outputText value="#{item.name}"/>
</h:panelGroup>
</f:facet>
</sc:tree>
</nowiki></textarea>
Before looking at the component in more detail, this is how it will render:
[[image:tree.png]]
Note that we define two facets, <code>file</code> and <code>directory</code>. These are application-specific types that we'll define in our model in Java code. The tree itself is bound to <code>#{testBean.newTree}</code>. The implementation of that method itself isn't very interesting, but the signature is:
<textarea name="code" class="java"><nowiki>
public List<ITreeNode> getNewTree() {
List<ITreeNode> list = new ArrayList<ITreeNode>();
// snip
return list;
}
</nowiki></textarea>
This method creates a list of <code>ITreeNode</code> objects, which defines the top-level items in the tree. Each item in the <code>List</code> is also an <code>ITreeNode</code> object, which looks like this:
<textarea name="code" class="java"><nowiki>
public interface ITreeNode {
String getType();
List<ITreeNode> getChildren();
}
</nowiki></textarea>
To use one of your classes in the tree, the class must implement <code>ITreeNode</code>. The <code>type</code> property on the interface tells <code><sc:tree></code> how to render that particular item. For example, in the Scales demo, we have <code>FileItem</code>, which returns <code>"file"</code> as its type. When rendering, <code><sc:tree></code> see that a particular item in the object graph has type <code>file</code> so it renders it based on the contents of the <code>file</code> facet. The number and depth of items in tree is limited only by the system resources of the server.





