Built-In Directives

The TreeList provides built-in directives which simplify the implementation of its editing operations.

Overview

The TreeList provides directives which automate common editing scenarios:

The editing directives can be used together with the data binding directives or custom data binding.

Reactive Editing Directive

The kendoTreeListReactiveEditing directive helps you to skip the boilerplate code, which is required to set up the TreeList for editing with Reactive Forms. The directive requires a createFormGroup input that has to be set to a function, which creates a FormGroup for the row model or for the new model when the user adds a new row.

The following example demonstrates how to use the kendoTreeListReactiveEditing directive.

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

import { CreateFormGroupArgs } from '@progress/kendo-angular-treelist';
import { Employee, employees } from './employees';

@Component({
  selector: 'my-app',
  template: `
    <kendo-treelist
        kendoTreeListExpandable
        [kendoTreeListFlatBinding]="data"
        idField="id" parentIdField="managerId"
        [kendoTreeListReactiveEditing]="createFormGroup"
        [height]="500"
        [pageSize]="10"
        [pageable]="true"
        [sortable]="true"
    >
        <ng-template kendoTreeListToolbarTemplate>
            <button kendoTreeListAddCommand type="button">Add new</button>
        </ng-template>
        <kendo-treelist-column [expandable]="true" field="name" title="Name">
        </kendo-treelist-column>
        <kendo-treelist-column field="title" title="Title">
        </kendo-treelist-column>
        <kendo-treelist-column field="phone" title="Phone">
        </kendo-treelist-column>
        <kendo-treelist-command-column width="140">
            <ng-template kendoTreeListCellTemplate let-isNew="isNew" let-cellContext="cellContext">
                <!-- "Add Child" command directive, will not be visible in edit mode -->
                <button [kendoTreeListAddCommand]="cellContext"
                        icon="filter-add-expression" title="Add Child">
                </button>

                <!-- "Edit" command directive, will not be visible in edit mode -->
                <button [kendoTreeListEditCommand]="cellContext"
                        icon="edit" title="Edit" [primary]="true">
                </button>

                <!-- "Remove" command directive, will not be visible in edit mode -->
                <button [kendoTreeListRemoveCommand]="cellContext"
                        icon="delete" title="Remove">
                </button>

                <!-- "Save" command directive, will be visible only in edit mode -->
                <button [kendoTreeListSaveCommand]="cellContext"
                        [disabled]="formGroup?.invalid"
                        icon="save" title="{{ isNew ? 'Add' : 'Update' }}">
                </button>

                <!-- "Cancel" command directive, will be visible only in edit mode -->
                <button [kendoTreeListCancelCommand]="cellContext"
                        icon="cancel" title="{{ isNew ? 'Discard changes' : 'Cancel' }}">
                </button>
            </ng-template>
        </kendo-treelist-command-column>
      </kendo-treelist>
  `
})
export class AppComponent {
    public data: Employee[] = employees;
    public formGroup: FormGroup;

    constructor() {
        this.createFormGroup = this.createFormGroup.bind(this);
    }

    public createFormGroup({ isNew, dataItem }: CreateFormGroupArgs): any {
        const item = isNew ? {} : dataItem;

        this.formGroup = new FormGroup({
            'id': new FormControl(item.id),
            'parentId': new FormControl(item.parentId),
            'name': new FormControl(item.name, Validators.required),
            'title': new FormControl(item.title),
            'phone': new FormControl(item.phone, Validators.required)
        });

        return this.formGroup;
    }
}

export interface Employee {
    id: number;
    managerId?: number;
    name: string;
    title: string;
    phone: string;
    hireDate?: Date;
}

