Guides
Guides

Tri-State Checkboxes

Tri-State checkboxes are not supported as a built-in feature - they can be implemented using custom templates.

Credit to Debajyoti Maity for building this and sharing with the community

Here is sample code that introduces Tri-State Checkboxes:

<tree-root
  #tree
  [nodes]="nodes"
  [options]="treeOptions"
  (onActivate)="selectNode($event)">

  <template #treeNodeTemplate let-node="node" let-index="index" >
    <input
      (change)="check( node, $event)"
      type="checkbox"
      [indeterminate]="node.data.indeterminate"
      [checked]="node.data.checked">

      {{ node.data.name }}
  </template>
</tree-root>

Component:

public check(node, $event) {
  this.updateChildNodesCheckBox(node, $event.target.checked);
  this.updateParentNodesCheckBox(node.parent);
}
public updateChildNodesCheckBox(node, checked) {
  node.data.checked = checked;
  if (node.children) {
    node.children.forEach((child) => this.updateChildNodesCheckBox(child, checked));
  }
}
public updateParentNodesCheckBox(node) {
  if (node && node.level > 0 && node.children) {
    let allChildChecked = true;
    let noChildChecked = true;

    for (let child of node.children) {
      if (!child.data.checked) {
        allChildChecked = false;
      } else if (child.data.checked) {
        noChildChecked = false;
      }
    }

    if (allChildChecked) {
      node.data.checked = true;
      node.data.indeterminate = false;
    } else if (noChildChecked) {
      node.data.checked = false;
      node.data.indeterminate = false;
    } else {
      node.data.checked = true;
      node.data.indeterminate = true;
    }
    this.updateParentNodesCheckBox(node.parent);
  }
}