Oracle ADF Code Corner: ADF Faces RC - Expanding an af:tree node by clicking onto its label
ADF Faces RC: Expanding an af:tree node by clicking
onto its label
Tree nodes in ADF Faces RC are expanded at runtime
by clicking onto the plus icon next to the folder name. For improved
usability you may want to allow users to click onto the folder name
as well to expand the a node; same for closing a folder node. This
functionality, which is not provided by default, can be added using
the ADF Faces RC client framework using a little bit of JavaScript.
Written by Frank Nimphius, Oracle
Corporation
24-April-2008
Introduction
ADF Faces RC components have a client and server side component set. Usually
the client side is referred to as the client framework because it not only contains
the component object but also a set of APIs to work with the ADF Faces RC framework.
This how-to explains how to use the client side framework to expand a tree node
in ADF Faces RC by the application user clicking onto the tree label.
Note: This sample is developed with ADF Faces RC TP4 and has never been tested
with an earlier version.
Code Sample
Starting from an ADF Tree that you built with Oracle ADF Faces, the following
changes are needed on the page to get this example to work
1. The af:tree component needs to have a child component af:clientListener
to respond to moue clicks
The clientListener configures the tree so it calls a local javaScript function
"expandNode" when a node in the tree gets selected
2. The JavaScript code that gets added to the page uses the Adf event to determine
the event source, which is the handle to the tree
</af:document> <f:facet name="metaContainer"> <af:group> <![CDATA[ <script> function expandNode(event){ var _tree = event.getSource(); rwKeySet = event.getAddedSet(); var firstRowKey; for(rowKey in rwKeySet){ firstRowKey = rowKey; // we are interested in the first hit, so break out here break; } if (_tree.isPathExpanded(firstRowKey)){ _tree.setDisclosedRowKey(firstRowKey,false); } else{ _tree.setDisclosedRowKey(firstRowKey,true); } } </script> ]]> </af:group> </f:facet> </af:document>
The three elements highlighted in bold are important to mention: First of all,
for better performance, all JavaScript code added to a page should be in the
metaContainer of the af:document element. Second, because the metaContainer
cannot have JavaScript directly added, you must have a af:group element as the
child of the metaContainer facet.
The expandNode() method has a single input argument, which is the event that
is passed into it by the framework. the event source, as mentioned earlier,
is the tree, of type AdfRichTree. The event also contains a set of added row
keys, which in the case of the tree are the index of the three node.
To determine whether to expand or close the selected node, the isPathExpanded
method is called. The isPathExpanded() method is inherited by the AdfRichTree
component and comes from its AdfUITree parent class. Not that this information
is important, but it gives you an idea of how the ADF Faces client framework
is organized in objects and subclasses.
Known Issues
There is one issues with this sample that I am aware of and that I will follow
up with. To close a previously expanded node by clicking on the same node label,
users first have to click on another node. My assumption is that the node selection
is blocking the event, but this is only a guess. I'll update the document as
soon as there is a solution for this.
What you should be aware of !
Make sure that all JavaScript you add to a page is properly formatted. If you
add invalid code, e.g. trying to guess API names or not closing a function properly,
then this shows at runtime, not at compile and not at design time. The way it
shows is that you see the famous splash screen of death, which is the rotating
image you see when starting your web application. Except for that this time
the splash doesn't stop spinning. If you see this, go back and check your JavaScript.
There exist plans in a next version of JDeveloper 11 to handle this issue more
gracefully.