export const employees: Employee[] = [
    {
        id: 1,
        name: 'Daryl Sweeney',
        title: 'Chief Executive Officer',
        phone: '(555) 924-9726',
        managerId: null,
        hireDate: new Date('2019-01-15')
    },
    {
        id: 2,
        name: 'Guy Wooten',
        title: 'Chief Technical Officer',
        phone: '(438) 738-4935',
        managerId: 1,
        hireDate: new Date('2019-02-19')
    },
    {
        id: 32,
        name: 'Buffy Weber',
        title: 'VP, Engineering',
        phone: '(699) 838-6121',
        managerId: 2,
        hireDate: new Date('2019-04-13')
    },
    {
        id: 11,
        name: 'Hyacinth Hood',
        title: 'Team Lead',
        phone: '(889) 345-2438',
        managerId: 32,
        hireDate: new Date('2018-01-17')
    },
    {
        id: 60,
        name: 'Akeem Carr',
        title: 'Junior Software Developer',
        phone: '(738) 136-2814',
        managerId: 11,
        hireDate: new Date('2018-01-18')
    },
    {
        id: 78,
        name: 'Rinah Simon',
        title: 'Software Developer',
        phone: '(285) 912-5271',
        managerId: 11,
        hireDate: new Date('2018-03-17')
    },
    {
        id: 42,
        name: 'Gage Daniels',
        title: 'Software Architect',
        phone: '(107) 290-6260',
        managerId: 32,
        hireDate: new Date('2019-03-14')
    },
    {
        id: 43,
        name: 'Constance Vazquez',
        title: 'Director, Engineering',
        phone: '(800) 301-1978',
        managerId: 32,
        hireDate: new Date('2018-03-18')
    },
    {
        id: 46,
        name: 'Darrel Solis',
        title: 'Team Lead',
        phone: '(327) 977-0216',
        managerId: 43,
        hireDate: new Date('2019-04-15')
    },
    {
        id: 47,
        name: 'Brian Yang',
        title: 'Senior Software Developer',
        phone: '(565) 146-5435',
        managerId: 46,
        hireDate: new Date('2019-02-21')
    },
    {
        id: 50,
        name: 'Lillian Bradshaw',
        title: 'Software Developer',
        phone: '(323) 509-3479',
        managerId: 46,
        hireDate: new Date('2019-05-23')
    },
    {
        id: 51,
        name: 'Christian Palmer',
        title: 'Technical Lead',
        phone: '(490) 421-8718',
        managerId: 46,
        hireDate: new Date('2019-04-16')
    },
    {
        id: 55,
        name: 'Summer Mosley',
        title: 'QA Engineer',
        phone: '(784) 962-2301',
        managerId: 46,
        hireDate: new Date('2019-09-21')
    },
    {
        id: 56,
        name: 'Barry Ayers',
        title: 'Software Developer',
        phone: '(452) 373-9227',
        managerId: 46,
        hireDate: new Date('2018-04-16')
    },
    {
        id: 59,
        name: 'Keiko Espinoza',
        title: 'Junior QA Engineer',
        phone: '(226) 600-5305',
        managerId: 46,
        hireDate: new Date('2018-01-22')
    },
    {
        id: 61,
        name: 'Candace Pickett',
        title: 'Support Officer',
        phone: '(120) 117-7475',
        managerId: 46,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 63,
        name: 'Mia Caldwell',
        title: 'Team Lead',
        phone: '(848) 636-6470',
        managerId: 43,
        hireDate: new Date('2018-07-17')
    },
    {
        id: 65,
        name: 'Thomas Terry',
        title: 'Senior Enterprise Support Officer',
        phone: '(764) 831-4248',
        managerId: 63,
        hireDate: new Date('2018-07-14')
    },
    {
        id: 67,
        name: 'Ruth Downs',
        title: 'Senior Software Developer',
        phone: '(138) 991-1440',
        managerId: 63,
        hireDate: new Date('2018-08-14')
    },
    {
        id: 70,
        name: 'Yasir Wilder',
        title: 'Senior QA Engineer',
        phone: '(759) 701-8665',
        managerId: 63,
        hireDate: new Date('2019-08-17')
    },
    {
        id: 71,
        name: 'Flavia Short',
        title: 'Support Officer',
        phone: '(370) 133-9238',
        managerId: 63,
        hireDate: new Date('2018-06-15')
    },
    {
        id: 74,
        name: 'Aaron Roach',
        title: 'Junior Software Developer',
        phone: '(958) 717-9230',
        managerId: 63,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 75,
        name: 'Eric Russell',
        title: 'Software Developer',
        phone: '(516) 575-8505',
        managerId: 63,
        hireDate: new Date('2019-09-13')
    },
    {
        id: 76,
        name: 'Cheyenne Olson',
        title: 'Software Developer',
        phone: '(241) 645-0257',
        managerId: 63,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 77,
        name: 'Shaine Avila',
        title: 'UI Designer',
        phone: '(844) 435-1360',
        managerId: 63,
        hireDate: new Date('2018-01-22')
    },
    {
        id: 81,
        name: 'Chantale Long',
        title: 'Senior QA Engineer',
        phone: '(252) 419-6891',
        managerId: 63,
        hireDate: new Date('2018-09-14')
    },
    {
        id: 83,
        name: 'Dane Cruz',
        title: 'Junior Software Developer',
        phone: '(946) 701-6165',
        managerId: 63,
        hireDate: new Date('2019-03-15')
    },
    {
        id: 84,
        name: 'Regan Patterson',
        title: 'Technical Writer',
        phone: '(265) 946-1765',
        managerId: 63,
        hireDate: new Date('2019-05-17')
    },
    {
        id: 85,
        name: 'Drew Mckay',
        title: 'Senior Software Developer',
        phone: '(327) 293-0162',
        managerId: 63,
        hireDate: new Date('2019-05-21')
    },
    {
        id: 88,
        name: 'Bevis Miller',
        title: 'Senior Software Developer',
        phone: '(525) 557-0169',
        managerId: 63,
        hireDate: new Date('2018-08-15')
    },
    {
        id: 89,
        name: 'Bruce Mccarty',
        title: 'Support Officer',
        phone: '(936) 777-8730',
        managerId: 63,
        hireDate: new Date('2019-10-21')
    },
    {
        id: 90,
        name: 'Ocean Blair',
        title: 'Team Lead',
        phone: '(343) 586-6614',
        managerId: 43,
        hireDate: new Date('2018-06-20')
    },
    {
        id: 91,
        name: 'Guinevere Osborn',
        title: 'Software Developer',
        phone: '(424) 741-0006',
        managerId: 90,
        hireDate: new Date('2019-06-17')
    },
    {
        id: 92,
        name: 'Olga Strong',
        title: 'Graphic Designer',
        phone: '(949) 417-1168',
        managerId: 90,
        hireDate: new Date('2018-06-15')
    },
    {
        id: 93,
        name: 'Robert Orr',
        title: 'Support Officer',
        phone: '(977) 341-3721',
        managerId: 90,
        hireDate: new Date('2018-06-22')
    },
    {
        id: 95,
        name: 'Odette Sears',
        title: 'Senior Software Developer',
        phone: '(264) 818-6576',
        managerId: 90,
        hireDate: new Date('2019-05-20')
    },
    {
        id: 45,
        name: 'Zelda Medina',
        title: 'QA Architect',
        phone: '(563) 359-6023',
        managerId: 32,
        hireDate: new Date('2018-08-16')
    },
    {
        id: 3,
        name: 'Priscilla Frank',
        title: 'Chief Product Officer',
        phone: '(217) 280-5300',
        managerId: 1,
        hireDate: new Date('2019-04-22')
    },
    {
        id: 4,
        name: 'Ursula Holmes',
        title: 'EVP, Product Strategy',
        phone: '(370) 983-8796',
        managerId: 3,
        hireDate: new Date('2018-01-15')
    },
    {
        id: 24,
        name: 'Melvin Carrillo',
        title: 'Director, Developer Relations',
        phone: '(344) 496-9555',
        managerId: 3,
        hireDate: new Date('2018-01-17')
    },
    {
        id: 29,
        name: 'Martha Chavez',
        title: 'Developer Advocate',
        phone: '(140) 772-7509',
        managerId: 24,
        hireDate: new Date('2018-05-14')
    },
    {
        id: 30,
        name: 'Oren Fox',
        title: 'Developer Advocate',
        phone: '(714) 284-2408',
        managerId: 24,
        hireDate: new Date('2018-07-19')
    },
    {
        id: 41,
        name: 'Amos Barr',
        title: 'Developer Advocate',
        phone: '(996) 587-8405',
        managerId: 24,
        hireDate: new Date('2019-01-16')
    }
  ];
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ReactiveFormsModule } from '@angular/forms';

import { TreeListModule } from '@progress/kendo-angular-treelist';

import { AppComponent } from './app.component';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        ReactiveFormsModule,
        TreeListModule
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Template Editing Directive

The kendoTreeListTemplateEditing directive simplifies the setup when you use the Angular Template-Driven Forms in your project. The directive requires a createNewItem input (which has to be set to a function) that creates a new instance of the edited model.

The following example demonstrates how to use the kendoTreeListTemplateEditing directive.

import { Component } from '@angular/core';
import { Employee, employees } from './employees';

