0

Assue I have a class DataObj

public class DataObj implements Serializable {
  private Set<String> values;
  private String name;

  // default constructor, constructor to pass properties

  // getter and setter
}

and set an instance as data property of a TreeNode:

@ManagedBean
public ACtrl extends Serializable {
  private TreeNode root = new DefaultTreeNode(new DataObj(new HashSet<>(Arrays.asList("a","b")), "some name"));

  // default constructor

  // getter for root
}

How can I create dynamic p:treeNodes which contain components based on the data property (and it's content), e.g. a checkbox for each string in DataObj.values?

The following example shows how to change content based on the type or value of TreeNode.data, but c:if and c:forEach don't work (I'm very sure they aren't supposed to because node should be null when they're evaluated):

<ui:composition 
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets" 
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:p="http://primefaces.org/ui"  >
  <h:form id="form">
    <p:tree id="tree" value="#{aCtrl.root}" var="node" >
      <p:treeNode id="treeNode">
        <h:outputText value="#{node.name}"/>
        <p:spinner value="#{node}" rendered="#{node.getClass().getName() eq 'java.lang.Integer'}"/>
        <c:if test="#{node.getClass().getName() eq 'DataObj'}">
          <c:forEach items="#{node.values}" var="value">
            <h:selectBooleanCheckbox value="#{value}"/>
            <h:outputText value="#{value.name}"/>
          </c:forEach>
        </c:if>
      </p:treeNode>
    </p:tree>  
  </h:form>  
</ui:composition>

Please consider this pseudo code... I'm aware that it doesn't run or compile, but it eases the explanation of my problem and possibly the answers :)

Do alternative JSF component libraries or extensions exist to solve this?

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177

1 Answers1

0

Usage of ui:repeat is necessary (tried this before but didn't pay attention to the fact that value has to be "a List, array, java.sql.ResultSet, or an individual java Object", but not a key set of map keys :) - need to add .toArray() in this case ).

...
<p:treeNode id="treeNode" >
  <ui:repeat var="key" value="#{node.type.aValue.keySet().toArray()}">  
    <h:selectBooleanCheckbox id="checkbox" value="#{node.type.aValue.get(key)}"/>
    <h:outputLabel for="checkbox" value="#{key}"/>
  </ui:repeat>  
</p:treeNode>
...

where node.type.aValue is a Map<String,Boolean>.

Useful:

Community
  • 1
  • 1
Kalle Richter
  • 8,008
  • 26
  • 77
  • 177