Custom toolbar in Angular Grid component

23 Sep 202324 minutes to read

Custom toolbar in Syncfusion Angular Grid allows you to create a distinctive toolbar layout, style, and functionality that aligns with the specific needs of your application, providing a personalized experience within the Grid component.

This can be achieved by utilizing the toolbarTemplate property, which offers extensive customization options for the toolbar. You can define a custom template for the toolbar and handle the actions of the toolbar items in the clicked event.

The following example demonstrates, how to render the custom toolbar using toolbarTemplate

import { Component, OnInit, ViewChild } from '@angular/core';
import { ClickEventArgs } from '@syncfusion/ej2-navigations';
import { data } from './datasource';
import { GridComponent } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' height='200px' [allowGrouping]='true' [groupSettings]='groupOptions'>
                    <ng-template #toolbarTemplate let-data>
                        <ejs-toolbar (clicked)='clickHandler($event)'>
                            <e-items>
                                <e-item id="collapse" text="Collapse All" prefixIcon="e-chevron-up icon"></e-item>
                                <e-item id="expand" text="Expand All" prefixIcon="e-chevron-down icon"></e-item>
                            </e-items>
                        </ejs-toolbar>
                    </ng-template>
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' isPrimaryKey='true' textAlign='Right' width=90></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=100></e-column>
                        <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                        <e-column field='ShipName' headerText='Ship Name' width=120></e-column>
                    </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public groupOptions?: object;

    @ViewChild('grid')
    public grid?: GridComponent;

    ngOnInit(): void {
        this.data = data;
        this.groupOptions = { columns: ['CustomerID'] };
    }

    clickHandler(args: ClickEventArgs): void {
        const target = (args.originalEvent.target as HTMLElement).closest('button'); // find clicked button
        if ((target as HTMLElement).id === 'collapse') {
            // collapse all expanded grouped row
            (this.grid as GridComponent).groupModule.collapseAll();
        }
        if ((target as HTMLElement).id === 'expand') {
            // expand all collapsed grouped row
            (this.grid as GridComponent).groupModule.expandAll();
        }
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ToolbarService, GroupService } from '@syncfusion/ej2-angular-grids';
import { ToolbarModule } from '@syncfusion/ej2-angular-navigations';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ToolbarModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ToolbarService, GroupService]
})
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);

Render image with text in custom toolbar

Render an image with text in custom toolbar in Syncfusion Angular Grid allows easily render an image along with text in the toolbar of the Grid. This feature enhances the visual presentation of the Grid, providing additional context and improving the overall experience.

To render an image with text in custom toolbar, you can utilize the ng-template along with the DomSanitizer service and the bypassSecurityTrustResourceUrl method in your code. This ensures the secure presentation of an image provided as a base64-encoded string.

  1. DomSanitizer: The DomSanitizer service furnishes methods that enable you to mark a value as trusted for specific security contexts. By doing so, you inform Angular that you have already verified the value’s safety, permitting it to be rendered. This plays a pivotal role in preventing XSS attacks.

  2. bypassSecurityTrustResourceUrl: This specific method of DomSanitizer is used when you want to assure Angular that a URL is secure and suitable for use as a resource source. In your code example, by applying this method to denote a base64-encoded image as secure, you explicitly signify that the supplied image data is trustworthy and does not pose a security risk.

The following example demonstrates how to render an image in the toolbar of the grid using ng-template.

import { Component, OnInit, ViewChild } from '@angular/core';
import { data } from './datasource';
import { deleteImage } from './delete';
import { addImage } from './add';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { GridComponent, EditSettingsModel} from '@syncfusion/ej2-angular-grids';
import { ButtonComponent } from '@syncfusion/ej2-angular-buttons';
import { ClickEventArgs } from '@syncfusion/ej2-buttons';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' height='200px' [editSettings]='editSettings'>
                <ng-template #toolbarTemplate let-data>
                    <div class="image">
                        <img [src]="addImageSource" id="addImage" />
                        <button
                        #addButton
                        class="button"
                        id="addButton"
                        ejs-button
                        cssClass="e-outline"
                        (click)="editAction($event)"
                        >
                        Add
                        </button>
                        <img [src]="deleteImageSource" id="deleteImage" />
                        <button
                        #deleteButton
                        class="button"
                        ejs-button
                        id="deleteButton"
                        cssClass="e-outline"
                        (click)="editAction($event)"
                        >
                        Delete
                        </button>
                    </div>
                </ng-template>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' isPrimaryKey='true' textAlign='Right' width=90></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=100></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=120></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    @ViewChild('grid')
    public grid: GridComponent;
    public editSettings?:EditSettingsModel ;
    public deleteImageSource?: SafeResourceUrl | undefined;
    public addImageSource?: SafeResourceUrl | undefined;
    constructor(private sanitizer: DomSanitizer) { }

    ngOnInit(): void {
        this.data = data;
        this.editSettings={ allowEditing: true, allowAdding: true, allowDeleting: true }
        this.deleteImageSource = this.sanitizer.bypassSecurityTrustResourceUrl(
            `data:image/png;base64, ${deleteImage}`
        );
        this.addImageSource = this.sanitizer.bypassSecurityTrustResourceUrl(
            `data:image/png;base64, ${addImage}`
        );
    }

    editAction(args: MouseEvent) {
        if ((args.currentTarget as HTMLElement).id === 'addButton') {
            this.grid.addRecord();
        } else {
            var selectedRecord = this.grid.getSelectedRecords()[0];
            this.grid.deleteRecord(selectedRecord as string);
        }
    }

}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ToolbarService, EditService } from '@syncfusion/ej2-angular-grids';
import { ToolbarModule } from '@syncfusion/ej2-angular-navigations';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ToolbarModule,
        ButtonModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ToolbarService, 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);