@Component({
  selector: 'my-app',
  template: `
  <form novalidate #myForm="ngForm">
      <kendo-treelist
          kendoTreeListExpandable
          [kendoTreeListFlatBinding]="data"
          idField="id" parentIdField="managerId"
          [kendoTreeListTemplateEditing]="createNewEmployee"
          [height]="500"
          [pageSize]="10"
          [pageable]="true"
          [sortable]="true"
      >
          <ng-template kendoTreeListToolbarTemplate>
              <button kendoTreeListAddCommand type="button">Add new</button>
          </ng-template>
          <kendo-treelist-column [expandable]="true" field="name" title="Name">
              <ng-template kendoTreeListEditTemplate let-dataItem="dataItem">
                  <input [(ngModel)]="dataItem.name" name="name" class="k-textbox" required/>
              </ng-template>
          </kendo-treelist-column>
          <kendo-treelist-column field="title" title="Title">
              <ng-template kendoTreeListEditTemplate let-dataItem="dataItem">
                  <input [(ngModel)]="dataItem.title" name="title" class="k-textbox"/>
              </ng-template>
          </kendo-treelist-column>
          <kendo-treelist-column field="phone" title="Phone" editor="numeric" format="#">
              <ng-template kendoTreeListEditTemplate let-dataItem="dataItem">
                  <input
                      [(ngModel)]="dataItem.phone"
                      name="phone"
                      required
                      min="0"
                      max="99"
                      class="k-textbox"
                      type="number"/>
              </ng-template>
          </kendo-treelist-column>
          <kendo-treelist-command-column width="140">
              <ng-template kendoTreeListCellTemplate let-isNew="isNew" let-cellContext="cellContext">
                  <!-- "Add Child" command directive, will not be visible in edit mode -->
                  <button [kendoTreeListAddCommand]="cellContext"
                          icon="filter-add-expression" title="Add Child">
                  </button>

                  <!-- "Edit" command directive, will not be visible in edit mode -->
                  <button [kendoTreeListEditCommand]="cellContext"
                          icon="edit" title="Edit" [primary]="true">
                  </button>

                  <!-- "Remove" command directive, will not be visible in edit mode -->
                  <button [kendoTreeListRemoveCommand]="cellContext"
                          icon="delete" title="Remove">
                  </button>

                  <!-- "Save" command directive, will be visible only in edit mode -->
                  <button [kendoTreeListSaveCommand]="cellContext"
                          [disabled]="formGroup?.invalid"
                          icon="save" title="{{ isNew ? 'Add' : 'Update' }}">
                  </button>

                  <!-- "Cancel" command directive, will be visible only in edit mode -->
                  <button [kendoTreeListCancelCommand]="cellContext"
                          icon="cancel" title="{{ isNew ? 'Discard changes' : 'Cancel' }}">
                  </button>
              </ng-template>
          </kendo-treelist-command-column>
      </kendo-treelist>
    </form>
  `
})
export class AppComponent {
    public data: Employee[] = employees;

    public createNewEmployee(): any {
        return {};
    }
}

export interface Employee {
    id: number;
    managerId?: number;
    name: string;
    title: string;
    phone: string;
    hireDate?: Date;
}

export const employees: Employee[] = [
    {
        id: 1,
        name: 'Daryl Sweeney',
        title: 'Chief Executive Officer',
        phone: '(555) 924-9726',
        managerId: null,
        hireDate: new Date('2019-01-15')
    },
    {
        id: 2,
        name: 'Guy Wooten',
        title: 'Chief Technical Officer',
        phone: '(438) 738-4935',
        managerId: 1,
        hireDate: new Date('2019-02-19')
    },
    {
        id: 32,
        name: 'Buffy Weber',
        title: 'VP, Engineering',
        phone: '(699) 838-6121',
        managerId: 2,
        hireDate: new Date('2019-04-13')
    },
    {
        id: 11,
        name: 'Hyacinth Hood',
        title: 'Team Lead',
        phone: '(889) 345-2438',
        managerId: 32,
        hireDate: new Date('2018-01-17')
    },
    {
        id: 60,
        name: 'Akeem Carr',
        title: 'Junior Software Developer',
        phone: '(738) 136-2814',
        managerId: 11,
        hireDate: new Date('2018-01-18')
    },
    {
        id: 78,
        name: 'Rinah Simon',
        title: 'Software Developer',
        phone: '(285) 912-5271',
        managerId: 11,
        hireDate: new Date('2018-03-17')
    },
    {
        id: 42,
        name: 'Gage Daniels',
        title: 'Software Architect',
        phone: '(107) 290-6260',
        managerId: 32,
        hireDate: new Date('2019-03-14')
    },
    {
        id: 43,
        name: 'Constance Vazquez',
        title: 'Director, Engineering',
        phone: '(800) 301-1978',
        managerId: 32,
        hireDate: new Date('2018-03-18')
    },
    {
        id: 46,
        name: 'Darrel Solis',
        title: 'Team Lead',
        phone: '(327) 977-0216',
        managerId: 43,
        hireDate: new Date('2019-04-15')
    },
    {
        id: 47,
        name: 'Brian Yang',
        title: 'Senior Software Developer',
        phone: '(565) 146-5435',
        managerId: 46,
        hireDate: new Date('2019-02-21')
    },
    {
        id: 50,
        name: 'Lillian Bradshaw',
        title: 'Software Developer',
        phone: '(323) 509-3479',
        managerId: 46,
        hireDate: new Date('2019-05-23')
    },
    {
        id: 51,
        name: 'Christian Palmer',
        title: 'Technical Lead',
        phone: '(490) 421-8718',
        managerId: 46,
        hireDate: new Date('2019-04-16')
    },
    {
        id: 55,
        name: 'Summer Mosley',
        title: 'QA Engineer',
        phone: '(784) 962-2301',
        managerId: 46,
        hireDate: new Date('2019-09-21')
    },
    {
        id: 56,
        name: 'Barry Ayers',
        title: 'Software Developer',
        phone: '(452) 373-9227',
        managerId: 46,
        hireDate: new Date('2018-04-16')
    },
    {
        id: 59,
        name: 'Keiko Espinoza',
        title: 'Junior QA Engineer',
        phone: '(226) 600-5305',
        managerId: 46,
        hireDate: new Date('2018-01-22')
    },
    {
        id: 61,
        name: 'Candace Pickett',
        title: 'Support Officer',
        phone: '(120) 117-7475',
        managerId: 46,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 63,
        name: 'Mia Caldwell',
        title: 'Team Lead',
        phone: '(848) 636-6470',
        managerId: 43,
        hireDate: new Date('2018-07-17')
    },
    {
        id: 65,
        name: 'Thomas Terry',
        title: 'Senior Enterprise Support Officer',
        phone: '(764) 831-4248',
        managerId: 63,
        hireDate: new Date('2018-07-14')
    },
    {
        id: 67,
        name: 'Ruth Downs',
        title: 'Senior Software Developer',
        phone: '(138) 991-1440',
        managerId: 63,
        hireDate: new Date('2018-08-14')
    },
    {
        id: 70,
        name: 'Yasir Wilder',
        title: 'Senior QA Engineer',
        phone: '(759) 701-8665',
        managerId: 63,
        hireDate: new Date('2019-08-17')
    },
    {
        id: 71,
        name: 'Flavia Short',
        title: 'Support Officer',
        phone: '(370) 133-9238',
        managerId: 63,
        hireDate: new Date('2018-06-15')
    },
    {
        id: 74,
        name: 'Aaron Roach',
        title: 'Junior Software Developer',
        phone: '(958) 717-9230',
        managerId: 63,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 75,
        name: 'Eric Russell',
        title: 'Software Developer',
        phone: '(516) 575-8505',
        managerId: 63,
        hireDate: new Date('2019-09-13')
    },
    {
        id: 76,
        name: 'Cheyenne Olson',
        title: 'Software Developer',
        phone: '(241) 645-0257',
        managerId: 63,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 77,
        name: 'Shaine Avila',
        title: 'UI Designer',
        phone: '(844) 435-1360',
        managerId: 63,
        hireDate: new Date('2018-01-22')
    },
    {
        id: 81,
        name: 'Chantale Long',
        title: 'Senior QA Engineer',
        phone: '(252) 419-6891',
        managerId: 63,
        hireDate: new Date('2018-09-14')
    },
    {
        id: 83,
        name: 'Dane Cruz',
        title: 'Junior Software Developer',
        phone: '(946) 701-6165',
        managerId: 63,
        hireDate: new Date('2019-03-15')
    },
    {
        id: 84,
        name: 'Regan Patterson',
        title: 'Technical Writer',
        phone: '(265) 946-1765',
        managerId: 63,
        hireDate: new Date('2019-05-17')
    },
    {
        id: 85,
        name: 'Drew Mckay',
        title: 'Senior Software Developer',
        phone: '(327) 293-0162',
        managerId: 63,
        hireDate: new Date('2019-05-21')
    },
    {
        id: 88,
        name: 'Bevis Miller',
        title: 'Senior Software Developer',
        phone: '(525) 557-0169',
        managerId: 63,
        hireDate: new Date('2018-08-15')
    },
    {
        id: 89,
        name: 'Bruce Mccarty',
        title: 'Support Officer',
        phone: '(936) 777-8730',
        managerId: 63,
        hireDate: new Date('2019-10-21')
    },
    {
        id: 90,
        name: 'Ocean Blair',
        title: 'Team Lead',
        phone: '(343) 586-6614',
        managerId: 43,
        hireDate: new Date('2018-06-20')
    },
    {
        id: 91,
        name: 'Guinevere Osborn',
        title: 'Software Developer',
        phone: '(424) 741-0006',
        managerId: 90,
        hireDate: new Date('2019-06-17')
    },
    {
        id: 92,
        name: 'Olga Strong',
        title: 'Graphic Designer',
        phone: '(949) 417-1168',
        managerId: 90,
        hireDate: new Date('2018-06-15')
    },
    {
        id: 93,
        name: 'Robert Orr',
        title: 'Support Officer',
        phone: '(977) 341-3721',
        managerId: 90,
        hireDate: new Date('2018-06-22')
    },
    {
        id: 95,
        name: 'Odette Sears',
        title: 'Senior Software Developer',
        phone: '(264) 818-6576',
        managerId: 90,
        hireDate: new Date('2019-05-20')
    },
    {
        id: 45,
        name: 'Zelda Medina',
        title: 'QA Architect',
        phone: '(563) 359-6023',
        managerId: 32,
        hireDate: new Date('2018-08-16')
    },
    {
        id: 3,
        name: 'Priscilla Frank',
        title: 'Chief Product Officer',
        phone: '(217) 280-5300',
        managerId: 1,
        hireDate: new Date('2019-04-22')
    },
    {
        id: 4,
        name: 'Ursula Holmes',
        title: 'EVP, Product Strategy',
        phone: '(370) 983-8796',
        managerId: 3,
        hireDate: new Date('2018-01-15')
    },
    {
        id: 24,
        name: 'Melvin Carrillo',
        title: 'Director, Developer Relations',
        phone: '(344) 496-9555',
        managerId: 3,
        hireDate: new Date('2018-01-17')
    },
    {
        id: 29,
        name: 'Martha Chavez',
        title: 'Developer Advocate',
        phone: '(140) 772-7509',
        managerId: 24,
        hireDate: new Date('2018-05-14')
    },
    {
        id: 30,
        name: 'Oren Fox',
        title: 'Developer Advocate',
        phone: '(714) 284-2408',
        managerId: 24,
        hireDate: new Date('2018-07-19')
    },
    {
        id: 41,
        name: 'Amos Barr',
        title: 'Developer Advocate',
        phone: '(996) 587-8405',
        managerId: 24,
        hireDate: new Date('2019-01-16')
    }
  ];
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms';

