7
votes

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.

2
with out selecting a node, How do you get the current tree node? I didn't understand your question.neni
have you tried using #{component} in your markup? that is supposed to resolve to the current component, should be treeNode in your caserootkit

2 Answers

6
votes

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

0
votes

Well, there is an attribute called "selection" in the tree component. You just need to provide a reference to the managed bean method.

For e.g., in your xhtml define the attribute the following way:

selection="#{myManagedBean.selectedNode}"

And with the definition of the above attribute, you will have to provide the usual setter and getter methods in the managed bean that references to org.primefaces.model.TreeNode instance.