Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access the current TreeNode in primefaces tree (in mark-up or programmatically) without binding to UI component in managed bean?

I am using Primefaces 3.4.1 with the 2.2.0-m05 milestone build of Oracle's JSF 2.2 implementation. I am also using Spring 3.1 for dependency injection and some AOP.

I am trying to use the Primefaces tree component to display a composite of logical filter rules (and allow the user to create composite/leaf nodes at any depth within the composite structure).

Example composite filter:

((location = 'cal') AND (description contains 'test')) OR (project = 'someProject')

Example tree markup:

<p:tree value="#{form.rootComponent}" var="filterComponent" animate="true">

    <p:treeNode type="composite">
       <!-- some composite specific components -->
    </p:treeNode>

    <p:treeNode type="leaf">
       <!-- some leaf specific components -->
    </p:treeNode>

</p:tree>

Although the "value" attribute on the element accepts the root TreeNode (retrieved from a managed bean), the "var" attribute points to the actual data present in the current tree node, rather than the node itself. I would like a way to access the current tree node, not its wrapped data, either in mark-up or programmatically.

If I can access it in mark-up, I can pass it as a method argument to a managed bean. If there's no way of accessing it in the mark-up, can I gain direct programmatic access through a model object? (presumably by gaining access to the underlying tree model?).

I know you can use an expression which resolves to an underlying DataModel instead of the data collection directly as the "value" of h:dataTable, but I believe you can only use the root node itself with p:tree.

I could include a reference to the tree node in the wrapped data object, but I'd really rather avoid nasty circular references if at all possible.

In the absence of a better alternative, I tried using the "binding" attribute to bind the p:tree element directly to a Tree instance in the managed bean (Tree being the UIComponent class for p:tree), which allows me to access the current node via the getTreeNode() method, but I would prefer to avoid this given the lifecycle mismatch between managed beans and view components. It is not working perfectly as is, and I assume there must be a much better, simpler solution.

I also tried using a jsf data table - with nested data tables to handle the composite part - but decided against it given the difficulty in creating a conditionally recursive structure within jsf markup (I believe the "rendered" attribute is not evaluated at view build time so it's difficult to avoid infinite recursion).

Just to clarify, I am only interested in the current tree node containing the data referred to by "var", not the node currently selected by the user.

like image 360
user1838501 Avatar asked Nov 20 '12 15:11

user1838501


1 Answers

PF Lead just added a new attribute called "nodeVar" for the p:treeTable (dunno if p:tree is included) as in PF 5.1.10 / 5.2. This feature will allow to get a hold of the actual TreeNode instead of it's data. Hence, one can now perform extra method calls on the node itself, such as TreeNode.isLeaf().

like image 135
Cerbenus Avatar answered Sep 22 '22 05:09

Cerbenus