import { TreeListModule } from '@progress/kendo-angular-treelist';

import { AppComponent } from './app.component';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        FormsModule,
        TreeListModule
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

In-Cell Editing Directive

The kendoTreeListInCellEditing directive sets up the TreeList for in-cell editing with Reactive Forms. The directive requires a createFormGroup input that has to be set to a function, which creates a FormGroup for the row model or for the new model when the user adds a new row.

For more information on how to disable the clicking on specific elements, refer to the article on in-cell editing.

The following example demonstrates how to use the kendoTreeListInCellEditing directive.

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

import { CreateFormGroupArgs } from '@progress/kendo-angular-treelist';
import { Employee, employees } from './employees';

@Component({
  selector: 'my-app',
  template: `
    <kendo-treelist
        kendoTreeListExpandable
        [kendoTreeListFlatBinding]="data"
        idField="id" parentIdField="managerId"
        [kendoTreeListInCellEditing]="createFormGroup"
        [height]="500"
        [pageSize]="10"
        [pageable]="true"
        [sortable]="true"
        >
        <ng-template kendoTreeListToolbarTemplate>
            <button kendoTreeListAddCommand type="button">Add new</button>
        </ng-template>
        <kendo-treelist-column [expandable]="true" field="name" title="Name">
        </kendo-treelist-column>
        <kendo-treelist-column field="title" title="Title">
        </kendo-treelist-column>
        <kendo-treelist-column field="phone" title="Phone">
        </kendo-treelist-column>
        <kendo-treelist-command-column width="140">
            <ng-template kendoTreeListCellTemplate let-isNew="isNew" let-cellContext="cellContext">
                <!-- "Add Child" command directive, will not be visible in edit mode -->
                <button [kendoTreeListAddCommand]="cellContext"
                        icon="filter-add-expression" title="Add Child">
                </button>

                <!-- "Remove" command directive, will not be visible in edit mode -->
                <button [kendoTreeListRemoveCommand]="cellContext"
                        icon="delete" title="Remove">
                </button>

                <!-- "Save" command directive, will be visible only in edit mode -->
                <button [kendoTreeListSaveCommand]="cellContext"
                        [disabled]="formGroup?.invalid"
                        icon="save" title="{{ isNew ? 'Add' : 'Update' }}">
                </button>

                <!-- "Cancel" command directive, will be visible only in edit mode -->
                <button [kendoTreeListCancelCommand]="cellContext"
                        icon="cancel" title="{{ isNew ? 'Discard changes' : 'Cancel' }}">
                </button>
            </ng-template>
        </kendo-treelist-command-column>
    </kendo-treelist>
  `
})
export class AppComponent {
    public data: Employee[] = employees;
    public formGroup: FormGroup;

    constructor() {
        this.createFormGroup = this.createFormGroup.bind(this);
    }

    public createFormGroup({ isNew, dataItem }: CreateFormGroupArgs): any {
        const item = isNew ? {} : dataItem;

        this.formGroup = new FormGroup({
            'id': new FormControl(item.id),
            'parentId': new FormControl(item.parentId),
            'name': new FormControl(item.name, Validators.required),
            'title': new FormControl(item.title),
            'phone': new FormControl(item.phone, Validators.required)
        });

        return this.formGroup;
    }
}

export interface Employee {
    id: number;
    managerId?: number;
    name: string;
    title: string;
    phone: string;
    hireDate?: Date;
}

