presentation of data rich:tree HtmlTree

Component identification parameters

Name | Value
--- | ---
component-type | org.richfaces.Tree
component-class | org.richfaces.component.html.HtmlTree
component-family | org.richfaces.Tree
renderer-type | org.richfaces.TreeRenderer
tag-class | org.richfaces.taglib.TreeTag

## Creating the Component with a Page Tag

There are two cases for a tree definition: together with <rich:recursiveTreeNodesAdaptor> or <rich:treeNodesAdaptor> and without them. In the first case, it's possible to define it without "value" and "var" attributes as follows:

Example:

    ...
        <rich:tree>
            <rich:recursiveTreeNodesAdaptor roots="#{fileSystemBean.sourceRoots}" var="item" nodes="#{item.nodes}" />
        </rich:tree>
    ...

In the second case, it's necessary to define it with these attributes as it's shown below:

Example:

    ...
        <rich:tree value="#{library.data}" var="item" >
               <rich:treeNode  icon="/images/tree/singer.png" >
                    <h:outputText value="#{item.name}" />
                </rich:treeNode>
                 ...
        </rich:tree>
    ...

## Creating the Component Dynamically Using Java

Example:

    import org.richfaces.component.html.HtmlTree;
    ...
    HtmlTree myTree = new HtmlTree();
    ...

## Details of Usage

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

A bean property is passed into a tree "value" attribute. The property keeps a structure of "TreeNode" type instances.

There is a default class "TreeNodeImpl", which is a default implementation for TreeNode interface. TreeNode has attribute "data" which value is available as a request scope variable with a name that is defined by "var" attribute of a tree component. "XmlTreeDataBuilder" class allows transforming XML into structures of objects containing "XmlNodeData" instances as data, which could be represented by the tree component.

For particular visual representation of data <rich:tree> selects one of the children <rich:treeNode> components by type. The type is defined with the "nodeFace" attribute that corresponds to a value of "type" attribute for treeNode. An example of definition is placed 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.gif" icon="/images/tree/singer.gif">
                    <h:outputText value="#{item.name}" />
                </rich:treeNode>
                <rich:treeNode type="album" iconLeaf="/images/tree/disc.gif" icon="/images/tree/disc.gif">
                    <h:outputText value="#{item.title}" />
                </rich:treeNode>
                <rich:treeNode type="song" iconLeaf="/images/tree/song.gif" icon="/images/tree/song.gif">
                    <h:outputText value="#{item.title}" />
                </rich:treeNode>
            </rich:tree>
    </h:form>
    ...

This is a result:

Expanded tree with child elements

In case when "nodeFace" attribute isn't defined or defined but its value isn't equal to any type of all children treeNode components or this value is equal to some type, but the value of "rendered" attribute for this treeNode is "false" then default treeNode is used.

Default treeNode is the first node (with not defined "type" attribute and defined "rendered" attribute) from all children nodes of the tree component. If such treeNode wasn't found, the following default interior presentation is used:

Example:

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

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

It's possible to define several <rich:treeNode> components with the equal values of "type" attribute and different values of "rendered" attribute. It provides the possibility to define different markup for the same <rich:treeNode> components type. An example is placed 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.gif" icon="/images/tree/singer.gif"
                          rendered="#{item.exist}">
                    <h:outputText value="#{item.name}" />
                </rich:treeNode>
              <rich:treeNode type="artist" iconLeaf="/images/tree/singer.gif" icon="/images/tree/singer_absent.gif"
                          rendered="#{not item.exist}">
                    <h:outputText value="#{item.name}" />
                </rich:treeNode>
    	...
            </rich:tree>
    </h:form>
    ...

The example represents definition of two different <rich:treeNode> components. The first specifies the album that's available for sale, the other specifies the album that is not available. The result is shown on the following screenshot:

Using the "type" and the "rendered" attributes

You can define an EL-expression for "nodeFace" attribute. See an example:

Example:

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

Switching on treeNode could be performed in three modes. Modes could be specified with "switchType" attribute.

- Ajax - Ajax submission is used for switching
- Server - regular form submission request is used
- Client - switching is done as a whole on a client, no interaction with the server presents

If "ajaxSubmitSelection" attribute value set to "true" than any change in selection initiates an Ajax request to the server.

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

Example:

    ...
        <rich:tree ....>
            ...
            <f:facet name="icon">
                <h:graphicImage value="/images/tree/singer.gif "/>
            </f:facet>
            <f:facet name="iconCollapsed">
                <h:graphicImage value="/images/tree/singer.gif " />
            </f:facet>
            <f:facet name="iconExpanded">
                <h:graphicImage value="/images/tree/singer.gif " />
            </f:facet>
            <f:facet name="iconLeaf">
                <h:graphicImage value="/images/tree/song.gif " />
            </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 tree tag is intended mainly for defining common attributes such as "ajaxSubmitSelection" , for instance.

## Built-In Drag and Drop

The <rich: tree> component functionality provides a built-in support for Drag and Drop operations. The main usage principles are the same as for RichFaces DnD wrapper components. Hence, to get additional information on the topic, read the corresponding chapters:"rich:dndParam", "rich:dragSupport", "rich:dragIndicator", "rich:dropSupport". As treeNodes could be Drag, Drop or DnD elements, a tree can include the following attributes groups.

Drag attributes group

dragValue | Element value drag passing into processing after a Drop event
--- | ---
dragListener | A listener that processes a Drag event
dragIndicator | Id of a component that is used as drag pointer during the drag operation
dragType | Defines a drag zone type that is used for definition of a dragged element, which can be accepted by a drop zone

Drop attributes group

dropValue | Element value drop passed into processing after Drop events .
--- | ---
dropListener | A listener that processes a Drop event.
acceptedTypes | Drag zone names are allowed to be processed with a Drop zone.
typeMapping | Drag zones names mapping on the corresponding drop zone parameters.

An example of usage is placed below.

Example:

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

In the example a song from one album can be dragged into other because for the second treeNode with "type" ="album" was defined attribute "acceptedTypes" ="song". Its value is equal to the value of the "type" attribute defined for the third treeNode (see picture below). Also an album can be dragged into treeNode with "type" ="artist".

DnD operations

## Events handling

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

- nodeSelectListener is called during request sending on a node selecting event (if request sending on this event is defined)
- dropListener processes a Drop event
- dragListener processes a Drug event
- changeExpandListener processes expand/collapse event of a treeNode

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

Client event attributes are:

- onexpand - expands a node event
- oncollapse - collapses a node event
- ondragexit - element passing out from a tree zone event
- ondragstart - drags a start event
- ondragend - drags an end event (a drop event)
- ondragenter - drags an element appearing on a tree event

They can be used to add some JavaScript effects.

Also standart HTML event attributes like "onclick" , "onmousedown" , "onmouseover" and etc. could be 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.

## Look-and-Feel Customization

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:

- Redefine the corresponding skin parameters

- Add to your style sheets style classes used by a <rich:tree> component

## Skin Parameters Redefinition:

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.

Skin parameters for a wrapper element

Skin parameters | CSS properties
--- | ---
overAllBackground | background-color

## Definition of Custom Style Classes

Classes names that define a component appearance

Class name | Description
--- | ---
rich-tree | Defines styles for a wrapper <div> element of a tree

In order to redefine styles for all <rich:tree> components on a page using CSS, it's enough to create a class with the same names and define necessary properties in them.

To change styles of particular <rich:tree> components define your own style class in the corresponding <rich:tree> attribute.

## Relevant Resources Links

Here you can see the example of <rich:tree> usage and sources for the given example.

How to Expand/Collapse Tree Nodes from code, see here.