You can further customize the styles and layout of the image and text in the custom toolbar to suit your specific design requirements.

Render DropDownList in custom toolbar

Render DropDownList in custom toolbar in Syncfusion Angular Grid enables you to extend the functionality of the custom toolbar by incorporating a DropDownList component, allowing you to perform various actions within the Grid based on their selections.

This can be achieved by utilizing the ng-template. The example below demonstrates how to render the DropDownList component in the custom toolbar, where the toolbar template includes the its change event is bound to the onChange method.

In the onChange method, the text of the selected item is checked to determine the appropriate action. For example, if Update is chosen, the endEdit method is called to exit the edit mode. If Edit is selected, the selected record is passed to the startEdit method to initiate the edit mode dynamically. Similarly, if Delete is picked, the selected record is passed to the deleteRecord method to remove it from the grid.

import { Component, OnInit, ViewChild } from '@angular/core';
import { ChangeEventArgs, DropDownListComponent, } from '@syncfusion/ej2-angular-dropdowns';
import { data } from './datasource';
import { GridComponent, EditSettingsModel  } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' height='200px' [editSettings]='editSettings'>
                <ng-template #toolbarTemplate let-data>
                <div style="display: flex">
                    <label style="padding: 10px 10px 26px 0">
                        Change the value:
                    </label>
                    <ejs-dropdownlist #dropDown style="margin-top:5px" (change)="onChange($event)" [dataSource]='dropDownData' [placeholder]='placeholder' width="120px"></ejs-dropdownlist>
                </div>
                    </ng-template>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' isPrimaryKey='true' textAlign='Right' width=90></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=100></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=120></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    public editSettings?:EditSettingsModel ;
    public placeholder = 'Select a value'

    @ViewChild('grid')
    public grid: GridComponent;
    @ViewChild('dropDown')
    public dropDown: DropDownListComponent;

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

    public dropDownData = [{ text: 'Edit' }, { text: 'Delete' }, { text: 'Update' }];
    public onChange(args: ChangeEventArgs): void {
        const selectedRow = this.grid.getSelectedRecords()[0];
        if (args.itemData.text === 'Update') {
            this.grid.endEdit();
        }
        if (args.itemData.text === 'Edit') {
            this.grid.startEdit();
        }
        if (args.itemData.text === 'Delete') {
            this.grid.deleteRecord(selectedRow as string);
        }
        (this.dropDown as DropDownListComponent).value = '';
        (this.dropDown as DropDownListComponent).placeholder = args.itemData.text as string;
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ToolbarService, EditService } from '@syncfusion/ej2-angular-grids';
import { ToolbarModule } from '@syncfusion/ej2-angular-navigations';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ToolbarModule,
        DropDownListAllModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ToolbarService, 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);

Render a component or element using the toolbar template

Rendering a component or element using the toolbar template in the Syncfusion Angular Grid allows you to extend the capabilities of the grid toolbar by incorporating custom components or elements. This provides flexibility to enhance the toolbar with custom buttons, dropdowns, input fields, icons, or any other desired UI elements. You can bind event handlers or handle interactions within the template to enable specific actions or behaviors associated with the added components or elements.

To render custom components or elements within the toolbar, use the ng-template directive. This allows you to include other components, such as a Button, and perform specific grid actions based on the button click. For example, when the ExcelExport button is clicked, the excelExport method is called to export the grid to Excel. Similarly, when the PdfExport button is clicked, the pdfExport method is called to export the grid to PDF format.Likewise, when the Print button is clicked, the print method will triggered to print the grid.

The following example demonstrates how to render a Button component in the toolbar using ng-template and perform grid action based on the respected button click.

import { Component, OnInit, ViewChild } from '@angular/core';
import { data } from './datasource';
import { GridComponent } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' height='200px'  [allowExcelExport]="true" [allowPdfExport]="true">
                <ng-template #toolbarTemplate let-data>
                    <div id='toolbar'>
                        <button id="excelButton" ejs-button cssClass="e-outline" (click)="exportAction($event)">Excel Export</button>
                        <button id="pdfButton" ejs-button cssClass="e-outline" (click)="exportAction($event)">Pdf Export</button>
                        <button id="printButton" ejs-button cssClass="e-outline" (click)="exportAction($event)">Print</button>
                    </div>
                </ng-template>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' isPrimaryKey='true' textAlign='Right' width=90></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=100></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=120></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    @ViewChild('grid')
    public grid?: GridComponent;

    ngOnInit(): void {
        this.data = data;
    }

    exportAction(args: MouseEvent) {
        if ((args.currentTarget  as HTMLElement).id === 'excelButton') {
            (this.grid as GridComponent).excelExport();
        }
        else if ((args.currentTarget as HTMLElement).id === 'pdfButton') {
            (this.grid as GridComponent).pdfExport();
        }
        else {
            (this.grid as GridComponent).print();
        }
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ToolbarService,  PdfExportService, ExcelExportService  } from '@syncfusion/ej2-angular-grids';
import { ToolbarModule } from '@syncfusion/ej2-angular-navigations';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ToolbarModule,
        ButtonModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ToolbarService, PdfExportService, ExcelExportService]
})
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);