export const employees: Employee[] = [
    {
        id: 1,
        name: 'Daryl Sweeney',
        title: 'Chief Executive Officer',
        phone: '(555) 924-9726',
        managerId: null,
        hireDate: new Date('2019-01-15')
    },
    {
        id: 2,
        name: 'Guy Wooten',
        title: 'Chief Technical Officer',
        phone: '(438) 738-4935',
        managerId: 1,
        hireDate: new Date('2019-02-19')
    },
    {
        id: 32,
        name: 'Buffy Weber',
        title: 'VP, Engineering',
        phone: '(699) 838-6121',
        managerId: 2,
        hireDate: new Date('2019-04-13')
    },
    {
        id: 11,
        name: 'Hyacinth Hood',
        title: 'Team Lead',
        phone: '(889) 345-2438',
        managerId: 32,
        hireDate: new Date('2018-01-17')
    },
    {
        id: 60,
        name: 'Akeem Carr',
        title: 'Junior Software Developer',
        phone: '(738) 136-2814',
        managerId: 11,
        hireDate: new Date('2018-01-18')
    },
    {
        id: 78,
        name: 'Rinah Simon',
        title: 'Software Developer',
        phone: '(285) 912-5271',
        managerId: 11,
        hireDate: new Date('2018-03-17')
    },
    {
        id: 42,
        name: 'Gage Daniels',
        title: 'Software Architect',
        phone: '(107) 290-6260',
        managerId: 32,
        hireDate: new Date('2019-03-14')
    },
    {
        id: 43,
        name: 'Constance Vazquez',
        title: 'Director, Engineering',
        phone: '(800) 301-1978',
        managerId: 32,
        hireDate: new Date('2018-03-18')
    },
    {
        id: 46,
        name: 'Darrel Solis',
        title: 'Team Lead',
        phone: '(327) 977-0216',
        managerId: 43,
        hireDate: new Date('2019-04-15')
    },
    {
        id: 47,
        name: 'Brian Yang',
        title: 'Senior Software Developer',
        phone: '(565) 146-5435',
        managerId: 46,
        hireDate: new Date('2019-02-21')
    },
    {
        id: 50,
        name: 'Lillian Bradshaw',
        title: 'Software Developer',
        phone: '(323) 509-3479',
        managerId: 46,
        hireDate: new Date('2019-05-23')
    },
    {
        id: 51,
        name: 'Christian Palmer',
        title: 'Technical Lead',
        phone: '(490) 421-8718',
        managerId: 46,
        hireDate: new Date('2019-04-16')
    },
    {
        id: 55,
        name: 'Summer Mosley',
        title: 'QA Engineer',
        phone: '(784) 962-2301',
        managerId: 46,
        hireDate: new Date('2019-09-21')
    },
    {
        id: 56,
        name: 'Barry Ayers',
        title: 'Software Developer',
        phone: '(452) 373-9227',
        managerId: 46,
        hireDate: new Date('2018-04-16')
    },
    {
        id: 59,
        name: 'Keiko Espinoza',
        title: 'Junior QA Engineer',
        phone: '(226) 600-5305',
        managerId: 46,
        hireDate: new Date('2018-01-22')
    },
    {
        id: 61,
        name: 'Candace Pickett',
        title: 'Support Officer',
        phone: '(120) 117-7475',
        managerId: 46,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 63,
        name: 'Mia Caldwell',
        title: 'Team Lead',
        phone: '(848) 636-6470',
        managerId: 43,
        hireDate: new Date('2018-07-17')
    },
    {
        id: 65,
        name: 'Thomas Terry',
        title: 'Senior Enterprise Support Officer',
        phone: '(764) 831-4248',
        managerId: 63,
        hireDate: new Date('2018-07-14')
    },
    {
        id: 67,
        name: 'Ruth Downs',
        title: 'Senior Software Developer',
        phone: '(138) 991-1440',
        managerId: 63,
        hireDate: new Date('2018-08-14')
    },
    {
        id: 70,
        name: 'Yasir Wilder',
        title: 'Senior QA Engineer',
        phone: '(759) 701-8665',
        managerId: 63,
        hireDate: new Date('2019-08-17')
    },
    {
        id: 71,
        name: 'Flavia Short',
        title: 'Support Officer',
        phone: '(370) 133-9238',
        managerId: 63,
        hireDate: new Date('2018-06-15')
    },
    {
        id: 74,
        name: 'Aaron Roach',
        title: 'Junior Software Developer',
        phone: '(958) 717-9230',
        managerId: 63,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 75,
        name: 'Eric Russell',
        title: 'Software Developer',
        phone: '(516) 575-8505',
        managerId: 63,
        hireDate: new Date('2019-09-13')
    },
    {
        id: 76,
        name: 'Cheyenne Olson',
        title: 'Software Developer',
        phone: '(241) 645-0257',
        managerId: 63,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 77,
        name: 'Shaine Avila',
        title: 'UI Designer',
        phone: '(844) 435-1360',
        managerId: 63,
        hireDate: new Date('2018-01-22')
    },
    {
        id: 81,
        name: 'Chantale Long',
        title: 'Senior QA Engineer',
        phone: '(252) 419-6891',
        managerId: 63,
        hireDate: new Date('2018-09-14')
    },
    {
        id: 83,
        name: 'Dane Cruz',
        title: 'Junior Software Developer',
        phone: '(946) 701-6165',
        managerId: 63,
        hireDate: new Date('2019-03-15')
    },
    {
        id: 84,
        name: 'Regan Patterson',
        title: 'Technical Writer',
        phone: '(265) 946-1765',
        managerId: 63,
        hireDate: new Date('2019-05-17')
    },
    {
        id: 85,
        name: 'Drew Mckay',
        title: 'Senior Software Developer',
        phone: '(327) 293-0162',
        managerId: 63,
        hireDate: new Date('2019-05-21')
    },
    {
        id: 88,
        name: 'Bevis Miller',
        title: 'Senior Software Developer',
        phone: '(525) 557-0169',
        managerId: 63,
        hireDate: new Date('2018-08-15')
    },
    {
        id: 89,
        name: 'Bruce Mccarty',
        title: 'Support Officer',
        phone: '(936) 777-8730',
        managerId: 63,
        hireDate: new Date('2019-10-21')
    },
    {
        id: 90,
        name: 'Ocean Blair',
        title: 'Team Lead',
        phone: '(343) 586-6614',
        managerId: 43,
        hireDate: new Date('2018-06-20')
    },
    {
        id: 91,
        name: 'Guinevere Osborn',
        title: 'Software Developer',
        phone: '(424) 741-0006',
        managerId: 90,
        hireDate: new Date('2019-06-17')
    },
    {
        id: 92,
        name: 'Olga Strong',
        title: 'Graphic Designer',
        phone: '(949) 417-1168',
        managerId: 90,
        hireDate: new Date('2018-06-15')
    },
    {
        id: 93,
        name: 'Robert Orr',
        title: 'Support Officer',
        phone: '(977) 341-3721',
        managerId: 90,
        hireDate: new Date('2018-06-22')
    },
    {
        id: 95,
        name: 'Odette Sears',
        title: 'Senior Software Developer',
        phone: '(264) 818-6576',
        managerId: 90,
        hireDate: new Date('2019-05-20')
    },
    {
        id: 45,
        name: 'Zelda Medina',
        title: 'QA Architect',
        phone: '(563) 359-6023',
        managerId: 32,
        hireDate: new Date('2018-08-16')
    },
    {
        id: 3,
        name: 'Priscilla Frank',
        title: 'Chief Product Officer',
        phone: '(217) 280-5300',
        managerId: 1,
        hireDate: new Date('2019-04-22')
    },
    {
        id: 4,
        name: 'Ursula Holmes',
        title: 'EVP, Product Strategy',
        phone: '(370) 983-8796',
        managerId: 3,
        hireDate: new Date('2018-01-15')
    },
    {
        id: 24,
        name: 'Melvin Carrillo',
        title: 'Director, Developer Relations',
        phone: '(344) 496-9555',
        managerId: 3,
        hireDate: new Date('2018-01-17')
    },
    {
        id: 29,
        name: 'Martha Chavez',
        title: 'Developer Advocate',
        phone: '(140) 772-7509',
        managerId: 24,
        hireDate: new Date('2018-05-14')
    },
    {
        id: 30,
        name: 'Oren Fox',
        title: 'Developer Advocate',
        phone: '(714) 284-2408',
        managerId: 24,
        hireDate: new Date('2018-07-19')
    },
    {
        id: 41,
        name: 'Amos Barr',
        title: 'Developer Advocate',
        phone: '(996) 587-8405',
        managerId: 24,
        hireDate: new Date('2019-01-16')
    }
  ];
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ReactiveFormsModule } from '@angular/forms';

