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

jsf, jsf-2, primefaces

Solution

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().

Problem

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.

Original source