Create new RichFaces Documentation Jira issue

This will launch the RichFaces Jira page - to complete your feedback please login if needed, and submit the Jira.

JBoss.orgCommunity Documentation

6.9.1.  < rich:tree > available since 3.0.0

The component is designed for hierarchical data presentation and is applied for building a tree structure with a drag-and-drop capability.


Table 6.181. rich : tree attributes

Attribute Name Description
acceptCursorsList of comma separated cursors that indicates when acceptable draggable over dropzone
acceptedTypesA list of drag zones types, which elements are accepted by a drop zone
adviseNodeOpenedMethodBinding pointing at a method accepting an org.richfaces.component.UITree with return of java.lang.Boolean type. If returned value is: java.lang.Boolean. TRUE, a particular treeNode is expanded; java.lang.Boolean.FALSE, a particular treeNode is collapsed; null, a particular treeNode saves the current state
adviseNodeSelectedMethodBinding pointing at a method accepting an org.richfaces.component.UITree with return of java.lang.Boolean type. If returned value is: java.lang.Boolean. TRUE, a particular treeNode is selected; java.lang.Boolean.FALSE, a particular treeNode is unselected; null, a particular treeNode saves the current state
ajaxChildActivationEncodeBehaviorDefines which nodes keys will be added to AjaxNodeKeys automatically on the request from the children of the node. Values: "none" - nothing, "node" - only current node, "subtree" - node and all its children.
ajaxKeysThis attribute defines row keys that are updated after an AJAX request.
ajaxNodeKeysKeys of the nodes (without subtree) to be updated for ajax request risen by the node itself
ajaxNodeSelectionEncodeBehaviorDefines which nodes keys will be added to AjaxNodeKeys automatically on selecting ajax request from the node. Values: "none" - nothing, "node" - only current node, "subtree" - node and all its children.
ajaxSingleLimits JSF tree processing (decoding, conversion, validation and model updating) only to a component that sends the request. Boolean
ajaxSubmitSelectionIf "true", an Ajax request to be submit when selecting node. Default value is "false".
binding JSF: The attribute takes a value-binding expression for a component property of a backing bean
bypassUpdatesIf "true", after process validations phase it skips updates of model beans on a force render response. It can be used for validating components input
changeExpandListenerListener called on expand/collapse event on the node
componentStateIt defines EL-binding for a component state for saving or redefinition
cursorTypeMappingMapping between drop types and acceptable cursors
dataSerialized (on default with JSON) data passed on the client by a developer on AJAX request. It's accessible via "data.foo" syntax
disableKeyboardNavigationDisables keyboard navigation. Default value is "false"
dragIndicatorId of a component that is used as drag pointer during the drag operation
dragListenerMethodBinding representing an action listener method that will be notified after drag operation
dragTypeA drag zone type that is used for zone definition, which elements can be accepted by a drop zone
dragValueData to be sent to the drop zone after a drop event. Default value is "getRowKey()".
dropListenerMethodBinding representing an action listener method that will be notified after drop operation
dropValueData to be processed after a drop event. Default value is "getRowKey()".
eventsQueueName of requests queue to avoid send next request before complete other from same event. Can be used to reduce number of requests of frequently events (key press, mouse move etc.)
focusID of an element to set focus after request is completed on client side
grabbingCursorsList of comma separated cursors that indicates when you has grabbed something
grabCursorsList of comma separated cursors that indicates when you can grab and drag an object
highlightedClassAssigns one or more space-separated CSS class names to the component highlighted node
iconThe icon for node
iconCollapsedThe icon for collapsed node
iconExpandedThe icon for expanded node
iconLeafAn icon for component leaves
id JSF: Every component may have a unique id that is automatically created if omitted
ignoreDupResponsesAttribute allows to ignore an Ajax Response produced by a request if the newest 'similar' request is in a queue already. ignoreDupResponses="true" does not cancel the request while it is processed on the server, but just allows to avoid unnecessary updates on the client side if the response isn't actual now
immediateA flag indicating that this component value must be converted and validated immediately (during an Apply Request Values phase), rather than waiting until a Process Validations phase
limitToListIf "true", then of all AJAX-rendered on the page components only those will be updated, which ID's are passed to the "reRender" attribute of the describable component. "false"-the default value-means that all components with ajaxRendered="true" will be updated.
nodeFaceNode face facet name
nodeSelectListenerMethodBinding representing an action listener method that will be notified after selection of node.
onbeforedomupdateThe client-side script method to be called before DOM is updated
onclick DHTML: The client-side script method to be called when the element is clicked
oncollapseThe client-side script method to be called when a node is collapsed
oncompleteThe client-side script method to be called after the request is completed
oncontextmenuThe client-side script method to be called when the right mouse button is clicked over the component. Returning false prevents a default browser context menu from being displayed.
ondblclick DHTML: The client-side script method to be called when the element is double-clicked
ondragendThe client-side script method to be called when the dragging operation is finished
ondragenterThe client-side script method to be called when a draggable object enters the zone
ondragexitThe client-side script method to be called after a draggable object leaves the zone
ondragstartThe client-side script method to be called when the dragging operation is started
ondropThe client-side script method to be called when something is dropped into the drop zone
ondropendThe client-side script method to be called when a draggable object is dropped into any zone
ondropoutThe client-side script method to be called when the draggable object is moved away from the drop zone
ondropoverThe client-side script method to be called when the draggable object is over the drop zone
onexpandThe client-side script method to be called when a node is expanded
onkeydown DHTML: The client-side script method to be called when a key is pressed down over the element
onkeypress DHTML: The client-side script method to be called when a key is pressed over the element and released
onkeyup DHTML: The client-side script method to be called when a key is released
onmousedown DHTML: The client-side script method to be called when a mouse button is pressed down over the element
onmousemove DHTML: The client-side script method to be called when a pointer is moved within the element
onmouseout DHTML: The client-side script method to be called when a pointer is moved away from the element
onmouseover DHTML: The client-side script method to be called when a pointer is moved onto the element
onmouseup DHTML: The client-side script method to be called when a mouse button is released
onselectedThe client-side script method to be called when a node is selected
preserveDataInRequestIf "true", data is preserved in a request. Default value is "true".
preserveModelPossible values are "state", "request", "none". Default value is "request"
processId['s] (in format of call UIComponent.findComponent()) of components, processed at the phases 2-5 in case of AjaxRequest caused by this component. Can be single id, comma-separated list of Id's, or EL Expression with array or Collection
rejectCursorsList of comma separated cursors that indicates when rejectable draggable over dropzone
rendered JSF: If "false", this component is not rendered
requestDelayAttribute defines the time (in ms.) that the request will be wait in the queue before it is ready to send. When the delay time is over, the request will be sent to the server or removed if the newest 'similar' request is in a queue already
reRenderId['s] (in format of call UIComponent.findComponent()) of components, rendered in case of AjaxRequest caused by this component. Can be single id, comma-separated list of Id's, or EL Expression with array or Collection
rightClickSelectionAllow to select tree item using mouse right click
rowKeyConverterConverter for a row key object
rowKeyVarThe attribute provides access to a row key in a Request scope
selectedClassAssigns one or more space-separated CSS class names to the component selected node
showConnectingLinesIf "true", connecting lines are show
similarityGroupingIdIf there are any component requests with identical IDs then these requests will be grouped.
stateAdvisorValueBinding pointing at instance of class implementing org.richfaces.component.state.TreeStateAdvisor interface.
stateVarThe attribute provides access to a component state on the client side
statusID (in format of call UIComponent.findComponent()) of Request status component
styleHTML: CSS style rules to be applied to the component
styleClass JSF: Assigns one or more CSS class names to the component. Corresponds to the HTML "class" attribute.
switchTypeTree Nodes switch mode: "client", "server", "ajax"
timeoutResponse waiting time on a particular request. If a response is not received during this time, the request is aborted
toggleOnClickIf "false" do not toggle node state on click. If "true", than node will be toggles on click on ether node content, or node icon. Default value is "false".
treeNodeVarThe attribute provides access to a TreeNode instance in a Request scope
typeMappingThe attribute associates a type of dragable zone (dragType) with <rich:dndParam> defined for <rich:dropSupport> for passing parameter value to <rich:dragIndicator>. It uses JSON format: (drag_type: parameter_name).
value JSF: The current value for this component
varAttribute contains a name providing an access to data defined with value

Table 6.182. Component identification parameters

NameValue
component-typeorg.richfaces.Tree
component-classorg.richfaces.component.html.HtmlTree
component-familyorg.richfaces.Tree
renderer-typeorg.richfaces.TreeRenderer
tag-classorg.richfaces.taglib.TreeTag

There are two ways to set up a tree

Example:

import org.richfaces.component.html.HtmlTree;

...
HtmlTree myTree = new HtmlTree();
...

As it has been mentioned above the <rich:tree> component allows rendering any tree-like data model.

You can build your <rich:tree> using model (org.richfaces.model.TreeNode or javax.swing.tree.TreeNode). In this case the <rich:tree> component interacts with data model via "TreeNode" interface ( org.richfaces.model.TreeNode ) that is used for the <rich:tree> nodes representation.

Actually you can develop and use your own implementation of the "TreeNode" interface or use a default one, which is defined with a default class "TreeNodeImpl" ( org.richfaces.model.TreeNodeImpl ).

The "value" attribute of the <rich:tree> component contains a nodes structure defined in a bean property.

When the <rich:tree> component is being rendered it iterates over the model nodes and renders them using one of its immediate <rich:treeNode> children. Data property of the current model TreeNode is exposed using "var" attribute, so if var="station" you can refer to that data using #{station} syntax.

In the following example the <rich:tree> is built from a simple org.richfaces.model.TreeNode model:

...

private TreeNodeImpl<String> stationRoot = new TreeNodeImpl<String>();
private TreeNodeImpl<String> stationNodes = new TreeNodeImpl<String>(); 
private String[] kickRadioFeed = { "Hall & Oates - Kiss On My List",
    "David Bowie - Let's Dance", "Lyn Collins - Think (About It)",
    "Kim Carnes - Bette Davis Eyes",
    "KC & the Sunshine Band - Give It Up" };
    ... 
stationRoot.setData("KickRadio");
stationNodes.addChild(0, stationRoot);
for (int i = 0; i < kickRadioFeed.length; i++){
    TreeNodeImpl<String> child = new TreeNodeImpl<String>();
    child.setData(kickRadioFeed[i]);
    stationRoot.addChild(i, child);
}
...

As it is mentioned before you need to pass #{stations.stationNodes} property to the "value" attribute and define the "var" attribute in order to refer to the data:


...
<rich:tree value="#{stations.stationNodes}" var="station">
    <rich:treeNode>
        <h:outputText value="#{station}" />
    </rich:treeNode>
</rich:tree>
...

This is a result:


Implementation of the <rich:tree> component provides another way to build a tree. This approach implies using a "XmlTreeDataBuilder" class ( org.richfaces.component.xml.XmlTreeDataBuilder ) that allows to transform XML into structures of objects containing "XmlNodeData" ( org.richfaces.component.xml.XmlNodeData ) instances as data, which could be represented by the <rich:tree> component.

Let's try to build a simple <rich:tree> from a local XML file. In the following example a simple XML file (stations.xml) is used as a radio station playlist:


<?xml version="1.0"?>
<station name="KickRadio">
        <feed date="today">
            <song time="07:00">Hall & Oates - Kiss On My List</song>
            <song time="07:03">David Bowie - Let's Dance</song> 
            <song time="07:06">Lyn Collins - Think (About It)</song>
            <song time="07:10">Kim Carnes - Bette Davis Eyes</song>
            <song time="07:15">KC & the Sunshine Band - Give It Up</song>
        </feed>
</station>

Now you need to create a bean that holds a model nodes:

...

private TreeNode data;
    ...
FacesContext context = FacesContext.getCurrentInstance();
data = XmlTreeDataBuilder.build(new InputSource(getClass().getResourceAsStream("stations.xml")));
...

Finally you should set the "value" attribute to the data bean property and define the "var" attribute in order to refer to the data of nodes:


...
<rich:tree id="treeXML" value="#{stations.data}" var="vardata">
    <rich:treeNode>
        <h:outputText value="#{vardata.attributes['name']}" />
        <h:outputText value="#{vardata.attributes['date']}" />
        <h:outputText value="#{vardata.attributes['time']}" />
        <h:outputText value=" #{vardata.text}" />
    </rich:treeNode>
</rich:tree>
...

This is a result:


It's possible to define a visual representation of a node data model (to define a node icon) and its behavior in correspondence with the data contained in this node (with a value of the "var" attribute). The node behavior is defined by the components nested into the <rich:treeNode> (e.g. links or buttons). For these purposes you should use "nodeFace" attribute. For each tree node a value of "nodeFace" attribute is evaluated and <rich:treeNode> with a value of "type" attribute equal to a value of "nodeFace" is used for node representation. See an example below.

Example:


...
<h:form>
    <rich:tree style="width:300px" value="#{library.data}" var="item" nodeFace="#{item.type}">
        <rich:treeNode type="artist" iconLeaf="/images/tree/singer.png" icon="/images/tree/singer.png">
            <h:outputText value="#{item.name}" />
        </rich:treeNode>
        <rich:treeNode type="album" iconLeaf="/images/tree/disc.png" icon="/images/tree/disc.png">
            <h:outputText value="#{item.title}" />
        </rich:treeNode>
        <rich:treeNode type="song" iconLeaf="/images/tree/song.png" icon="/images/tree/song.png">
            <h:outputText value="#{item.title}" />
        </rich:treeNode>
    </rich:tree>
</h:form>
...

This is a result:


In the example above, when each node of data model is processed, data contained in the "data" property of "TreeNode" interface is assigned to a request scope variable, which name is defined with "var" attribute. The value of the "nodeFace" attribute is evaluated in correspondence with the data assigned to the "var" attribute. The corresponding <rich:treeNode> component (with a value of "type" attribute equal to a value of "nodeFace" ) is used for the node representation. For example, during data model processing, an object with a name "Chris Rea" was inserted in the "var" attribute. Then the value of "nodeFace" attribute was evaluated as "artist". Thus, for the node representation the <rich:treeNode> with "type" equal to "artist" was used.

You can also assign an EL-expression as value of the "nodeFace" attribute. See an example below:

Example:



nodeFace="#{data.name != 'param-value' ? 'artist' : 'album'}"
 

There are some essential points in a "nodeFace" attribute usage: you need to define notions for typeless and a default nodes.

The typeless node is the first <rich:treeNode> component (from all children nodes nested to the <rich:tree> component) with not defined "type" attribute and defined "rendered" attribute. The typeless node is used for representation when "nodeFace" attribute is null.

Default node has the following interior presentation:

Example:


...
<h:outputText value="#{varAttributeName}">
...

"varAttributeName" is a value for "var" attribute.

Default node is used in the following cases:

  • "nodeFace" attribute is defined, but its value isn't equal to any "type" attribute value from all children nodes;

  • "nodeFace" attribute is defined and its value is equal to a value of some "type" attribute from all children nodes, but the value of "rendered" attribute for this node is "false".

There is also one thing that has to be remembered using "type" and "rendered" attributes: it's possible to define several <rich:treeNode> components with equal values of "type" attribute and different values of "rendered" attribute. It provides a possibility to define different representation styles for the same node types. In the example with artists and their albums (see above) it's possible to represent albums that are available for sale and albums that are not available. Please study the example below:

Example:


...
<h:form>
    <rich:tree style="width:300px" value="#{library.data}" var="item" nodeFace="#{item.type}">
         ...
        <rich:treeNode type="album" iconLeaf="/images/tree/album.gif" icon="/images/tree/album.gif"
                      rendered="#{item.exist}">
            <h:outputText value="#{item.name}" />
        </rich:treeNode>
        <rich:treeNode type="album" iconLeaf="/images/tree/album_absent.gif" icon="/images/tree/album_absent.gif"
                      rendered="#{not item.exist}">
            <h:outputText value="#{item.name}" />
        </rich:treeNode>
         ...
    </rich:tree>
</h:form>
...

This is a result of the code:


In the example the <rich:treeNode> components has equal values of the "type" attribute. Depending on value of the "rendered" attribute the corresponding <rich:treeNode> component is selected for node representation. If an album is available for sale the value of the "rendered" for the first <rich:treeNode> component is "true", for the second one is "false". Thus, the first <rich:treeNode> is selected for node representation.

Tree node can be run in tree modes. Modes can be specified with "switchType" attribute for <rich:tree> component.

  • Ajax (default value) - Ajax submission is used performing the functionality. Note, that for collapse/expand operations an Ajax request is sent to the server and it can cause a short delay.

  • Server - regular form of submission request is used.

  • Client – all operations are performed totally on the client; no interaction with a server is involved. Full page content is reloaded after every action.

The "icon" , "iconCollapsed" , "iconExpanded" , "iconLeaf" attributes set the icons' images for the component. You can also define icons using facets with the same names. If the facets are defined, the corresponding attributes are ignored and facets' content is used as icons. By default the width of a rendered facet area is 16px.

Example:


...
<rich:tree value="#{library.data}" var="item">
    ...
    <f:facet name="icon">
        <h:graphicImage value="/images/tree/singer.png "/>
    </f:facet>
    <f:facet name="iconCollapsed">
        <h:graphicImage value="/images/tree/singer.png" />
    </f:facet>
    <f:facet name="iconExpanded">
        <h:graphicImage value="/images/tree/singer.png" />
    </f:facet>
    <f:facet name="iconLeaf">
        <h:graphicImage value="/images/tree/song.png" />
    </f:facet>
    ...
</rich:tree>
...

The <rich: tree> component can be used together with <rich: treeNodeAdaptor> . In this case there is no need to specify the attributes "value" and "var" . Besides, visual representation shouldn't be defined right in the tree. In this case a <rich: tree> tag is applied mainly for defining common attributes such as "ajaxSubmitSelection" etc.

Information about the "process" attribute usage you can find in the "Decide what to process" guide section.

As it's mentioned before, the <rich:tree> component uses a data model to represent the tree-like nodes structure on the page. To identify a particular node during a client request, the model provides a set of unique keys for tree nodes. The <rich:tree> can use strings as keys values which may contain special characters not allowed by browsers, such as the left angle bracket (<), ampersand (&), ant etc. Thus, to have a possibility to use unallowed characters in the tree nodes keys, the following converters are provided:

  • org.richfaces.TreeRowKeyConverter that is used for "TreeNode" based trees. The key should be of a java.lang.String type.

  • org.richfaces.TreeAdaptorRowKeyConverter that is used for adaptor-based trees (see <rich:treeNodesAdaptor> , <rich:recursiveTreeNodesAdaptor> ). The key should be of a java.lang.String type.

  • org.richfaces.TreeAdaptorIntegerRowKeyConverter which is provided for adaptor-based trees. The key should be of a java.lang.Integer type.

The converters can be extended in order to have a possibility for implementing custom converters.

To apply a converter to the <rich:tree> component, you should define it as a value of the "rowKeyConverter" attribute.

Have a look at the example of a tree which contains the RichFaces components as its nodes and the components attributes as the nodes child elements. As the components have unallowed characters (< and >) in their names, the org.richfaces.TreeRowKeyConverter is used here.

Example:


...
<rich:tree value="#{treeBean.data}" var="node" switchType="ajax"    rowKeyConverter="org.richfaces.TreeRowKeyConverter">
     <rich:treeNode ajaxSingle="true">
          <h:outputText value="#{node}"/>
     </rich:treeNode>
</rich:tree>
...

In the example the tree uses the following data model:

...

String[ ] components = {"< a4j:ajaxListener >", "< a4j:keepAlive >", "< a4j:actionparam >" };
String[ ][ ] attributes = {{"type"},
                                {"ajaxOnly", "beanName"},
                                {"actionListener", "assignTo", "binding", "converter", "id", "name", "noEscape", "value"}};
                               
data = new TreeNodeImpl<String>();
            
for (int i = 0; i < components.length; i++) {
     TreeNode<String> child = new TreeNodeImpl<String>();
     child.setData(components[i]);
     data.addChild(components[i], child);
                
     for (int j = 0; j < attributes[i].length; j++) {
          TreeNode<String> grandChild = new TreeNodeImpl<String>();
          grandChild.setData(attributes[i][j]);
          child.addChild(attributes[i][j], grandChild);
     }
}          
...

Words "built-in" in this context mean, that <rich:tree> component has its own attributes, that provide drag-and-drop capability. These attributes can be divided into two groups: those ones which provide drag and those which provide drop operations (see the tables below).



Consider drag-and-drop inside a tree. All zones, which are assumed to be dragged, must be marked. In terms of <rich:tree> these zones completely correspond to tree nodes. So, all dragging nodes should be marked with "dragType" attribute. Then, to mark zone(-s), where the dragging node could be dropped, pass the type of dragging node to the "acceptedTypes" attribute of the drop zone. It would be good to itemize, that each tree node in the <rich:tree> component’s structure has its own key. Depending on how the component is used, these keys can be generated by the component itself or can be taken from the component’s data model. Keys help to identify each node in a tree; key is what exactly being passing from one node to another in drag-and-drop operations. Finally, the method binding, that will process drag-and-drop operation, should be pointed via "dropListener" attribute of the <rich:tree> .

Chapters "6.40 <dragIndicator>" and "6.39 <dndParam>" describes how to apply visual element, that show some additional information (e.g. dragging item name) while operating with drag-and-drop.

Page code, that describes a tree with built in drag-and-drop in the way it is considered, is shown below.

Example:


...
<h:form>
     <rich:tree style="width:300px" value="#{libraryAjaxTree.data}" nodeFace="#{item.type}" var="item" dragIndicator=":treeDragIndicator" dropListener="#{libraryAjaxTree.processDrop}">
          <rich:treeNode type="artist" icon="/images/tree/group.png" iconLeaf="/images/tree/group.png" acceptedTypes="album">
               <h:outputText value="#{item.name}" />
          </rich:treeNode>
          <rich:treeNode type="album" icon="/images/tree/cd.png" iconLeaf="/images/tree/cd.png" dragType="album" acceptedTypes="song">
               <h:outputText value="#{item.title}" />
               <rich:dndParam name="label" type="drag" value="Album: #{item.title}" />
          </rich:treeNode>
          <rich:treeNode type="song" icon="/images/tree/music.png" iconLeaf="/images/tree/music.png" dragType="song">
               <h:outputText value="#{item.title}" />
               <rich:dndParam name="label" type="drag" value="Song: #{item.title}" />
          </rich:treeNode>
    </rich:tree>
</h:form>
...

This code renders following tree:


Listeners classes that process events on the server side are defined with the help of:

Listener methods can be defined using the following attributes or using nested tags.

Client event attributes are:

  • "onexpand" is a script expression to invoke when a node is expanded

  • "oncollapse" is a script expression to invoke when a node is collapsed

  • "ondragexit" is a script expression to invoke when an element passing out from a tree zone

  • "ondragstart" is a script expression to invoke when dragging starts

  • "ondragend" is a script expression to invoke when dragging ends (a drop event)

  • "ondragenter" is a script expression to invoke when a dragged element appears on a tree

They can be used to add some JavaScript effects.

Standart HTML event attributes like "onclick" , "onmousedown" , "onmouseover" etc. can be also used. Event handlers of a <rich:tree> component capture events occured on any tree part. But event handlers of treeNode capture events occured on treeNode only, except for children events.


For skinnability implementation, the components use a style class redefinition method. Default style classes are mapped on skin parameters.

There are two ways to redefine the appearance of all <rich:tree> components at once:

There is only one skin parameter for <rich:tree> . As it's a wrapper component for <rich:treeNode> components, look and feel customization is described in the corresponding section.



In order to redefine styles for all <rich:tree> components on a page using CSS, it's enough to create classes with the same names (possible classes could be found in the table above) and define necessary properties in them. An example is placed below:

Example:


...
 
.rich-tree{
    
font-weight:bold;
}
...

This is a result:


In the example a tree font weight was changed to bold.

Also it's possible to change styles of a particular <rich:tree> component. In this case you should create own style classes and use them in corresponding <rich:tree> styleClass attributes. An example is placed below:

Example:


...
.myClass{
    
font-weight:bold;
}
...

The "highlightedClass" attribute for <rich:tree> is defined as it's shown in the example below:

Example:


<rich:tree ... styleClass="myClass"/>

This is a result:


As it's shown on the picture above, font weight of highlighted text node of a tree was changed to bold.

On the component LiveDemo page you can see the example of <rich:tree> usage and sources for the given example.

How to Expand/Collapse Tree Nodes from code, see in thiswiki article.