Frozen in Angular Treegrid component

27 Sep 202318 minutes to read

Frozen rows and columns

Frozen rows and columns provides an option to make rows and columns always visible in the top and left side of the tree grid while scrolling.

In this demo, the frozenColumns is set as ‘2’ and the frozenRows is set as ‘3’. Hence, the left two columns and top three rows are frozen.

import { Component, OnInit, ViewEncapsulation, ViewChild } from '@angular/core';
import { FreezeService, TreeGridComponent } from '@syncfusion/ej2-angular-treegrid';
import { NumericTextBoxComponent } from '@syncfusion/ej2-angular-inputs';
import { sampleData } from './datasource';

@Component({
    selector: 'app-container',
    template: ` <div style="display: flex">
                   <label style="padding: 10px 10px 26px 0">Change the frozen columns:</label>
                
                    <ejs-numerictextbox id="frozenColumns" #frozenColumns min="0" max="5" [validateDecimalOnType]="true" decimals="0" format="n"
                     value="2" width="100px" ></ejs-numerictextbox>
                  <div> 
                     <button style="margin-left:5px" ejs-button (click)="frozenColumnFn()">Update</button>
                  </div>
                </div>

                <ejs-treegrid #treegrid [dataSource]='data' childMapping='subtasks' [treeColumnIndex]='1' height='310' [frozenColumns]='2' [frozenRows]='3' [allowSelection]='false'>
                  <e-columns>
                    <e-column field='taskID' headerText='Task ID' width='90' textAlign='Right'></e-column>
                    <e-column field='taskName' headerText='Task Name' width='230'></e-column>
                    <e-column field='startDate' headerText='Start Date' width='120' format='yMd' textAlign='Right'></e-column>
                    <e-column field='endDate' headerText='End Date' width='120' format='yMd' textAlign='Right'></e-column>
                    <e-column field='duration' headerText='Duration' width='110' textAlign='Right'></e-column>
                    <e-column field='progress' headerText='Progress' width='110' textAlign='Right'></e-column>
                    <e-column field='priority' headerText='Priority' width='110'></e-column>
                    <e-column field='approved' headerText='Approved' textAlign='Left' width='110'></e-column>
                  </e-columns>
                </ejs-treegrid>`,
providers: [FreezeService]
})
export class AppComponent implements OnInit {

    public data?: Object[];
    
    @ViewChild('treegrid')
    public treegrid?: TreeGridComponent;

    @ViewChild('frozenColumns')
    public frozenColumns?: NumericTextBoxComponent;

    ngOnInit(): void {
        this.data = sampleData;
    }
    frozenColumnFn() {
        (this.treegrid as TreeGridComponent).frozenColumns = (this.frozenColumns as NumericTextBoxComponent).value;
      }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';
import { NumericTextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule,NumericTextBoxModule,ButtonModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Freeze particular columns

You can use isFrozen property to freeze selected columns in tree grid.

In this demo, the columns with field name taskName and startDate is frozen using
the isFrozen property.

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

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data' childMapping='subtasks' height='310' [allowSelection]='false'>
        <e-columns>
            <e-column field='taskID' headerText='Task ID' width='90' textAlign='Right'></e-column>
            <e-column field='taskName' headerText='Task Name' width='200' isFrozen= 'true'></e-column>
            <e-column field='startDate' headerText='Start Date' isFrozen= 'true' width='150' format='yMd' textAlign='Right'></e-column>
            <e-column field='endDate' headerText='End Date' width='150' format='yMd' textAlign='Right'></e-column>
            <e-column field='duration' headerText='Duration' width='110' textAlign='Right'></e-column>
            <e-column field='progress' headerText='Progress' width='110' textAlign='Right'></e-column>
            <e-column field='priority' headerText='Priority' width='110'></e-column>
            <e-column field='approved' headerText='Approved' textAlign='Left' width='110'></e-column>
        </e-columns>
    </ejs-treegrid>`,
providers: [FreezeService]
})
export class AppComponent implements OnInit {

    public data?: Object[];

    ngOnInit(): void {
        this.data = sampleData;
    }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule, ToolbarService, SelectionService, EditService } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ToolbarService, 
        SelectionService,
        EditService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Freeze direction

You can freeze the tree grid columns on the left or right side by using the column.freeze property and the remaining columns will be movable. The grid will automatically move the columns to the left or right position based on the column.freeze value.

Types of the column.freeze directions:

  • Left: Allows you to freeze the columns at the left.
  • Right: Allows you to freeze the columns at the right.

In this demo, the Task Name column is frozen at the left and the Priority column is frozen at the right side of the content table.

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

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data' childMapping='subtasks' height='310' [treeColumnIndex]='1' [allowSelection]='false'>
        <e-columns>
            <e-column field='taskID' headerText='Task ID' width='90' textAlign='Right'></e-column>
            <e-column field='taskName' headerText='Task Name' width='200' freeze='Left'></e-column>
            <e-column field='startDate' headerText='Start Date' width='150' format='yMd' textAlign='Right'></e-column>
            <e-column field='endDate' headerText='End Date' width='150' format='yMd' textAlign='Right'></e-column>
            <e-column field='duration' headerText='Duration' width='110' textAlign='Right'></e-column>
            <e-column field='progress' headerText='Progress' width='110' textAlign='Right'></e-column>
            <e-column field='priority' headerText='Priority' width='110' freeze='Right'></e-column>
            <e-column field='approved' headerText='Approved' textAlign='Left' width='110'></e-column>
        </e-columns>
    </ejs-treegrid>`,
providers: [FreezeService]
})
export class AppComponent implements OnInit {