import { TreeListModule } from '@progress/kendo-angular-treelist';

import { AppComponent } from './app.component';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        ReactiveFormsModule,
        TreeListModule
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Custom Service

By default, the built-in editing directives modify the data in memory. You can plug-in different persistence methods by implementing a custom service through the editService input. The custom service handles the create, update, and remove data operations and implements the EditService interface

The following example demonstrates how to implement a custom service.

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { Observable } from 'rxjs';

import { CreateFormGroupArgs } from '@progress/kendo-angular-treelist';

import { Employee } from './employee';
import { CustomEditService } from './custom-edit.service';

@Component({
  selector: 'my-app',
  template: `
    <kendo-treelist
        kendoTreeListExpandable
        [data]="rootData | async"
        idField="EmployeeId"
        [kendoTreeListInCellEditing]="createFormGroup"
        [editService]="editService"
        [fetchChildren]="fetchChildren"
        [hasChildren]="hasChildren"
        [height]="500"
        >
        <ng-template kendoTreeListToolbarTemplate>
            <button kendoTreeListAddCommand type="button">Add new</button>
        </ng-template>
        <kendo-treelist-column [expandable]="true" field="FirstName" title="First Name">
        </kendo-treelist-column>
        <kendo-treelist-column field="LastName" title="Last Name">
        </kendo-treelist-column>
        <kendo-treelist-column field="Position" title="Position">
        </kendo-treelist-column>
        <kendo-treelist-column field="Extension" title="Extension" editor="numeric" format="#">
            <ng-template kendoTreeListCellTemplate let-dataItem>
                <span class="k-treelist-ignore-click k-icon k-i-info"
                      title="Elements with the 'k-treelist-ignore-click' class do not trigger 'cellClick' events.">
                </span>
                {{ dataItem.Extension }}
            </ng-template>
        </kendo-treelist-column>
        <kendo-treelist-command-column width="140">
            <ng-template kendoTreeListCellTemplate
                         let-isNew="isNew"
                         let-cellContext="cellContext"
                         let-dataItem="dataItem">
                <button [kendoTreeListAddCommand]="cellContext"
                        icon="filter-add-expression" title="Add Child">
                </button>
                <button [kendoTreeListRemoveCommand]="cellContext"
                        icon="delete" title="Remove">
                </button>
                <button [kendoTreeListSaveCommand]="cellContext"
                        [disabled]="formGroup?.invalid"
                        icon="save" title="Add">
                </button>
                <button [kendoTreeListCancelCommand]="cellContext"
                        icon="cancel" title="{{ isNew ? 'Discard changes' : 'Cancel' }}">
                </button>
            </ng-template>
        </kendo-treelist-command-column>
    </kendo-treelist>
  `
})
export class AppComponent implements OnInit {
    public rootData: Observable<Employee[]>;
    public formGroup: FormGroup;

    constructor(public editService: CustomEditService) {
        this.createFormGroup = this.createFormGroup.bind(this);
    }

    public ngOnInit(): void {
        this.rootData = this.editService;
        this.editService.read();
    }

    public fetchChildren = (item: Employee): Observable<Employee[]> => {
        return this.editService.fetchChildren(item.EmployeeId);
    }

    public hasChildren = (item: Employee): boolean => {
        return item.hasChildren;
    }

    public createFormGroup({ isNew, dataItem }: CreateFormGroupArgs): FormGroup {
        const item = isNew ? {} : dataItem;

        this.formGroup = new FormGroup({
            'EmployeeId': new FormControl(isNew ? 0 : item.EmployeeId),
            'ReportsTo': new FormControl(item.ReportsTo),
            'FirstName': new FormControl(item.FirstName, Validators.required),
            'LastName': new FormControl(item.LastName, Validators.required),
            'Position': new FormControl(item.Position),
            'Extension': new FormControl(item.Extension, Validators.compose([Validators.required, Validators.min(0)]))
        });

        return this.formGroup;
    }
}
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable, BehaviorSubject } from 'rxjs';
import { tap, take } from 'rxjs/operators';

import { EditService } from '@progress/kendo-angular-treelist';

import { Employee } from './employee';

const CREATE_ACTION = 'Create';
const UPDATE_ACTION = 'Update';
const REMOVE_ACTION = 'Destroy';

function noop() { /* */ }

@Injectable()
export class CustomEditService extends BehaviorSubject<Employee[]> implements EditService {
    constructor(private http: HttpClient) {
        super(null);
    }

    public read(): void {
        this.fetch('')
            .pipe(take(1))
            .subscribe(data => this.next(data));
    }

    public fetchChildren(reportsTo: number = null): Observable<Employee[]> {
        return this.fetch('', null, reportsTo);
    }

    public create(item: Employee, parent?: Employee, _id?: number): void {
        if (parent) {
            parent.hasChildren = true;
            item.ReportsTo = parent.EmployeeId;
        }

        this.save(item, true)
            .pipe(take(1))
            .subscribe(noop);
    }

    public update(item: Employee): void {
        this.save(item, false)
            .pipe(take(1))
            .subscribe(noop);
    }

    public remove(item: any, parent?: Employee): void {
        this.fetch(REMOVE_ACTION, item).subscribe(() => {
            this.read();
        });
    }

    public assignValues(target: Employee, source: Employee): void {
        Object.assign(target, source);
    }

    private save(item: Employee, isNew: boolean): Observable<Employee[]> {
        const action = isNew ? CREATE_ACTION : UPDATE_ACTION;

        return this.fetch(action, item).pipe(tap(() => {
            if (isNew) {
                this.read();
            }
        }));
    }

