Cell selection in Angular Gantt component

18 Oct 202524 minutes to read

Cell selection in the Gantt component enables interactive selection of specific cells or ranges of cells within the grid. You may select cells using mouse clicks or arrow keys (up, down, left, right). This is useful for highlighting, manipulating, or performing operations on particular gantt cells.

Single cell selection

Single cell selection in the Gantt chart is enabled by setting selectionSettings.mode to Cell and selectionSettings.type to Single. This allows selecting only one cell at a time.

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { GanttModule, SelectionService } from '@syncfusion/ej2-angular-gantt';
import { SelectionSettingsModel } from '@syncfusion/ej2-angular-grids';

@Component({
  standalone: true,
  selector: 'app-root',
  imports: [GanttModule],
  providers: [SelectionService],
  template: `
    <ejs-gantt height="370px" [dataSource]="data" [taskFields]="taskSettings" [selectionSettings]="selectionSettings">
    </ejs-gantt>`,
  encapsulation: ViewEncapsulation.None
})

export class AppComponent implements OnInit {
  public data: object[] = [];
  public taskSettings: object = {};
  public selectionSettings: SelectionSettingsModel = {};

  ngOnInit(): void {
    this.data = [
      {
        TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
      },
      { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      {
        TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
      },
      { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      endDate: 'EndDate',
      duration: 'Duration',
      progress: 'Progress',
      dependency: 'Predecessor',
      parentID: 'ParentID'
    };
    this.selectionSettings = {
      mode: 'Cell',
      type: 'Single'
    };
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Multiple cell selection

Multiple cell selection in the Gantt chart is enabled by setting selectionSettings.mode to Cell and selectionSettings.type to Multiple. This allows selecting multiple cells at a time by holding the Ctrl key while clicking on each desired cell.

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { GanttModule, SelectionService } from '@syncfusion/ej2-angular-gantt';
import { SelectionSettingsModel } from '@syncfusion/ej2-angular-grids';

@Component({
  standalone: true,
  selector: 'app-root',
  imports: [GanttModule],
  providers: [SelectionService],
  template: `
    <ejs-gantt height="370px" [dataSource]="data" [taskFields]="taskSettings" [selectionSettings]="selectionSettings">
    </ejs-gantt>`,
  encapsulation: ViewEncapsulation.None
})

export class AppComponent implements OnInit {
  public data: object[] = [];
  public taskSettings: object = {};
  public selectionSettings: SelectionSettingsModel = {};

  ngOnInit(): void {
    this.data = [
      {
        TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
      },
      { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      {
        TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
      },
      { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      endDate: 'EndDate',
      duration: 'Duration',
      progress: 'Progress',
      dependency: 'Predecessor',
      parentID: 'ParentID'
    };
    this.selectionSettings = {
      mode: 'Cell',
      type: 'Multiple'
    };
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Select cells externally

You may programmatically select a single row, multiple cells, or a range of cells in the Gantt chart using built-in methods.

Single cell selection

Select a specific cell in the Gantt chart by calling the selectCell method and providing the desired row and column indexes as arguments.

import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { GanttComponent, GanttModule, SelectionService } from '@syncfusion/ej2-angular-gantt';
import { SelectionSettingsModel } from '@syncfusion/ej2-angular-grids';
import { TextBoxComponent, TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';

@Component({
    standalone: true,
    selector: 'app-root',
    imports: [GanttModule, TextBoxModule, ButtonModule],
    providers: [SelectionService],
    template: `  
        <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
            <label style="font-weight: bold;">Enter the cell index:</label>
            <ejs-textbox #textbox width="100"></ejs-textbox>
            <button ejs-button (click)="click()">Select Cell</button>
        </div>
        <ejs-gantt #gantt height="370px" [dataSource]="data" [taskFields]="taskSettings" [selectionSettings]="selectionSettings">
        </ejs-gantt>`,
    encapsulation: ViewEncapsulation.None
})

export class AppComponent implements OnInit {
    @ViewChild('gantt', { static: true }) public ganttInstance!: GanttComponent;
    @ViewChild('textbox', { static: false }) public textbox?: TextBoxComponent;
    public data: object[] = [];
    public taskSettings: object = {};
    public selectionSettings: SelectionSettingsModel = {};

    ngOnInit(): void {
        this.data = [
            { TaskID: 1, TaskName: 'Initiation Phase', StartDate: new Date('2023-04-01'), Duration: 5, Progress: 40 },
            { TaskID: 2, TaskName: 'Site Survey', StartDate: new Date('2023-04-06'), Duration: 4, ParentID: 1, Progress: 60 },
            { TaskID: 3, TaskName: 'Soil Testing', StartDate: new Date('2023-04-10'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 4, TaskName: 'Approval Process', StartDate: new Date('2023-04-14'), Duration: 3, ParentID: 1, Progress: 30 },
            { TaskID: 5, TaskName: 'Estimation Phase', StartDate: new Date('2023-04-18'), Duration: 6, Progress: 20 },
            { TaskID: 6, TaskName: 'Floor Plan Design', StartDate: new Date('2023-04-24'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 7, TaskName: 'Material Listing', StartDate: new Date('2023-04-27'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 8, TaskName: 'Final Approval', StartDate: new Date('2023-04-30'), Duration: 2, ParentID: 5, Progress: 50 }
        ];
        this.taskSettings = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            parentID: 'ParentID'
        };
        this.selectionSettings = {
            mode: 'Row',
            type: 'Single'
        };
    }

    public click(): void {
        const value = (this.textbox as TextBoxComponent).element.value as string;
        const cellIndex = parseInt(value, 10);
        if (!isNaN(cellIndex)) {
            this.ganttInstance.selectCell(cellIndex);
        }
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Multiple cell selection

Select multiple cells in the Gantt chart by calling the selectCells method and providing an array of the row and column indexes for each target cell.

import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { GanttComponent, GanttModule, SelectionService} from '@syncfusion/ej2-angular-gantt';
import { SelectionSettingsModel } from '@syncfusion/ej2-angular-grids';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';

@Component({
  standalone: true,
  selector: 'app-root',
  imports: [GanttModule, ButtonModule],
  providers: [SelectionService],
  template: `
    <div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0 20px 0;">
      <button ejs-button (click)="selectCells([1, 3])">Select [1, 3]</button>
      <button ejs-button (click)="selectCells([0, 2])">Select [0, 2]</button>
      <button ejs-button (click)="selectCells([2, 4])">Select [2, 4]</button>
      <button ejs-button (click)="selectCells([0, 5])">Select [0, 5]</button>
      <button ejs-button (click)="selectCells([1, 6])">Select [1, 6]</button>
      <button ejs-button (click)="selectCells([0, 7])">Select [0, 7]</button>
      <button ejs-button (click)="selectCells([6, 7])">Select [6, 7]</button>
      <button ejs-button (click)="selectCells([4, 6])">Select [4, 6]</button>
      <button ejs-button (click)="selectCells([2, 5])">Select [2, 5]</button>
    </div>
    <ejs-gantt #gantt height="370px" [dataSource]="data" [taskFields]="taskSettings" [selectionSettings]="selectionSettings" enableHover="true">
    </ejs-gantt>`,
  encapsulation: ViewEncapsulation.None
})

export class AppComponent implements OnInit {
  @ViewChild('gantt', { static: true }) public ganttInstance!: GanttComponent;
  public data: object[] = [];
  public taskSettings: object = {};
  public selectionSettings: SelectionSettingsModel = {};

  ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Project Kickoff', StartDate: new Date('2023-04-01'), Duration: 5, Progress: 40 },
      { TaskID: 2, TaskName: 'Requirement Gathering', StartDate: new Date('2023-04-06'), Duration: 4, ParentID: 1, Progress: 60 },
      { TaskID: 3, TaskName: 'Feasibility Study', StartDate: new Date('2023-04-10'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 4, TaskName: 'Initial Approval', StartDate: new Date('2023-04-14'), Duration: 3, ParentID: 1, Progress: 30 },
      { TaskID: 5, TaskName: 'Design Phase', StartDate: new Date('2023-04-18'), Duration: 6, Progress: 20 },
      { TaskID: 6, TaskName: 'UI/UX Design', StartDate: new Date('2023-04-24'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 7, TaskName: 'Architecture Planning', StartDate: new Date('2023-04-27'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 8, TaskName: 'Final Review', StartDate: new Date('2023-04-30'), Duration: 2, ParentID: 5, Progress: 50 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress',
      parentID: 'ParentID'
    };
    this.selectionSettings = {
      mode: 'Row',
      type: 'Multiple'
    };
  }

  public selectCells(cellIndexes: number[]): void {
    this.ganttInstance.clearSelection();
    this.ganttInstance.selectCells(cellIndexes);
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Get selected cell information

To retrieve information about selected cells in the Gantt chart, use methods like getSelectedRowCellIndexes method to get the list of row and column indexes for selected cells, and the getCellSelectedRecords method to retrieve the related data objects for each selected cell.

import { Component, ViewChild, OnInit, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
import { GanttComponent, GanttModule, SelectionService, SelectionSettingsModel } from '@syncfusion/ej2-angular-gantt';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DialogModule } from '@syncfusion/ej2-angular-popups';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, GanttModule, ButtonModule, DialogModule],
  providers: [SelectionService],
  encapsulation: ViewEncapsulation.None,
  template: `
    <div style="padding: 10px 0px 20px 0px">
      <button ejs-button class="btn" (click)="showSelectedDetails()">Show Selected Cell Details</button>
    </div>
    <ejs-gantt #gantt height="370px" [dataSource]="data" [taskFields]="taskSettings" [selectionSettings]="selectionSettings"> 
    </ejs-gantt>
    <ejs-dialog [header]="'Selected Cell Details'" [visible]="dialogVisible" (close)="dialogClose()" showCloseIcon="true" width="600px" height="300px" [position]="{ X: 300, Y: 100 }">
      <ng-template #content>
        <div style="max-height: 240px; overflow-y: auto; padding-right: 10px;">
          <table border="1" cellpadding="5" cellspacing="0" style="width: 100%;">
            <thead>
              <tr>
                <th>Row Index</th>
                <th>Cell Index</th>
                <th>Row Details</th>
              </tr>
            </thead>
            <tbody>
              <tr *ngFor="let detail of selectedDetails">
                <td></td>
                <td></td>
                <td>
                  <table style="width: 100%; border-collapse: collapse;">
                    <tr>
                      <td><strong>Task ID:</strong></td>
                      <td></td>
                    </tr>
                    <tr>
                      <td><strong>Task Name:</strong></td>
                      <td></td>
                    </tr>
                    <tr>
                      <td><strong>Start Date:</strong></td>
                      <td></td>
                    </tr>
                    <tr>
                      <td><strong>Duration:</strong></td>
                      <td></td>
                    </tr>
                    <tr>
                      <td><strong>Progress:</strong></td>
                      <td>%</td>
                    </tr>
                  </table>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </ng-template>
    </ejs-dialog>`
})

export class AppComponent implements OnInit {
  @ViewChild('gantt', { static: true }) public ganttInstance!: GanttComponent;
  public data: object[] = [];
  public taskSettings: object = {};
  public selectionSettings: SelectionSettingsModel = {
    mode: 'Cell',
    type: 'Multiple'
  };
  public selectedDetails: {
    rowIndex: number;
    cellIndex: string;
    record: GanttTask;
  }[] = [];

  public dialogVisible: boolean = false;

  ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 80 },
      { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
    ];

    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      endDate: 'EndDate',
      duration: 'Duration',
      progress: 'Progress',
      parentID: 'ParentID'
    };
  }

  public showSelectedDetails(): void {
    const records = this.ganttInstance.selectionModule.getCellSelectedRecords() as GanttTask[];
    const indexes = this.ganttInstance.selectionModule.getSelectedRowCellIndexes();

    this.selectedDetails = indexes.map((index, i) => ({
      rowIndex: index.rowIndex,
      cellIndex: index.cellIndexes.join(', '),
      record: records[i] || {}
    }));

    this.dialogVisible = true;
  }

  public dialogClose(): void {
    this.dialogVisible = false;
  }
}

interface GanttTask {
  TaskID: number;
  TaskName: string;
  StartDate: Date;
  EndDate?: Date;
  Duration?: number;
  Progress?: number;
  ParentID?: number;
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Customize cell selection action

You may customize cell selection behavior in the Gantt chart using cellSelecting, cellSelected, cellDeselecting, and cellDeselected events. These events provide dynamic control over selection, allowing conditional logic and visual updates based on specific criteria.

The following sample demonstrates customizing cell selection in the Gantt chart using Syncfusion events. In the cellSelected event, the background color is set to rgb(96, 158, 101), while selection is canceled in the cellSelecting event when the TaskName is Perform Soil test. During cellDeselecting, the text color is changed to rgb(253, 253, 253), and in the cellDeselected event, the background color is updated to rgb(245, 69, 69).

import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
import { GanttComponent, GanttModule, CellSelectingEventArgs, SelectionService, SelectionSettingsModel } from '@syncfusion/ej2-angular-gantt';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { CellSelectEventArgs, CellDeselectEventArgs } from '@syncfusion/ej2-angular-grids';

interface Task {
  TaskID: number;
  TaskName: string;
  StartDate: Date;
  EndDate?: Date;
  Duration?: number;
  Progress?: number;
  ParentID?: number;
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, GanttModule, ButtonModule],
  providers: [SelectionService],
  encapsulation: ViewEncapsulation.None,
  template: `
    <p id="message" *ngIf="showMessage"></p>
    <ejs-gantt #gantt height="370px" [dataSource]="data" [taskFields]="taskSettings" (cellSelected)="cellSelected($event)" (cellSelecting)="cellSelecting($event)" (cellDeselected)="cellDeselected($event)" (cellDeselecting)="cellDeselecting($event)" [selectionSettings]="selectionSettings" enableHover="false">
    </ejs-gantt>`
})

export class AppComponent implements OnInit {
  @ViewChild('gantt', { static: true }) public ganttInstance!: GanttComponent;
  public data: Task[] = [];
  public taskSettings: object = {};
  public selectionSettings: SelectionSettingsModel = {};
  public showMessage = false;
  public message = '';

  ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 60 },
      { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 30 },
      { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 90 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 30 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 80 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      endDate: 'EndDate',
      duration: 'Duration',
      progress: 'Progress',
      parentID: 'ParentID'
    };
    this.selectionSettings = {
      mode: 'Cell',
      type: 'Single'
    };
  }

  public cellSelected(args: CellSelectEventArgs): void {
    this.message = `Trigger cellSelected`;
    this.showMessage = true;
    (args.currentCell as HTMLElement).style.backgroundColor = 'rgb(96, 158, 101)';
  }

  public cellSelecting(args: CellSelectingEventArgs): void {
    this.message = `Trigger cellSelecting`;
    this.showMessage = true;
    const task = args.data as Task;
    if (task.TaskName === 'Perform Soil test') {
      args.cancel = true;
      this.message += ' - Selection canceled for "Perform Soil test"';
    }
  }

  public cellDeselected(args: CellDeselectEventArgs): void {
    this.message = `Trigger cellDeselected`;
    this.showMessage = true;
    if (args.cells && args.cells.length > 0) {
      const cell = args.cells[0] as HTMLElement;
      cell.style.backgroundColor = 'rgb(245, 69, 69)';
    }
  }

  public cellDeselecting(args: CellDeselectEventArgs): void {
    this.message = `Trigger cellDeselecting`;
    this.showMessage = true;
    if (args.cells && args.cells.length > 0) {
      const cell = args.cells[0] as HTMLElement;
      cell.style.color = 'rgb(253, 253, 253)';
    }
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));