Chris S.
Chris S.

Reputation: 333

PrimeNG Tree - select TreeNode programmatically

I am using the PrimeNG Tree component to enable the users to select some values based on a tree structure. The selected nodes will be later stored in a database and when the user visits the edit dialog again these nodes should be pre selected.

Is there any way to achieve this with the current PrimeNG version? Alternatively it would be nice if you can tell me another angular2 tree component which supports checkbox selection and pre-selection of nodes as well.

Upvotes: 11

Views: 29869

Answers (6)

Mike
Mike

Reputation: 920

This is something in between of @Nishant and @Jignesh M. Khatri answer. Node selection works and parent.partialSelected works.

selectNodes(tree: TreeNode[], checkedNodes: TreeNode[], keys: string[]) {
    for (const node of tree) {
        if (keys.includes(node.key) || checkedNodes.includes(node.parent)) {
            checkedNodes.push(node)
        }
        if (node.children)
            this.selectNodes(node.children, checkedNodes, keys)
        this.partialCheckNodes(checkedNodes, node)
    }
}

private partialCheckNodes(checkedNodes: TreeNode[], node: TreeNode) {
    let count = node.children.length
    let c = 0
    for (const childNode of node.children) {
        if (checkedNodes.includes(childNode)) {
            c++
        }
        if (childNode.partialSelected) node.partialSelected = true
    }
    if (c != 0) {
        if (c == count) {
            node.partialSelected = false
            if (!checkedNodes.includes(node)) {
                checkedNodes.push(node)
            }
        } else {
            node.partialSelected = true
        }
    }
}

Upvotes: 3

Džan Operta
Džan Operta

Reputation: 493

Implement function to find a Node by key

getNodeWithKey(key: string, nodes: TreeNode[]): TreeNode | undefined {
   for (let node of nodes) {
     if (node.key === key) {
        return node;
     }

     if (node.children) {
       let matchedNode = this.getNodeWithKey(key, node.children);
       if (matchedNode) {
         return matchedNode;
       }
     }
   }
   return undefined;
}

Now we are able to easily find the selected nodes based on selected keys, and update the selectedNodes property.

preselectNodes(keys: string[], allNodes: TreeNode[]): void {
    this.selectedNodes = keys.map(key => this.getNodeWithKey(key, allNodes)).filter(this.isTreeNode);
}

The selectedNodes property needs to be assigned in p-tree

<p-tree
  [value]="data"
  selectionMode="multiple"
  [(selection)]="selectedNodes"
  [metaKeySelection]="true"
></p-tree>

isTreeNode is a filter isTreeNode = (item: TreeNode | undefined): item is TreeNode => { return !!item }

Upvotes: 1

Nishant
Nishant

Reputation: 305

Here is method to select nodes programmatically:

HTML

<p-tree 
  [value]="list['Entities']" 
  [(selection)]="data['Entities']" 
  selectionMode="checkbox">  
</p-tree>

Method

const selectNodes = (tree: TreeNode[], checkedNodes: TreeNode[], keys: string[]) => {
  // Iterate through each node of the tree and select nodes
  let count = tree.length;
  for (const node of tree) {
    // If the current nodes key is in the list of keys to select, or it's parent is selected then select this node as well
    if (keys.includes(node.key) || checkedNodes.includes(node.parent)) {
      checkedNodes.push(node);
      count--;
    }

    // Look at the current node's children as well
    if (node.children)
      selectNodes(node.children, checkedNodes, keys);
  }

  // Once all nodes of a tree are looked at for selection, see if only some nodes are selected and make this node partially selected
  if (tree.length > 0 && tree[0].parent) tree[0].parent.partialSelected = (count > 0 && count != tree.length);
}

Call to the Method

const keysToBeSelected = [2,3,4]
selectNodes(this.list.Entities, this.filterData.Entities, keysToBeSelected);

Upvotes: 3

Mohammad Niazmand
Mohammad Niazmand

Reputation: 1547

Set the selectionMode attribute of with 'checkbox' like below:

<p-tree
 selectionMode="checkbox"
 [(selection)]="selectedNodes"
  ></p-tree>

The selectedNodes variable contains selected nodes.Add all nodes that you want to be selected in this variable.

Upvotes: -1

Jignesh M. Khatri
Jignesh M. Khatri

Reputation: 1596

Found a workaround for pre-selection of multiple check-boxes (programmatically) in PrimeNG Tree. You can find working example here: https://github.com/jigneshkhatri/primeng-treenode-preselect

Upvotes: 0

Aleksandr Petrovskij
Aleksandr Petrovskij

Reputation: 1243

In selectionMode="checkbox" selected nodes stored in [(selection)]="selectedNodesArray" property.

You can put values from database into selectedNodesArray and this nodes will be selected.

Upvotes: 11

Related Questions