Syncfusion AI Assistant

How can I help you?

Row editing in Angular TreeGrid component

5 Sep 202524 minutes to read

In Row edit mode, when you begin editing a selected record, the entire row enters edit state. This allows you to modify all cell values in the row and save the changes to the data source. To enable row editing, set the editSettings.mode property to Row.

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import {ButtonModule} from '@syncfusion/ej2-angular-buttons'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'



import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';

@Component({
imports: [
        
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
    ],

providers: [PageService,
                SortService,
                FilterService,
                EditService,
                ToolbarService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data'  [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' childMapping='subtasks' >
        <e-columns>
                    <e-column field='taskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
                    <e-column field='taskName' headerText='Task Name' textAlign='Left' width=180></e-column>
                    <e-column field='priority' headerText='Priority' textAlign='Right' width=90></e-column>
                    <e-column field='startDate' headerText='Start Date' textAlign='Right' format='yMd' type='date' editType='datepickeredit' width=90></e-column>
                    <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
        </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];
    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' };
        this.toolbarOptions = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Automatically update a column based on another column’s edited value

Update a column value based on another column’s value while editing by using the Cell Edit Template feature.

In the example below, the price column value is updated based on changes in the units and unitPrice columns during batch editing.

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import {ButtonModule} from '@syncfusion/ej2-angular-buttons'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'



import { Component, OnInit} from '@angular/core';
import { summaryData } from './datasource';
import { EditSettingsModel, ToolbarItems, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { IEditCell } from '@syncfusion/ej2-angular-grids';
import { NumericTextBox } from '@syncfusion/ej2-inputs';

@Component({
imports: [
        
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
    ],

providers: [PageService,
                SortService,
                FilterService,
                EditService,
                ToolbarService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid id="treegrid" [dataSource]='data'  [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' childMapping='subtasks' (cellEdit)="cellEdit($event)">
                    <e-columns>
                        <e-column field='ID' headerText='ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
                        <e-column field='Name' headerText='Name' textAlign='Left' width=180></e-column>
                        <e-column field='units' headerText='Units' textAlign='Right' editType="numericedit" [edit]="unitsParams" format="C2" width=120></e-column>
                        <e-column field='unitPrice' headerText='Unit Price' textAlign='Right' editType="numericedit" [edit]="unitPriceParams" width=120></e-column>
                        <e-column field='price' headerText='Total Price' [allowEditing]= 'false' textAlign='Right' format="C2" width=110></e-column>
                    </e-columns>
                </ejs-treegrid>`
})

export class AppComponent implements OnInit {
  @ViewChild('treegrid')
  public treegrid?: TreeGridComponent;
  public data?: Object[];
  public editSettings?: EditSettingsModel;
  public toolbarOptions?: ToolbarItems[];
  public unitsParams?: IEditCell;
  public unitPriceParams?: IEditCell;

  public unitsElem?: HTMLElement;
  public unitsObj?: NumericTextBox;

  public unitPriceElem?: HTMLElement;
  public unitPriceObj?: NumericTextBox;

  ngOnInit(): void {
    this.data = summaryData;
    this.editSettings = {
      allowEditing: true,
      allowAdding: true,
      allowDeleting: true,
      mode: 'Row'
    };
    this.toolbarOptions = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
    this.unitsParams = {
      create: () => {
        this.unitsElem = document.createElement('input');
        return this.unitsElem;
      },
      read: () => {
        return (this.unitsObj as NumericTextBox).value;
      },
      destroy: () => {
        (this.unitsObj as NumericTextBox).destroy();
      },
      write: (args: any) => {
        this.unitsObj = new NumericTextBox({
          value: args.rowData[args.column.field],
          change: (() => {
            var formEle = (((this.treegrid as TreeGridComponent).element as HTMLElement).querySelector('form') as HTMLFormElement)['ej2_instances'][0];
            var totalCostFieldEle = formEle.getInputElement('price');
            totalCostFieldEle.value = (this.unitsObj as NumericTextBox).value * (this.unitPriceObj as NumericTextBox).value;
          }).bind(this)
        });
        this.unitsObj.appendTo(this.unitsElem);
      }
    };
    this.unitPriceParams = {
      create: () => {
        this.unitPriceElem = document.createElement('input');
        return this.unitPriceElem;
      },
      read: () => {
        return (this.unitPriceObj as NumericTextBox).value;
      },
      destroy: () => {
        (this.unitPriceObj as NumericTextBox).destroy();
      },
      write: (args: any) => {
        this.unitPriceObj = new NumericTextBox({
          value: args.rowData[args.column.field],
          change: (() => {
            var formEle = (((this.treegrid as TreeGridComponent).element as HTMLElement).querySelector('form') as HTMLFormElement)['ej2_instances'][0];
            var totalCostFieldEle = formEle.getInputElement('price');
            totalCostFieldEle.value = (this.unitsObj as NumericTextBox).value * (this.unitPriceObj as NumericTextBox).value;
          }).bind(this)
        });
        this.unitPriceObj.appendTo(this.unitPriceElem);
      }
    };
  }
  cellEdit(args: any) {
    if (args.columnName == 'price') {
      args.cancel = true;
    }
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Cancel edit based on condition

You can prevent TreeGrid CRUD operations (edit, add, delete) based on a custom condition by handling the actionBegin event with the appropriate requestType (such as beginEdit for editing, add for adding, and delete for deleting).

In the example below, CRUD operations are prevented when the priority column value is Low.

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import {ButtonModule} from '@syncfusion/ej2-angular-buttons'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'



import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';

@Component({
imports: [
        
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
    ],

providers: [PageService,
                SortService,
                FilterService,
                EditService,
                ToolbarService],
standalone: true,
    selector: 'app-container',
    template: `<button (click)="btnClick($event)">TreeGrid is Addable</button>
                <ejs-treegrid [dataSource]='data' [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' (actionBegin)="actionBegin($event)" childMapping='subtasks' >
                    <e-columns>
                        <e-column field='taskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
                        <e-column field='taskName' headerText='Task Name' textAlign='Left' width=180></e-column>
                        <e-column field='priority' headerText='Priority' textAlign='Right' width=90></e-column>
                        <e-column field='startDate' headerText='Start Date' textAlign='Right' format='yMd' type='date' editType='datepickeredit' width=90></e-column>
                        <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];
    public isAddable: boolean = true;

    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true };
        this.toolbarOptions = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
    }

    actionBegin(args: any) {
        if (args.requestType == 'beginEdit') {
            if (args.rowData['priority'] == 'Low') {
                args.cancel = true;
            }
        }
        if (args.requestType == 'delete') {
            if (args.data[0]['priority'] == 'Low') {
                args.cancel = true;
            }
        }
        if (args.requestType == 'add') {
            if (!this.isAddable) {
                args.cancel = true;
            }
        }
    }
    btnClick(args: any) {
        args.target.innerText == 'TreeGrid is Addable' ? (args.target.innerText = 'TreeGrid is Not Addable') : (args.target.innerText = 'TreeGrid is Addable');
        this.isAddable = !this.isAddable;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Perform CRUD action programmatically

TreeGrid methods enable you to perform CRUD operations programmatically:

  • addRecord: Add a new record (optionally specifying data and index/position).
  • startEdit: Change the selected row to edit state.
  • updateRow: Update a row by index.
  • setCellValue: Update the value for a cell using primary key, field name, and new value.
  • setRowData: Update an entire row using primary key and data.
  • deleteRecord: Delete a selected row.
  • closeEdit: Cancel editing programmatically in Row and Dialog modes.
  • deleteRow: Delete a row by providing the row element.
import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import {ButtonModule} from '@syncfusion/ej2-angular-buttons'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'

import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';

@Component({
imports: [
        
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
    ],

providers: [PageService,
                SortService,
                FilterService,
                EditService,
                ToolbarService],
standalone: true,
    selector: 'app-container',
    template: `<button ej-button id='edit' (click)='clickEdit()'>Edit</button>
               <button ej-button id='add' (click)='clickAdd()'>Add</button>
               <button ej-button id='delete' (click)='clickDelete()'>Delete</button>
               <button ej-button id='updaterow' (click)='clickUpdateRow()'>Update Row</button>
               <button ej-button id='updatecell' (click)='clickUpdateCell()'>Update cell</button>
               <button ej-button id='updateEntireRow' (click)='clickupdateEntireRow()'>Update entire Row</button>
               <ejs-treegrid #treegrid id="TreeGrid" [dataSource]='data' [editSettings]='editSettings' [treeColumnIndex]='1' height='270' childMapping='subtasks'>
                    <e-columns>
                        <e-column field='taskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
                        <e-column field='taskName' headerText='Task Name' textAlign='Left' width=180></e-column>
                        <e-column field='priority' headerText='Priority' textAlign='Right' width=90></e-column>
                        <e-column field='startDate' headerText='Start Date' textAlign='Right' format='yMd' type='date' width=90></e-column>
                        <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {
    public editSettings?: EditSettingsModel;
    public data?: object[];
    @ViewChild('treegrid')
    public treegrid?: TreeGridComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: "Row" };
    }

    clickEdit(){
        (this.treegrid as TreeGridComponent).startEdit();
    }
    clickAdd(){
        (this.treegrid as TreeGridComponent).addRecord({ taskID: "150", taskName: "Newly Added", priority: "Normal", duration: "5",startDate: "2/3/2017"  });
    }
    clickDelete(){
        (this.treegrid as TreeGridComponent).deleteRecord();
    }
    clickUpdateRow(){
        (this.treegrid as TreeGridComponent).updateRow(0, { taskID: 1, taskName: 'Updated', priority: 'Low', duration: 15, startDate: '12/3/2019' });
    }
    clickUpdateCell(){
        (this.treegrid as TreeGridComponent).setCellValue(((this.treegrid as TreeGridComponent).getCurrentViewRecords()[0] as any).taskID,'taskName','Value Changed');
    }
    clickupdateEntireRow() {
        (this.treegrid as TreeGridComponent).setRowData(((this.treegrid as TreeGridComponent).getCurrentViewRecords()[1] as any).taskID, (this.treegrid as TreeGridComponent).flatData[35]);
      }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Show delete confirmation dialog

A delete confirmation dialog can be shown by setting showDeleteConfirmDialog in the [editSettings] to true.

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import {ButtonModule} from '@syncfusion/ej2-angular-buttons'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'



import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';

@Component({
imports: [
        
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
    ],

providers: [PageService,
                SortService,
                FilterService,
                EditService,
                ToolbarService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data'  [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' childMapping='subtasks' >
                    <e-columns>
                        <e-column field='taskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
                        <e-column field='taskName' headerText='Task Name' textAlign='Left' width=180></e-column>
                        <e-column field='priority' headerText='Priority' textAlign='Right' width=90></e-column>
                        <e-column field='startDate' headerText='Start Date' textAlign='Right' format='yMd' type='date' width=90></e-column>
                        <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];

    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { showDeleteConfirmDialog: true, allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' };
        this.toolbarOptions = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

The showDeleteConfirmDialog property is supported in all editing modes.

Move focus to a particular cell when editing a row

Use the recordDoubleClick event to focus the specific cell that was double-clicked when editing a row, rather than defaulting to the first cell.

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import {ButtonModule} from '@syncfusion/ej2-angular-buttons'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'



import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems, TreeGridComponent, Toolbar } from '@syncfusion/ej2-angular-treegrid';
import { Grid } from '@syncfusion/ej2-angular-grids';

@Component({
imports: [
        
        TreeGridModule,
        ButtonModule,
        DropDownListAllModule,
    ],

providers: [PageService,
                SortService,
                FilterService,
                EditService,
                ToolbarService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid [dataSource]='data'  [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' childMapping='subtasks' (actionComplete)='actionComplete($event)' (recordDoubleClick)='recordDoubleClick($event)' >
                    <e-columns>
                        <e-column field='taskID' headerText='Task ID' [isPrimaryKey]='true' textAlign='Right' width=90></e-column>
                        <e-column field='taskName' headerText='Task Name' textAlign='Left' width=180></e-column>
                        <e-column field='priority' headerText='Priority' textAlign='Right' width=90></e-column>
                        <e-column field='startDate' headerText='Start Date' textAlign='Right' format='yMd' type='date' width=90></e-column>
                        <e-column field='duration' headerText='Duration' textAlign='Right' width=80></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {
    public data?: object[];
    public editSettings?: EditSettingsModel;
    public fieldName?: string;
    @ViewChild('treegrid')
    public treegrid?: TreeGridComponent;
    public toolbarOptions?: Toolbar;

    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: "Row"};
    }
    actionComplete(e: any) {
        if (e.requestType === "beginEdit") {
            // focus the column
            e.form.elements[(((this.treegrid as TreeGridComponent).grid as Grid).element as HTMLElement).getAttribute("id") as string + this.fieldName].focus();
        }
    }
    recordDoubleClick(e: any) {
        var clickedColumnIndex = e.cell.getAttribute("aria-colindex");
        this.fieldName = (this.treegrid as TreeGridComponent | any).columnModel[parseInt(clickedColumnIndex)].field;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));