    private fetch(action: string = '', data?: any, id?: any): Observable<Employee[]> {
        let params = new HttpParams();

        if (typeof id !== 'undefined') {
            params = params.set('id', id);
        }

        if (data) {
            params = params.set('models', JSON.stringify([data]));
        }

        return this.http.jsonp<Employee[]>(
            `https://demos.telerik.com/kendo-ui/service/EmployeeDirectory/${action}?${params.toString()}`,
            'callback'
        );
    }
}
export interface Employee {
    EmployeeId: number;
    ReportsTo: number;
    FirstName: string;
    LastName: string;
    Position: string;
    Extension: string;
    hasChildren?: boolean;
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http';

import { TreeListModule } from '@progress/kendo-angular-treelist';

import { AppComponent } from './app.component';
import { CustomEditService } from './custom-edit.service';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        ReactiveFormsModule,
        FormsModule,
        TreeListModule,
        HttpClientModule,
        HttpClientJsonpModule
    ],
    bootstrap: [ AppComponent ],
    providers: [ CustomEditService ]
})
export class AppModule {}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Confirmation Dialog on Row Removal

If you use any of the built-in editing directives, you can also display a confirmation dialog when the user is about to remove a row. To show the Remove dialog, set a function to the removeConfirmation input. The function is expected to return a Boolean value which will indicate if the record will be removed. If the function returns an observable or a promise, resolve it with a Boolean value.

The following example demonstrates how to display a Remove confirmation dialog.

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Subject } from 'rxjs';

import { CreateFormGroupArgs } from '@progress/kendo-angular-treelist';
import { Employee, employees } from './employees';

@Component({
  selector: 'my-app',
  template: `
    <kendo-treelist
        kendoTreeListExpandable
        [kendoTreeListFlatBinding]="data"
        idField="id" parentIdField="managerId"
        [kendoTreeListReactiveEditing]="createFormGroup"
          [removeConfirmation]="removeConfirmation"
        [height]="500"
        [pageSize]="10"
        [pageable]="true"
        [sortable]="true"
    >
        <ng-template kendoTreeListToolbarTemplate>
            <button kendoTreeListAddCommand type="button">Add new</button>
        </ng-template>
        <kendo-treelist-column [expandable]="true" field="name" title="Name">
        </kendo-treelist-column>
        <kendo-treelist-column field="title" title="Title">
        </kendo-treelist-column>
        <kendo-treelist-column field="phone" title="Phone">
        </kendo-treelist-column>
        <kendo-treelist-command-column width="140">
            <ng-template kendoTreeListCellTemplate let-isNew="isNew" let-cellContext="cellContext">
                <!-- "Add Child" command directive, will not be visible in edit mode -->
                <button [kendoTreeListAddCommand]="cellContext"
                        icon="filter-add-expression" title="Add Child">
                </button>

                <!-- "Edit" command directive, will not be visible in edit mode -->
                <button [kendoTreeListEditCommand]="cellContext"
                        icon="edit" title="Edit" [primary]="true">
                </button>

                <!-- "Remove" command directive, will not be visible in edit mode -->
                <button [kendoTreeListRemoveCommand]="cellContext"
                        icon="delete" title="Remove">
                </button>

                <!-- "Save" command directive, will be visible only in edit mode -->
                <button [kendoTreeListSaveCommand]="cellContext"
                        [disabled]="formGroup?.invalid"
                        icon="save" title="{{ isNew ? 'Add' : 'Update' }}">
                </button>

                <!-- "Cancel" command directive, will be visible only in edit mode -->
                <button [kendoTreeListCancelCommand]="cellContext"
                        icon="cancel" title="{{ isNew ? 'Discard changes' : 'Cancel' }}">
                </button>
            </ng-template>
        </kendo-treelist-command-column>
    </kendo-treelist>
    <kendo-dialog title="Please confirm" *ngIf="itemToRemove" (close)="confirmRemove(false)">
        <p style="margin: 30px; text-align: center;">Are you sure you want to delete employee {{ itemToRemove.name }}?</p>
        <kendo-dialog-actions>
            <button class='k-button' (click)="confirmRemove(false)">No</button>
            <button class='k-button k-primary' (click)="confirmRemove(true)" primary="true">Yes</button>
        </kendo-dialog-actions>
    </kendo-dialog>
  `
})
export class AppComponent {
    public data: Employee[] = employees;
    public formGroup: FormGroup;
    public removeConfirmationSubject: Subject<boolean> = new Subject<boolean>();
    public itemToRemove: any;

    constructor() {
        this.createFormGroup = this.createFormGroup.bind(this);
        this.removeConfirmation = this.removeConfirmation.bind(this);
    }

    public createFormGroup({ isNew, dataItem }: CreateFormGroupArgs): any {
        const item = isNew ? {} : dataItem;

        this.formGroup = new FormGroup({
            'id': new FormControl(item.id),
            'parentId': new FormControl(item.parentId),
            'name': new FormControl(item.name, Validators.required),
            'title': new FormControl(item.title),
            'phone': new FormControl(item.phone, Validators.required)
        });

        return this.formGroup;
    }

    public confirmRemove(shouldRemove: boolean): void {
        this.removeConfirmationSubject.next(shouldRemove);

        this.itemToRemove = null;
    }

    public removeConfirmation(dataItem): Subject<boolean> {
        this.itemToRemove = dataItem;

        return this.removeConfirmationSubject;
    }
}

export interface Employee {
    id: number;
    managerId?: number;
    name: string;
    title: string;
    phone: string;
    hireDate?: Date;
}

