Validation in Angular TreeGrid component

24 May 202424 minutes to read

Validation is a crucial aspect of data integrity in any application. The Angular TreeGrid component in Syncfusion provides built-in support for easy and effective data validation. This feature ensures that the data entered or modified adheres to predefined rules, preventing errors and guaranteeing the accuracy of the displayed information.

Column validation

Column validation allows you to validate the edited or added row data before saving it. This feature is particularly useful when you need to enforce specific rules or constraints on individual columns to ensure data integrity. By applying validation rules to columns, you can display error messages for invalid fields and prevent the saving of erroneous data. This feature leverages the Form Validator component to perform the validation.

You can define validation rules using the columns.validationRules property to specify the criteria for validating column values. The predefined rule sets can be referred here.

The following code example demonstrates how to define a validation rule for tree grid column:

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 { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';

@Component({
    imports: [TreeGridModule  ],

    providers: [PageService, 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 [validationRules]='taskidRule' ></e-column>
                        <e-column field='taskName' headerText='Task Name' editType='stringedit' textAlign='Left' width=180  [validationRules]='stringRule' ></e-column>
                        <e-column field='approved' headerText='Approved' editType='booleanedit' type='boolean' textAlign='Right' [displayAsCheckBox]='true' width=110></e-column>
                        <e-column field='priority' headerText='Priority' editType='dropdownedit' textAlign='Right' width=110 [validationRules]='stringRule' ></e-column>
                        <e-column field='startDate' headerText='Start Date' textAlign='Right' [format]='formatOptions' editType='datetimepickeredit' [validationRules]='dateRule' width=180 ></e-column>
                        <e-column field='progress' headerText='Progress' textAlign='Right' editType='numericedit' width=120 [edit]='editing' [validationRules]='progressRule' ></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];
    public editing?: Object;
    public formatOptions?: Object;
    public editOptions?: Object;
    public stringRule?: Object;
    public taskidRule?: Object;
    public progressRule?: Object;
    public dateRule?: Object;
    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' };
        this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel'];
        this.editing = { params: { format: 'n' } };
        this.formatOptions = { format: 'M/d/y hh:mm a', type: 'dateTime' };
        this.progressRule = { number: true, min: 0 };
        this.taskidRule = { required: true, number: true };
        this.dateRule = { date: true };
        this.stringRule = { required: true };
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Custom validation

The custom validation feature is used to define and enforce your own validation rules for specific columns in the tree grid. By leveraging the Form Validator custom rules, you can implement your desired validation logic and display error messages for invalid fields.

In the below demo, custom validation applied for Priority column.

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 { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';

@Component({
    imports: [TreeGridModule  ],

    providers: [PageService, 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 [validationRules]='taskidRule' ></e-column>
                        <e-column field='taskName' headerText='Task Name' editType='stringedit' textAlign='Left' width=180  [validationRules]='stringRule' ></e-column>
                        <e-column field='priority' headerText='Priority' editType='stringedit' textAlign='Right' width=110 [validationRules]='stringRule' ></e-column>
                        <e-column field='progress' headerText='Progress' textAlign='Right' editType='numericedit' width=120 [edit]='editing' [validationRules]='progressRule' ></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];
    public editing?: Object;
    public formatOptions?: Object;
    public editOptions?: Object;
    public stringRule?: Object;
    public taskidRule?: Object;
    public progressRule?: Object;
    
    public customFn: (args: { [key: string]: string }) => boolean = (args: { [key: string]: string }) => {
        return args['value'].length >= 8;
    };
    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' };
        this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel'];
        this.editing = { params: { format: 'n' } };
        this.formatOptions = { format: 'M/d/y hh:mm a', type: 'dateTime' };
        this.progressRule = { number: true, min: 0 };
        this.taskidRule = { required: true, number: true };
        this.stringRule = { required: true, minLength: [this.customFn, 'Value should be within 8 letters'] };
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Custom validation based on dropdown change

The custom validation feature in the Tree Grid allows you to apply validation rules and messages to a column based on the value of another column in edit mode. This feature is particularly useful when you need to enforce specific validation criteria that depend on the selection made in a dropdown column.

In the following sample, dropdownlist edit type is used for the Role and Salary columns. Here, you can apply the custom validation in the Salary column based on the value selected in the Role column.

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridComponent, TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import { Component, OnInit } from '@angular/core';
import { employeeDetails } from './datasource';
import { Query } from '@syncfusion/ej2-data';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';
import { CheckBoxModule, CheckBoxComponent } from '@syncfusion/ej2-angular-buttons'
import { EditEventArgs, IEditCell, getObject } from '@syncfusion/ej2-angular-grids';
import { ChangeEventArgs } from '@syncfusion/ej2-angular-dropdowns';

let jobRole: { [key: string]: Object }[] = [
  { role: 'TeamLead' },
  { role: 'Manager' },
  { role: 'Engineer' },
  { role: 'Sales' },
  { role: 'Support' },
];

let salaryDetails: { [key: string]: Object }[] = [
  { salary: 6000 },
  { salary: 17000 },
  { salary: 18000 },
  { salary: 26000 },
  { salary: 25000 },
  { salary: 40000 },
  { salary: 35000 },
  { salary: 55000 },
  { salary: 65000 },

];

@Component({
    imports: [TreeGridModule, CheckBoxModule ],

    providers: [PageService, EditService, ToolbarService],
    standalone: true,
    selector: 'app-container',
    template: `<ejs-treegrid #treegrid [dataSource]='data'  [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' childMapping='subtasks' (created)="load()" (actionBegin)="actionBegin($event)"  >
                    <e-columns>
                      <e-column field='EmployeeID' headerText='Employee ID' textAlign='Right' isPrimaryKey='true' width=120></e-column>
                      <e-column field='Role' headerText='Role' width=160  editType= 'dropdownedit' [edit]='roleParams'></e-column>
                      <e-column field='Salary' headerText='Salary' textAlign= 'Right' editType= 'dropdownedit' width=160 [edit]='salaryParams'></e-column>
                      <e-column field='Address' headerText='Address' [validationRules]='addressRules' width=160></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];
    public roleParams?: IEditCell;
    public salaryParams?: IEditCell;
    public addressRules?: object;
    public rules?: object;
    @ViewChild('treegrid') treegrid?: TreeGridComponent;
    

    ngOnInit(): void {
        this.data = employeeDetails;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' };
        this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel'];
        this.addressRules = { required: true };
        this.roleParams = {
          params: {
              query: new Query(),
              dataSource: jobRole,
              fields: { value: 'role', text: 'role' },
              allowFiltering: true,
              change: this.valChange.bind(this)

          }
      };
      this.salaryParams = {
          params: {
              query: new Query(),
              dataSource: salaryDetails,
              fields: { value: 'salary', text: 'salary' },
              allowFiltering: true,

          }
      };
    }
    public valChange(args: ChangeEventArgs) {

      window.role = (args.value?.toString() as string); // Explicitly cast args.value to string
      const formObj = (this.treegrid as TreeGridComponent).grid.editModule.formObj.element['ej2_instances'][0];

      switch ( window.role) {

          case 'Sales':
              formObj.rules['Salary']['required'][1] = 'Please enter valid Sales Salary >=5000 and< 15000';

              break;

          case 'Support':
              formObj.rules['Salary']['required'][1] = 'Please enter valid Support Salary >=15000 and < 19000';

              break;

          case 'Engineer':
              formObj.rules['Salary']['required'][1] = 'Please enter valid Engineer Salary between >=25000 and < 30000';

              break;

          case 'TeamLead':
              formObj.rules['Salary']['required'][1] = 'Please enter valid TeamLead Salary >= 30000 and < 50000';

              break;

          case 'Manager':
              formObj.rules['Salary']['required'][1] = 'Please enter valid Manager Salary >=50000 and < 70000';

              break;
      }
  }

  public customFn(args: { value: number }): boolean {
      const formObj = (this.treegrid as TreeGridComponent).grid.editModule.formObj.element['ej2_instances'][0];
      switch (window.role ) {

          case 'Sales':
              if ((args.value >= 5000) && (args.value < 15000))
                  return true;
              else
                  formObj.rules['Salary']['required'][1] = 'Please enter valid Sales Salary >=5000 and< 15000';

              break;

          case 'Support':
              if ((args.value >= 15000 && args.value < 19000))
                  return true;
              else
                  formObj.rules['Salary']['required'][1] = 'Please enter valid Support Salary >=15000 and < 19000';

              break;

          case 'Engineer':
              if ((args.value >= 25000 && args.value < 30000))
                  return true;
              else
                  formObj.rules['Salary']['required'][1] = 'Please enter valid Engineer Salary between >=25000 and < 30000';

              break;

          case 'TeamLead':
              if ((args.value >= 30000) && (args.value < 50000))
                  return true;
              else
                  formObj.rules['Salary']['required'][1] = 'Please enter valid TeamLead Salary >= 30000 and < 50000';

              break;

          case 'Manager':
              if ((args.value >= 50000) && (args.value < 70000))
                  return true;
              else
                  formObj.rules['Salary']['required'][1] = 'Please enter valid Manager Salary >=50000 and < 70000';

              break;

      }
      return false;
  }
  load(): void {
      let column = (this.treegrid as TreeGridComponent).grid.getColumnByField('Salary');
      column.validationRules = {
          required: [this.customFn.bind(this), 'Please enter valid salary'],
      };
  }
  actionBegin(args: EditEventArgs) {
      
      window.role = args.rowData as { Role: string }['Role'];
  }

}

declare global {
  interface Window {
      role: string;
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Custom validation for numeric column

Custom validation for a numeric column in the Tree Grid is useful when you want to enforce specific validation rules on numeric values in a column. This allows you to define your own validation logic and display custom error messages when you enters invalid data.

In the following example, custom validation functions are defined for the progress column, namely customFn_max and customFn_min. These functions are designed to check the entered numeric value against your validation criteria.

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 { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';

@Component({
    imports: [TreeGridModule  ],

    providers: [PageService, 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 [validationRules]='taskidRule' ></e-column>
                        <e-column field='taskName' headerText='Task Name' editType='stringedit' textAlign='Left' width=180  [validationRules]='stringRule' ></e-column>
                        <e-column field='priority' headerText='Priority' editType='stringedit' textAlign='Right' width=110 [validationRules]='stringRule' ></e-column>
                        <e-column field='progress' headerText='Progress' textAlign='Right' editType='numericedit' width=120 [edit]='editing' [validationRules]='progressRule' ></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];
    public editing?: Object;
    public formatOptions?: Object;
    public editOptions?: Object;
    public stringRule?: Object;
    public taskidRule?: Object;
    public progressRule?: Object;
    
    public customFn_max: (args: { [key: string]: number }) => boolean = (args: { [key: string]: number }) => {
        return (args['value'] <= 1000);
    }

    public customFn_min: (args: { [key: string]:  number}) => boolean = (args: { [key: string]:  number }) => {
      return (args['value'] >= 1);
    }
    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' };
        this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel'];
        this.editing = { params: { format: 'n' } };
        this.formatOptions = { format: 'M/d/y hh:mm a', type: 'dateTime' };
        this.progressRule = { 
                number: true,
                maxLength: [this.customFn_max, 'Please enter a value less than 1000'],
                minLength: [this.customFn_min, 'Please enter a value greater than 1']  };
        this.taskidRule = { required: true, number: true };
        this.stringRule = { required: true };
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Dynamically add or remove validation rules from the form

You can dynamically add or remove validation rules from input elements within a form. This feature is particularly useful when you need to adjust the validation rules based on different scenarios or dynamically changing data.

To add validation rules dynamically to an input element, you can use the addRules method. This method enables you to add validation rules to the corresponding input element based on the name attribute.

The following example to demonstrates how to dynamically add or remove a required validation rule for an input field based on a CheckBox selection:

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridComponent, TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';
import { CheckBoxModule, CheckBoxComponent } from '@syncfusion/ej2-angular-buttons'
import { EditEventArgs } from '@syncfusion/ej2-angular-grids';
@Component({
    imports: [TreeGridModule, CheckBoxModule ],

    providers: [PageService, EditService, ToolbarService],
    standalone: true,
    selector: 'app-container',
    template: `<div style='padding:2px 2px 20px 3px'>
                    <ejs-checkbox #checkbox label="Enable/Disable validation rule for Task name coulumn" [checked]="true"></ejs-checkbox>
                </div>
                <ejs-treegrid #treegrid [dataSource]='data'  [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' childMapping='subtasks' (actionComplete)="actionComplete($event)" >
                    <e-columns>
                        <e-column field='taskID' headerText='Task ID' isPrimaryKey='true' textAlign='Right' width=90 [validationRules]='taskidRule' ></e-column>
                        <e-column field='taskName' headerText='Task Name' editType='stringedit' textAlign='Left' width=180  ></e-column>
                        <e-column field='priority' headerText='Priority' editType='stringedit' textAlign='Right' width=110 ></e-column>
                        <e-column field='progress' headerText='Progress' textAlign='Right' editType='numericedit' width=120 [edit]='editing' [validationRules]='progressRule' ></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];
    public editing?: Object;
    public formatOptions?: Object;
    public editOptions?: Object;
    public stringRule?: Object;
    public taskidRule?: Object;
    public progressRule?: Object;
    
    @ViewChild('treegrid') treegrid?: TreeGridComponent;
    @ViewChild('checkbox') checkbox?: CheckBoxComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Row' };
        this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel'];
        this.editing = { params: { format: 'n' } };
        this.formatOptions = { format: 'M/d/y hh:mm a', type: 'dateTime' };
        this.progressRule = { number: true, };
        this.taskidRule = { required: true, number: true };
        
    }
    actionComplete(args: EditEventArgs) {
        const formObj = (this.treegrid as TreeGridComponent).grid.editModule.formObj;
        const stringRule = {
            required: true,
            minLength: [5, 'Task name should have a minimum length of 5 characters'],
        };

        if (args.requestType === 'beginEdit' || args.requestType === 'add') {
            if ((this.checkbox as CheckBoxComponent).checked) {
                // Add the custom validation rule
                formObj.addRules('taskName', stringRule);
            }
        }
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

To remove an existing validation rule from an input element, you can use the removeRules method.

Change the position of validation error message

By default, the validation error message in the Tree Grid is displayed below the input field. However, you have an option to customize its position and display it in a different location. This feature is particularly useful when you want to align the error message according to your application’s design and layout.

To change the position of the validation error message in tree grid, you can utilize the customPlacement event. This event allows you to define a custom logic to position the error message at the desired location.

Here’s an example that demonstrates how to change the position of the validation error message to the top of the input field:

import { NgModule,ViewChild } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { TreeGridComponent, TreeGridModule } from '@syncfusion/ej2-angular-treegrid'
import { PageService, SortService, FilterService,EditService,ToolbarService } from '@syncfusion/ej2-angular-treegrid'
import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-treegrid';
import { CheckBoxModule, CheckBoxComponent } from '@syncfusion/ej2-angular-buttons'
import { EditEventArgs, getObject } from '@syncfusion/ej2-angular-grids';
@Component({
    imports: [TreeGridModule, CheckBoxModule ],

    providers: [PageService, 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)" >
                    <e-columns>
                        <e-column field='taskID' headerText='Task ID' isPrimaryKey='true' textAlign='Right' width=90 [validationRules]='taskidRule' ></e-column>
                        <e-column field='taskName' headerText='Task Name' editType='stringedit' textAlign='Left' [validationRules]='stringRule' width=180  ></e-column>
                        <e-column field='priority' headerText='Priority' editType='stringedit' textAlign='Right' [validationRules]='stringRule' width=110 ></e-column>
                        <e-column field='progress' headerText='Progress' textAlign='Right' editType='numericedit' width=120 [edit]='editing' [validationRules]='progressRule' ></e-column>
                    </e-columns>
                </ejs-treegrid>`
})
export class AppComponent implements OnInit {

    public data?: Object[];
    public editSettings?: EditSettingsModel;
    public toolbarOptions?: ToolbarItems[];
    public editing?: Object;
    public formatOptions?: Object;
    public editOptions?: Object;
    public stringRule?: Object;
    public taskidRule?: Object;
    public progressRule?: Object;
    
    @ViewChild('treegrid') treegrid?: TreeGridComponent;
    @ViewChild('checkbox') checkbox?: CheckBoxComponent;

    ngOnInit(): void {
        this.data = sampleData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' };
        this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel'];
        this.editing = { params: { format: 'n' } };
        this.formatOptions = { format: 'M/d/y hh:mm a', type: 'dateTime' };
        this.progressRule = { number: true, min:0 };
        this.taskidRule = { required: true, number: true };
        this.stringRule = { required: true };
    }
    actionComplete(args: EditEventArgs) {
        var valueError = getObject('valErrorPlacement', (this.treegrid as TreeGridComponent).grid.editModule).bind((this.treegrid as TreeGridComponent).grid.editModule);  
        (this.treegrid as TreeGridComponent).grid.editModule.formObj.customPlacement = (input:any, error:any) => { 
          valueError(input, error);
          
          var element = document.getElementById(input.name + '_Error');
          var tooltipWidth = (element as HTMLElement).offsetWidth;
          var  inputElement = null;
          if (document.querySelector('#' + (this.treegrid as TreeGridComponent).grid.element.id + input.name)) {
            inputElement = document.querySelector('#' +(this.treegrid as TreeGridComponent).grid.element.id + input.name);
          } else if (document.querySelector('#' + input.name)) {
            inputElement = document.querySelector('#' + input.name);
          }
          var inputPosition = ( inputElement as Element).getBoundingClientRect();
          var leftPosition =  (inputPosition.left - tooltipWidth - 16).toString() + 'px'; //for right side
          var topPosition = (inputPosition.top).toString() + 'px';
          (element as HTMLElement).style.left = leftPosition; 
          (element as HTMLElement).style.top =  topPosition;
          (element as HTMLElement).style.position = 'fixed';
        } 
      } 
    
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));