2
votes

I took this example from Primefaces Showcase Tree Checkbox Selection:

public TreeCheckboxBean() {  
    root2 = new CheckboxTreeNode("Root", null);  
    TreeNode node0 = new CheckboxTreeNode("Node 0", root2);  
    TreeNode node1 = new CheckboxTreeNode("Node 1", root2);  
    TreeNode node2 = new CheckboxTreeNode("Node 2", root2);  

    TreeNode node00 = new CheckboxTreeNode("Node 0.0", node0);  
    TreeNode node01 = new CheckboxTreeNode("Node 0.1", node0);  

    TreeNode node10 = new CheckboxTreeNode("Node 1.0", node1);  
    TreeNode node11 = new CheckboxTreeNode("Node 1.1", node1);  

    TreeNode node000 = new CheckboxTreeNode("Node 0.0.0", node00);  
    TreeNode node001 = new CheckboxTreeNode("Node 0.0.1", node00);  
    TreeNode node010 = new CheckboxTreeNode("Node 0.1.0", node01);  

    TreeNode node100 = new CheckboxTreeNode("Node 1.0.0", node10);  
}

public TreeNode[] getSelectedNodes() {  
    return selectedNodes;  
}  

public void setSelectedNodes(TreeNode[] selectedNodes) {  
    this.selectedNodes = selectedNodes;  
}  

public void displaySelectedMultiple() {  
    if(selectedNodes != null && selectedNodes.length > 0) {  
        StringBuilder builder = new StringBuilder();  

        for(TreeNode node : selectedNodes) {  
            builder.append(node.getData().toString());  
            builder.append("<br />");  
        }  

        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Selected", builder.toString());  

        FacesContext.getCurrentInstance().addMessage(null, message);  
    }  
}  

From there I check child Node 0.1, Node 0.1.0, Node 1.1. And when I click display selected button, the notification only shows the above node as selected.

Is there any way that I can include Node 0 and Node 1 as selected also?

So it will become Node 0, Node 0.1, Node 0.1.0, Node 1, Node 1.1

FYI: I'm using Primefaces 4, JSF 2.1.26.

3

3 Answers

4
votes

I think you have to do it yourself in the backing bean.

Collection<TreeNode> selectedNodes2 = new ArrayList<>();
for(TreeNode node : selectedNodes) {
    selectedNodes2.add(node);
    while (node.getParent()!=null){
        selectedNodes2.add(node.getParent());
        node = node.getParent();
    }
}

You can use node.setSelected(true) to actually select the nodes if you want.

2
votes
public void setSelectedTreeNode(String name) {
    List<TreeNode> tree = root.getChildren();
    findNode(name, tree);
}

private void findNode(String name, List<TreeNode> tree) {
    for (TreeNode node : tree) {
        if (node.getData().toString().contains(name)) {
            setSelectedNode(node);
            break;
        }
        findNode(name, node.getChildren());
    }
}

You must use a recursive method, above example will help you.

0
votes

if you want to propagate selection to parents using ANY strategy (instead of ALL) for children selection you have to implement event listeners.

<p:tree value="#{treeCheckboxBean.root2}" var="node"  
        selectionMode="checkbox"  
        selection="#{treeCheckboxBean.selectedNodes}">   

    <p:ajax event="select" listener="#{treeBean.onNodeSelect}" />  

    <p:treeNode>  
        <h:outputText value="#{node}" />  
    </p:treeNode>  
</p:tree>  

and

public class TreeBean implements Serializable 
{  
            private TreeNode[] selectedNodes; 

    ...

    public void onNodeSelect(NodeSelectEvent event) 
    {  
        for(TreeNode node = event.getTreeNode(); node != null; node = node.getParent())
        {
            node.setSelected(true);
            ArrayUtils.add(selectedNodes, node);
        }
    }  
}

not tested, but you got the idea :)