Select one child in Angular TreeView component

27 Aug 20256 minutes to read

The TreeView component supports both single and multiple node selections through the allowMultiSelection property. In scenarios where the application requires selecting only one child node at a time under a specific parent node while maintaining multi-selection capability across different parent branches, this can be implemented using the nodeSelecting event. This event provides control over the selection process by allowing custom logic to prevent or modify selection behavior based on the current selection state and parent-child relationships.

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { FormsModule } from '@angular/forms'
import { TreeViewModule } from '@syncfusion/ej2-angular-navigations'
import { Component, Inject, ViewChild } from '@angular/core';
import { TreeViewComponent } from '@syncfusion/ej2-angular-navigations';
import { NodeSelectEventArgs } from '@syncfusion/ej2-navigations';
/**
 * Single child selection at a time
 */
@Component({
  imports: [
    FormsModule, TreeViewModule
  ],
  standalone: true,
  selector: 'app-container',
  template: `<div id='treeparent'><ejs-treeview #tree id="listtree" allowMultiSelection='allowMultiSelection' [fields]='listfields' (nodeSelecting)="onNodeSelecting($event)"></ejs-treeview></div>`
})
export class AppComponent {

  @ViewChild('tree')
  public tree?: TreeViewComponent;
  // Self-referential list data source for TreeView component
  public localData: Object[] = [
    { id: 1, name: 'Parent 1', hasChild: true, expanded: true },
    { id: 2, pid: 1, name: 'Child 1' },
    { id: 3, pid: 1, name: 'Child 2' },
    { id: 4, pid: 1, name: 'Child 3' },
    { id: 7, name: 'Parent 2', hasChild: true, expanded: true },
    { id: 8, pid: 7, name: 'Child 1' },
    { id: 9, pid: 7, name: 'Child 2' },
    { id: 10, pid: 7, name: 'Child 3' },
  ];
  public listfields: Object = { dataSource: this.localData, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild' };
  public allowMultiSelection: boolean = true;
  public parent?: any; public child?: any;
  public count: boolean = false;
  public childCount: boolean = false;
  // Triggers when you select any node
  public onNodeSelecting(args: NodeSelectEventArgs): void {
    console.log(args.nodeData);
    let id: any = args.nodeData['parentID'];
    if (!this.count) {
      this.parent = id;
      this.count = true;
    }
    if (!this.childCount) {
      this.child = args.nodeData['id'];
      this.childCount = true
    }
    if (id != null && id === this.parent) {
      let element: HTMLElement = (this.tree as any).element.querySelector('[data-uid="' + id + '"]') as HTMLElement;
      let liElements: any = element.querySelectorAll('ul li');
      for (let i: number = 0; i < liElements.length; i++) {
        let nodeData: any = (this.tree as any).getNode(liElements[i]);
        if (nodeData.selected && args.action === "select" && this.child !== args.nodeData['id']) {
          args.cancel = true;
        }
        // For unselect the selectedNodes
        else if (args.action === "un-select" && this.child === args.nodeData['id']) {
          this.childCount = false;
          this.child = null;
          this.parent = null;
          this.count = false;
        }
      }
    } else if (id !== this.parent && id !== null) {
      if (args.action == "select") {
        args.cancel = true
      }
    } else if (id === null) {
      this.childCount = false;
      this.child = null;
      this.parent = null;
      this.count = false
    }
  }
}
@import 'node_modules/@syncfusion/ej2-base/styles/material.css';
@import 'node_modules/@syncfusion/ej2-inputs/styles/material.css';
@import 'node_modules/@syncfusion/ej2-buttons/styles/material.css';
@import 'node_modules/@syncfusion/ej2-angular-base/styles/material.css';
@import 'node_modules/@syncfusion/ej2-angular-navigations/styles/material.css';
@import 'node_modules/@syncfusion/ej2-angular-inputs/styles/material.css';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));