-
1. Re: rich:tree - programatically set the selected node and ex
kingcu Jul 9, 2007 10:29 AM (in response to kingcu)Can someone please let me know if this is possible? Thanks.
-
2. Re: rich:tree - programatically set the selected node and ex
max76 Jul 9, 2007 11:47 AM (in response to kingcu)Hi,
just have a look at the HtmlTree (and also the UITree) API. There are methods for controlling the expansion state of the tree: look at queueXXX() methods.
i successfully testet collapseAll and expandAll. collapsing and expansion if single nodes should also work somehow.
hope that helps...
---
max -
3. Re: rich:tree - programatically set the selected node and ex
kingcu Jul 9, 2007 12:57 PM (in response to kingcu)Thanks Max for your reply.
The question I have now is that how I can get to UITree: I know that if I attach an event listener to the tree, I can get to UITree through the event source; but, in my case, I need to set the expansion point when I build the tree data model and before the tree starts to render. In other words, I want the tree to be displayed with the specific node expanded at the very beginning instead of later when some user action triggers. -
4. Re: rich:tree - programatically set the selected node and ex
max76 Jul 9, 2007 2:02 PM (in response to kingcu)Hello,
hmmm, good question, i dont know how that is possible (if it is possible), but i think there may be something like interceptors that may be called before a page is rendered...
One possible solution that should work would be an UIComponent property in your bean that is bound to the tree (so you have an instance to the HtmlTree when a plain action is called) and some client script that calls an action of your bean when the view is loaded; this action expands the nodes and then the tree is reloaded...
i think on registering java-script code at body.onload, call an action with a4j:jsfunction (ajax4jsf) and rerender just your tree (ajaxstyle)...
sure, thats a workaround, no solution to your problem.
--
max -
5. Re: rich:tree - programatically set the selected node and ex
kingcu Jul 9, 2007 6:14 PM (in response to kingcu)Thanks. Sounds like a plan. One more question: in the onload actionListener, I can get the UIComponent and then cast it to a HtmlTree, but is there any API that allows me to traverse it? Because I need to compare each tree node with the previously selected business id to determine if this is the node to expand to.
-
6. Re: rich:tree - programatically set the selected node and ex
max76 Jul 10, 2007 6:44 AM (in response to kingcu)i dont think there is an easy and intuitive way to do so...
you can try to struggle with getTreeNode() and getTreeNode(java.lang.Object rowKey) methods.
For me i am still unable to expand a given node, i dont know by now how exactly node expansion works... it looks like you must provide some sort of path (with node ids) to the node you wish to expand... but for now i can only exand one level after another :-(
maybe a short hint from someone would help!
thanks,
max -
7. Re: rich:tree - programatically set the selected node and ex
max76 Jul 10, 2007 7:24 AM (in response to kingcu)just solved node-expansion to a given node...
i had to expand all container_nodes on the way to a given node manually, that means you must queue a nodeExpansion for every parentnode.
hope that helps... -
8. Re: rich:tree - programatically set the selected node and ex
mugwump Jul 12, 2007 5:44 AM (in response to kingcu)Hi max,
I got the same problem and try to make sense of your last post: The API-Documentation for the tree is awful, so could you please elaborate a little more on your solution?!
"queue a nodeExpansion": Meaning exactly what?! In javascript in the client? On the server on the UITree before the page gets rendered (still trying to figure out how to do this: Maybe build the UITree and then bind it?!)
thx for any help!
stf -
9. Re: rich:tree - programatically set the selected node and ex
kingcu Jul 12, 2007 12:49 PM (in response to kingcu)I got my tree working to a point where I could programmatically do a expandAll. Let me post my code here so that we have a base for further discussion.
My JSF page looks like this:<ui:define name="body"> <h:form> <a:jsFunction name="bodyOnload" actionListener="#{treeController.expandTree}" reRender="businessTree" /> </h:form> <h:messages globalOnly="true" styleClass="message" id="globalMessages"/> <h:form> <rich:tree id="businessTree" binding="#{treeController.tree}" switchType="ajax" value="#{businessTree}" var="business" style="margin: 10px; width: 300px;" nodeFace="simpleNode"> <rich:treeNode type="simpleNode"> <h:outputText value="#{business.name}"/> </rich:treeNode> </rich:tree> </h:form> </ui:define>
The JavaScript function bodyOnload() is called from the facelet template where the HTML body tag is declared:<body onload="bodyOnload()">
The server side code is a Seam component:@Name("treeController") public class TreeController { private HtmlTree tree; public HtmlTree getTree() { return tree; } public void setTree(HtmlTree tree) { this.tree = tree; } // Called on JSF on body onload to expand the business tree to the selected business public void expandTree() { try { tree.queueExpandAll(); } catch (IOException e1) { e1.printStackTrace(); } } }
-
10. Re: rich:tree - programatically set the selected node and ex
kingcu Jul 12, 2007 12:55 PM (in response to kingcu)However, now I got stuck with two things:
1. Programmatically traverse the tree starting from the root, because I need to compare each node with the previously user selected business to determine the exact expansion point; it seems getTreeNode() only returns the selected node, to me there should be another API getTreeRoot() that returns the root node of the tree.
2. Programmatically select a given tree node, because I want the expanded tree node to be automatically selected after expansion. I don't see any API existing that allows me to accomplish this. There is a isSelected() to determine if the node is selected, but no corresponding setSelected().
IMO, there should be an API corresponding to each user action that occurs on the tree, like: expand, collapse, select, etc.
Max: I would be interested to see how you determine the specific expansion point in the tree. -
11. Re: rich:tree - programatically set the selected node and ex
max76 Jul 13, 2007 9:22 AM (in response to kingcu)Hi!
1st: every treenode has an unique id -- this id is later used to identify the node which gets expanded... see TreeNode.addChild(java.lang.Object identifier, TreeNode child); in my case the id is simply an Integer which gets incremented when i add a node.
2nd: my treemodel class has a reference to the rootnode; and with this rootnode i can reach every node in my tree via treenode.getChildren()
3rd: my treemodel has a reference to the HtmlTree
So the expand all action looks like (as mentioned by kingcu):public String expandAll() { System.out.println("expandAll"); HtmlTree hTree = (HtmlTree) tree; try { hTree.queueExpandAll(); } catch (IOException e1) { e1.printStackTrace(); } return null; }
If i want to expand to a given node i must expand every parentcontainer on the way to the node...
If my tree looks like A-B-C-D where D is a leave an i want to expand the node D one must expand node A, node B, and node C ... thats what i mean with queue expansion of parents... and this is done via ((HtmlTree) tree).queueNodeExpand(RowKey);
The RowKey describes the Path to the node...
this is done via following action:
nodeId is a property of my treemodel with the ID of the node that should be expanded...
getNode(nodeID) is an utility method that traverses the tree and returns the node object with the given id.
path is an list of IDs of the parents (in my example A, A-B, A-B-C)public String expandNode() { Node node = getNode(nodeId); ArrayList<Integer> path = new ArrayList<Integer>(); while (node != null) { path.add(node.getId()); node = (Node) node.getParent(); } Collections.reverse(path); path.remove(0); // dont expand rootnode, it is not displayed for (int i = 0; i < path.size(); i++) { ArrayList<Integer> list = new ArrayList<Integer>(); for (int n = 0; n <= i; n++) { list.add(path.get(n)); } ListRowKey key = new ListRowKey(list); try { ((HtmlTree) tree).queueNodeExpand(key); } catch (IOException e) { e.printStackTrace(); } } return null; }
hope that helps... -
12. Re: rich:tree - programatically set the selected node and ex
vh Jul 18, 2007 8:46 PM (in response to kingcu)This is great. But I didn't see it mention how to select a node.
Can you help? -
13. Re: rich:tree - programatically set the selected node and ex
mheidt Aug 6, 2007 3:42 PM (in response to kingcu)vh,
I enhanced the code by the following:TreeState ts = (TreeState)tree.getComponentState();
and at the endif (key!=null){ ts.setSelected(key); this.setSelectedNode((ComponentSetNode)tree.getRowData(key)); //optional }
-
14. Re: rich:tree - programatically set the selected node and ex
blabno May 24, 2008 10:14 AM (in response to kingcu)Actually your code does not work for me.
I use following instead :List<Object> path = new ArrayList<Object>(); while (node != null) { path.add(((MyTreeNodeImpl) node).getId()); node = node.getParent(); } Collections.reverse(path); path.remove(0); // dont expand rootnode, it is not displayed TreeState state = (TreeState) tree.getComponentState(); for (int i = 0; i < path.size(); i++) { List<Object> list = new ArrayList<Object>(); for (int n = 0; n <= i; n++) { list.add(path.get(n)); } ListRowKey key = new ListRowKey(list); try { state.expandNode(tree, key); } catch (IOException e) { log.error(e); } } ListRowKey key = new ListRowKey(path); state.setSelected(key);
Note that I do not use((HtmlTree) tree).queueNodeExpand(key);
but instead i usestate.expandNode(tree, key);