3

I'm need primefaces tree in "checkbox" selection mode, but only one and only one node can be selected at a time. By default, primefaces tree selects all descendants when a node is selected and that is actually what I want to change.

Can anybody help me figure it out, please?

user3348246
  • 101
  • 1
  • 1
  • 4

1 Answers1

2

I finally found a way to realize this by looking at the Javascript source code of the tree. You can e.g. create a singleton that caches the previously selected node. By using the "onNodeClick" attribute of the tree you can call a Javascript function that unselects the previous node before the widget internally sets the new selected node (and potentially posts the new selection when using ajax events).


Update:

I modified the Facelet and the Javascript to search the tree for a preselected node on initialization. Be aware that the preselected node has to be visible to make it work correctly. See this answer for details about expanding the parent nodes.


Bean:

@Named
@ViewScoped
public class BackingBean implements Serializable {

    private TreeNode rootTreeNode;

    // IMPORTANT: Use array!
    private TreeNode[] selected;

    public TreeNode getRootTreeNode() {
        if (rootTreeNode == null) {
            rootTreeNode = new DefaultTreeNode("Root", null);

            // init child tree nodes
        }
        return rootTreeNode;
    }

    public TreeNode[] getSelected() {
        return selected;
    }

    public void setSelected(TreeNode[] selected) {
        this.selected = selected;
    }

}

Facelet:

<p:tree id="tree"
        onNodeClick="TREE_SELECTION.updateSelection(node, event)"
        propagateSelectionDown="false" propagateSelectionUp="false"
        selection="#{backingBean.selected}" selectionMode="checkbox"
        value="#{backingBean.rootTreeNode}"
        var="data"
        widgetVar="treeWidget">

    <p:treeNode>
        <h:outputText value="#{dataWrapper.label}" />
    </p:treeNode>

</p:tree>

Javascript:

<script type="text/javascript">
    // singleton for tree selection
    var TREE_SELECTION = {
        init: function (treeWidgetVar) {
            this.treeWidget = PF(treeWidgetVar);
            this.selectedNode = this.treeWidget.jq.find('.ui-treenode-selected');
        },
        treeWidget: null,
        selectedNode: null,
        updateSelection: function (node, event) {
            // get the checkbox state of the clicked node
            var checkbox = node.find('> .ui-treenode-content > .ui-chkbox'),
                    checked = checkbox.find('> .ui-chkbox-box > .ui-chkbox-icon').hasClass('ui-icon-check');
            if (checked) {
                // checkbox is going to be unchecked
                this.selectedNode = null;
                return;
            }

            // check for previously selected node
            if (this.selectedNode !== null) {
                // get the checkbox of the previously selected node
                checkbox = this.selectedNode.find('> .ui-treenode-content > .ui-chkbox');

                // update tree
                this.treeWidget.uncheck(checkbox);
                this.treeWidget.removeFromSelection(this.treeWidget.getRowKey(this.selectedNode));
            }

            // cache selected node
            this.selectedNode = node;
        }
    };

    // initialize singleton when document is loaded
    $(function () {
        TREE_SELECTION.init('treeWidget');
    });
</script>
Community
  • 1
  • 1
ltlBeBoy
  • 1,242
  • 16
  • 23