export const employees: Employee[] = [
    {
        id: 1,
        name: 'Daryl Sweeney',
        title: 'Chief Executive Officer',
        phone: '(555) 924-9726',
        managerId: null,
        hireDate: new Date('2019-01-15')
    },
    {
        id: 2,
        name: 'Guy Wooten',
        title: 'Chief Technical Officer',
        phone: '(438) 738-4935',
        managerId: 1,
        hireDate: new Date('2019-02-19')
    },
    {
        id: 32,
        name: 'Buffy Weber',
        title: 'VP, Engineering',
        phone: '(699) 838-6121',
        managerId: 2,
        hireDate: new Date('2019-04-13')
    },
    {
        id: 11,
        name: 'Hyacinth Hood',
        title: 'Team Lead',
        phone: '(889) 345-2438',
        managerId: 32,
        hireDate: new Date('2018-01-17')
    },
    {
        id: 60,
        name: 'Akeem Carr',
        title: 'Junior Software Developer',
        phone: '(738) 136-2814',
        managerId: 11,
        hireDate: new Date('2018-01-18')
    },
    {
        id: 78,
        name: 'Rinah Simon',
        title: 'Software Developer',
        phone: '(285) 912-5271',
        managerId: 11,
        hireDate: new Date('2018-03-17')
    },
    {
        id: 42,
        name: 'Gage Daniels',
        title: 'Software Architect',
        phone: '(107) 290-6260',
        managerId: 32,
        hireDate: new Date('2019-03-14')
    },
    {
        id: 43,
        name: 'Constance Vazquez',
        title: 'Director, Engineering',
        phone: '(800) 301-1978',
        managerId: 32,
        hireDate: new Date('2018-03-18')
    },
    {
        id: 46,
        name: 'Darrel Solis',
        title: 'Team Lead',
        phone: '(327) 977-0216',
        managerId: 43,
        hireDate: new Date('2019-04-15')
    },
    {
        id: 47,
        name: 'Brian Yang',
        title: 'Senior Software Developer',
        phone: '(565) 146-5435',
        managerId: 46,
        hireDate: new Date('2019-02-21')
    },
    {
        id: 50,
        name: 'Lillian Bradshaw',
        title: 'Software Developer',
        phone: '(323) 509-3479',
        managerId: 46,
        hireDate: new Date('2019-05-23')
    },
    {
        id: 51,
        name: 'Christian Palmer',
        title: 'Technical Lead',
        phone: '(490) 421-8718',
        managerId: 46,
        hireDate: new Date('2019-04-16')
    },
    {
        id: 55,
        name: 'Summer Mosley',
        title: 'QA Engineer',
        phone: '(784) 962-2301',
        managerId: 46,
        hireDate: new Date('2019-09-21')
    },
    {
        id: 56,
        name: 'Barry Ayers',
        title: 'Software Developer',
        phone: '(452) 373-9227',
        managerId: 46,
        hireDate: new Date('2018-04-16')
    },
    {
        id: 59,
        name: 'Keiko Espinoza',
        title: 'Junior QA Engineer',
        phone: '(226) 600-5305',
        managerId: 46,
        hireDate: new Date('2018-01-22')
    },
    {
        id: 61,
        name: 'Candace Pickett',
        title: 'Support Officer',
        phone: '(120) 117-7475',
        managerId: 46,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 63,
        name: 'Mia Caldwell',
        title: 'Team Lead',
        phone: '(848) 636-6470',
        managerId: 43,
        hireDate: new Date('2018-07-17')
    },
    {
        id: 65,
        name: 'Thomas Terry',
        title: 'Senior Enterprise Support Officer',
        phone: '(764) 831-4248',
        managerId: 63,
        hireDate: new Date('2018-07-14')
    },
    {
        id: 67,
        name: 'Ruth Downs',
        title: 'Senior Software Developer',
        phone: '(138) 991-1440',
        managerId: 63,
        hireDate: new Date('2018-08-14')
    },
    {
        id: 70,
        name: 'Yasir Wilder',
        title: 'Senior QA Engineer',
        phone: '(759) 701-8665',
        managerId: 63,
        hireDate: new Date('2019-08-17')
    },
    {
        id: 71,
        name: 'Flavia Short',
        title: 'Support Officer',
        phone: '(370) 133-9238',
        managerId: 63,
        hireDate: new Date('2018-06-15')
    },
    {
        id: 74,
        name: 'Aaron Roach',
        title: 'Junior Software Developer',
        phone: '(958) 717-9230',
        managerId: 63,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 75,
        name: 'Eric Russell',
        title: 'Software Developer',
        phone: '(516) 575-8505',
        managerId: 63,
        hireDate: new Date('2019-09-13')
    },
    {
        id: 76,
        name: 'Cheyenne Olson',
        title: 'Software Developer',
        phone: '(241) 645-0257',
        managerId: 63,
        hireDate: new Date('2018-09-18')
    },
    {
        id: 77,
        name: 'Shaine Avila',
        title: 'UI Designer',
        phone: '(844) 435-1360',
        managerId: 63,
        hireDate: new Date('2018-01-22')
    },
    {
        id: 81,
        name: 'Chantale Long',
        title: 'Senior QA Engineer',
        phone: '(252) 419-6891',
        managerId: 63,
        hireDate: new Date('2018-09-14')
    },
    {
        id: 83,
        name: 'Dane Cruz',
        title: 'Junior Software Developer',
        phone: '(946) 701-6165',
        managerId: 63,
        hireDate: new Date('2019-03-15')
    },
    {
        id: 84,
        name: 'Regan Patterson',
        title: 'Technical Writer',
        phone: '(265) 946-1765',
        managerId: 63,
        hireDate: new Date('2019-05-17')
    },
    {
        id: 85,
        name: 'Drew Mckay',
        title: 'Senior Software Developer',
        phone: '(327) 293-0162',
        managerId: 63,
        hireDate: new Date('2019-05-21')
    },
    {
        id: 88,
        name: 'Bevis Miller',
        title: 'Senior Software Developer',
        phone: '(525) 557-0169',
        managerId: 63,
        hireDate: new Date('2018-08-15')
    },
    {
        id: 89,
        name: 'Bruce Mccarty',
        title: 'Support Officer',
        phone: '(936) 777-8730',
        managerId: 63,
        hireDate: new Date('2019-10-21')
    },
    {
        id: 90,
        name: 'Ocean Blair',
        title: 'Team Lead',
        phone: '(343) 586-6614',
        managerId: 43,
        hireDate: new Date('2018-06-20')
    },
    {
        id: 91,
        name: 'Guinevere Osborn',
        title: 'Software Developer',
        phone: '(424) 741-0006',
        managerId: 90,
        hireDate: new Date('2019-06-17')
    },
    {
        id: 92,
        name: 'Olga Strong',
        title: 'Graphic Designer',
        phone: '(949) 417-1168',
        managerId: 90,
        hireDate: new Date('2018-06-15')
    },
    {
        id: 93,
        name: 'Robert Orr',
        title: 'Support Officer',
        phone: '(977) 341-3721',
        managerId: 90,
        hireDate: new Date('2018-06-22')
    },
    {
        id: 95,
        name: 'Odette Sears',
        title: 'Senior Software Developer',
        phone: '(264) 818-6576',
        managerId: 90,
        hireDate: new Date('2019-05-20')
    },
    {
        id: 45,
        name: 'Zelda Medina',
        title: 'QA Architect',
        phone: '(563) 359-6023',
        managerId: 32,
        hireDate: new Date('2018-08-16')
    },
    {
        id: 3,
        name: 'Priscilla Frank',
        title: 'Chief Product Officer',
        phone: '(217) 280-5300',
        managerId: 1,
        hireDate: new Date('2019-04-22')
    },
    {
        id: 4,
        name: 'Ursula Holmes',
        title: 'EVP, Product Strategy',
        phone: '(370) 983-8796',
        managerId: 3,
        hireDate: new Date('2018-01-15')
    },
    {
        id: 24,
        name: 'Melvin Carrillo',
        title: 'Director, Developer Relations',
        phone: '(344) 496-9555',
        managerId: 3,
        hireDate: new Date('2018-01-17')
    },
    {
        id: 29,
        name: 'Martha Chavez',
        title: 'Developer Advocate',
        phone: '(140) 772-7509',
        managerId: 24,
        hireDate: new Date('2018-05-14')
    },
    {
        id: 30,
        name: 'Oren Fox',
        title: 'Developer Advocate',
        phone: '(714) 284-2408',
        managerId: 24,
        hireDate: new Date('2018-07-19')
    },
    {
        id: 41,
        name: 'Amos Barr',
        title: 'Developer Advocate',
        phone: '(996) 587-8405',
        managerId: 24,
        hireDate: new Date('2019-01-16')
    }
  ];
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ReactiveFormsModule } from '@angular/forms';

import { TreeListModule } from '@progress/kendo-angular-treelist';
import { DialogModule } from '@progress/kendo-angular-dialog';

import { AppComponent } from './app.component';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        ReactiveFormsModule,
        TreeListModule,
        DialogModule
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

In this article