    public data?: Object[];

    ngOnInit(): void {
        this.data = sampleData;
    }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule, ToolbarService, SelectionService, EditService } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ToolbarService, 
        SelectionService,
        EditService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

  • Freeze Direction is not compatible with the isFrozen and frozenColumns properties.
  • You can get the frozen right rows by using the getFrozenRightRows method in tree grid.
  • To get the movable rows, you can use the getMovableRows method in tree grid.
  • You can get the movable row by index using the getMovableRowByIndex method in tree grid.
  • To get the movable cell from index using the getMovableCellFromIndex method in tree grid. In this method, you need to pass the row index and column index of movable column as parameter.
  • To get the frozen right column header element by index, you can use the getFrozenRightColumnHeaderByIndex method in tree grid. In this method, you need to pass the frozen right column header index as parameter.
  • To get the frozen left column header element by index, you can use the getFrozenLeftColumnHeaderByIndex method in tree grid. In this method, you need to pass the frozen left column header index as parameter.
  • To get the frozen right cell element from index, you can use the getFrozenRightCellFromIndex method in tree grid. In this method, you need to pass the row index and cell index of the frozen right column as parameter.
    To get the movable column header element by index, you can use the getMovableColumnHeaderByIndex method in tree grid. In this method, you need to pass the movable column index as parameter.
  • To get the frozen right row element by index, you can use the getFrozenRightRowByIndex method in tree grid. In this method, you need to pass the right frozen row index as parameter.

Limitations of frozen tree grid

The following features are not supported in frozen rows and columns:

  • Row Template
  • Detail Template
  • Cell Editing

Limitations of freeze direction

This feature has the following limitations, along with the above mentioned frozen tree grid limitations.

  • Infinite scroll cache mode.
  • Freeze direction in the stacked header is not compatible with column reordering.

Add validation rule for frozen tree grid

In a frozen column-enabled tree grid, the content will be separated into frozen and movable parts. The following code is used to dynamically add validation to input fields in the movable part. In the actionComplete event args, find the movableform instance as an argument. Here, add the validation rules dynamically.

  actionComplete: (args: DialogEditEventArgs) => {
        if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
            // Add Validation Rules
            args.movableForm.ej2_instances[0].addRules('duration', { max: 200 }); // Here, 'duration' is the column name.
        }
    }

Validation rules for the ‘duration’ and ‘taskID’ columns can be added in the following sample.

import { TreeGrid, Selection, Edit, Toolbar, EditSettingsModel, FreezeService } from '@syncfusion/ej2-angular-treegrid';
import { Component, OnInit } from '@angular/core';
import { sampleData } from './datasource';

@Component({
    selector: 'app-container',
    template: `<ejs-treegrid [dataSource]='data' childMapping='subtasks' height='310' [treeColumnIndex]='0' [toolbar]='toolbar' [editSettings]='editSettings' allowSelection='false' enableHover='false' (actionComplete)="actionComplete($event)">
        <e-columns>
            <e-column field='taskID' headerText='Task ID' [validationRules]='validationrules' width='90' textAlign='Right'></e-column>
            <e-column field='taskName' headerText='Task Name' width='200' freeze='Left'></e-column>
            <e-column field='duration' headerText='Duration' [validationRules]='validationrules' width='110' textAlign='Right'></e-column>
            <e-column field='startDate' headerText='Start Date' width='150' format='yMd' textAlign='Right'></e-column>
            <e-column field='endDate' headerText='End Date' width='150' format='yMd' textAlign='Right'></e-column>
            <e-column field='progress' headerText='Progress' width='110' textAlign='Right'></e-column>
            <e-column field='priority' headerText='Priority' width='110' freeze='Right'></e-column>
            <e-column field='approved' headerText='Approved' textAlign='Left' width='110'></e-column>
        </e-columns>
    </ejs-treegrid>`,
    providers: [FreezeService]
})
export class AppComponent implements OnInit {

    public data?: object[];
    public toolbar?: string[];
    public editSettings?: EditSettingsModel;
    public validationrules?: Object;

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

    actionComplete(args: any) {
        if (args.requestType === 'beginEdit' || args.requestType === 'add') {
            // Add Validation Rules
            args.movableForm.ej2_instances[0].addRules('duration', { max: 200 });
            args.movableForm.ej2_instances[0].addRules('taskID', { max: 20 });
        }
    }
}
import { NgModule,ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TreeGridModule, ToolbarService, SelectionService, EditService } from '@syncfusion/ej2-angular-treegrid';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        TreeGridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ToolbarService, 
        SelectionService,
        EditService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

import 'zone.js';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

  • This is applicable when a frozen column is enabled and the edit mode is set as “Row” in the tree grid.
  • You can refer to Syncfusion Angular Tree Grid feature tour page for its groundbreaking feature representations. Also, explore Syncfusion Angular Tree Grid example to know how to present and manipulate data.