Search results

How To

21 Dec 2022 / 39 minutes to read

Refresh the Datasource

You can add/delete the datasource records through an external button. To reflect the datasource changes in grid, you need to invoke the refresh method.

Please follow the below steps to refresh the grid after datasource change.

Step 1:

Add/delete the datasource record by using the following code.

Copied to clipboard
    this.grid.dataSource.unshift(data); // Add a new record.

    this.grid.dataSource.splice(selectedRow, 1); // Delete a record.

Step 2:

Refresh the grid after the datasource change by using the refresh method.

Copied to clipboard
    this.grid.refresh(); // Refresh the Grid.
Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { GridComponent } from '@syncfusion/ej2-angular-grids';
import { data } from './datasource';


@Component({
    selector: 'app-root',
    template: `<button ej-button class='e-flat' (click)='add()'> Add </button>
               <button ej-button class='e-flat' (click)='delete()'> Delete </button>
                <ejs-grid #grid [dataSource]='data' [height]='280' >
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=90></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                        <e-column field='Freight' headerText='Freight' textAlign='Right' format='C2' width=90></e-column>
                        <e-column field='ShipCity' headerText='Ship City' 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;
    }
    add(): void {
        const rdata: object = { OrderID: 10247, CustomerID: 'ASDFG', Freight: 40.4, OrderDate: new Date(8367642e5) };
        (this.grid.dataSource as object[]).unshift(rdata);
        this.grid.refresh();
    }
    delete(): void {
        const selectedRow: number = this.grid.getSelectedRowIndexes()[0];
        if (this.grid.getSelectedRowIndexes().length) {
            (this.grid.dataSource as object[]).splice(selectedRow, 1);
        } else {
            alert('No records selected for delete operation');
        }
        this.grid.refresh();
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Enable/Disable Grid and its actions

You can enable/disable the Grid and its actions by applying/removing corresponding CSS styles.

To enable/disable the grid and its actions, follow the given steps:

Step 1:

Create CSS class with custom style to override the default style of Grid.

Copied to clipboard
    .disablegrid {
        pointer-events: none;
        opacity: 0.4;
    }
    .wrapper {
        cursor: not-allowed;
    }

Step 2:

Add/Remove the CSS class to the Grid in the click event handler of Button.

Copied to clipboard
    public btnClick():void {
      if (this.Grid.element.classList.contains('disablegrid')) {
          this.Grid.element.classList.remove('disablegrid');
          document.getElementById("GridParent").classList.remove('wrapper');
      }
      else {
          this.Grid.element.classList.add('disablegrid');
          document.getElementById("GridParent").classList.add('wrapper');
      }
    }

In the below demo, the button click will enable/disable the Grid and its actions.

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

@Component({
    selector: 'app-root',
    template: `<button ejs-button (click)="btnClick()"  cssClass="e-flat">Enable/Disable Grid</button>
               <div id="GridParent">
                    <ejs-grid #Grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' height='273px'>
                        <e-columns>
                            <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                            <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                            <e-column field='Freight' headerText='Freight' textAlign= 'Right'
                             editType= 'numericedit' width=120 format= 'C2'></e-column>
                            <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
                        </e-columns>
                    </ejs-grid>
               </div>`
})
export class AppComponent implements OnInit {

    public data: object[];
    @ViewChild('Grid') public Grid: GridComponent;
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];

    ngOnInit(): void {
        this.data = data;
        this.editSettings = { allowAdding: true, allowEditing: true, allowDeleting: true };
        this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
    }
    public btnClick(): void {
        if (this.Grid.element.classList.contains('disablegrid')) {
            this.Grid.element.classList.remove('disablegrid');
            document.getElementById('GridParent').classList.remove('wrapper');
        } else {
            this.Grid.element.classList.add('disablegrid');
            document.getElementById('GridParent').classList.add('wrapper');
        }
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

By default, the expanded child grids will be printed from the current page alone. You can print the expanded child grids from other pages by using the actionBegin event.

In the following example, we have printed expanded child grids form other pages.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { data, employeeData } from './datasource';
import { DetailRowService, GridComponent, getPrintGridModel, Row, Column,
     ToolbarService, printGridInit, GridModel, HierarchyGridPrintMode } from '@syncfusion/ej2-angular-grids';
import { extend } from '@syncfusion/ej2-base';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='pData' [childGrid]='childGrid' [toolbar]='["Print"]'
     hierarchyPrintMode='Expanded' allowPaging=true [pageSettings]="{pageSize: 4}" (actionBegin)="actionBegin($event)" >
                    <e-columns>
                        <e-column field='EmployeeID' headerText='Employee ID' textAlign='Right' width=120></e-column>
                        <e-column field='FirstName' headerText='FirstName' width=150></e-column>
                        <e-column field='LastName' headerText='Last Name' width=150></e-column>
                        <e-column field='City' headerText='City' width=150></e-column>
                    </e-columns>
                </ejs-grid>
                `,
    providers: [DetailRowService, ToolbarService]
})
export class AppComponent implements OnInit {

    public pData: object[];
    public expandedChildGrid: object = {};
    public childGrid: GridModel = {
        dataSource: data,
        queryString: 'EmployeeID',
        columns: [
            { field: 'OrderID', headerText: 'Order ID', textAlign: 'Right', width: 120 },
            { field: 'CustomerID', headerText: 'Customer ID', width: 150 },
            { field: 'ShipCity', headerText: 'Ship City', width: 150 },
            { field: 'ShipName', headerText: 'Ship Name', width: 150 }
        ]
    };
    @ViewChild('grid') public grid: GridComponent;

    ngOnInit(): void {
        this.pData = employeeData;
        this.grid.on(printGridInit, this.printInit, this);
    }

    actionBegin(args) {
        if (args.requestType === 'paging') {
            this.expandedChildGrid = extend({}, this.expandedChildGrid, this.getExpandedState(this.grid, 'Expanded', args.previousPage));
        }
    }

    printInit(gridModel) {
        gridModel.printgrid.expandedRows = extend({}, this.expandedChildGrid, gridModel.expandedRows);
    }

    getExpandedState(gObj: GridComponent, hierarchyPrintMode: HierarchyGridPrintMode, currentPage: number): object {
        const obj: object = {};
        const rows: Row<Column>[] = gObj.getRowsObject();
        for (const row of rows) {
            if (row.isExpand && !row.isDetailRow) {
                const index: number = gObj.allowPaging ? row.index +
                    (currentPage * gObj.pageSettings.pageSize) - gObj.pageSettings.pageSize : row.index;
                obj[index] = {};
                obj[index].isExpand = true;
                obj[index].gridModel = getPrintGridModel(row.childGrid, hierarchyPrintMode);
            }
        }
        return obj;
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { PageService, SortService, FilterService, GroupService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
        SortService,
        FilterService,
        GroupService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Columns

Change Column Header Text Dynamically

You can change the column headerText dynamically through an external button.

Follow the given steps to change the header text dynamically:

Step 1:

Get the column object corresponding to the field name by using the getColumnByField method. Then change the header Text value.

Copied to clipboard
let column = this.grid.getColumnByField('ShipCity'); // Get column object.
column.headerText = 'Changed Text';

Step 2:

To reflect the changes in the grid header, invoke the refreshHeader method.

Copied to clipboard
this.grid.refreshHeader();
Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { GridComponent } from '@syncfusion/ej2-angular-grids';
import { data } from './datasource';


@Component({
    selector: 'app-root',
    template: `<button ej-button class='e-flat' (click)='click()'>Change Header Text</button>
                <ejs-grid #grid [dataSource]='data' [height]='280' >
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=90></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                        <e-column field='Freight' headerText='Freight' textAlign='Right' format='C2' width=90></e-column>
                        <e-column field='ShipCity' headerText='Ship City' 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;
    }
    click(): void {
        const column = this.grid.getColumnByField('ShipCity'); // get the JSON object of the column corresponding to the field name
        column.headerText = 'Changed Text'; // assign a new header text to the column
        this.grid.refreshHeader();
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Customize Column Styles

You can customise the appearance of header and content of the particular column using the customAttributes property.

To customize the grid column, follow the given steps:

Step 1:

Create a css class with custom style to override the default style for rowcell and headercell.

Copied to clipboard
.e-grid .e-rowcell.customcss{
    background-color: #ecedee;
    color: 'red';
    font-family: 'Bell MT';
    font-size: 20px;
}

.e-grid .e-headercell.customcss{
    background-color: #2382c3;
    color: white;
    font-family: 'Bell MT';
    font-size: 20px;
}

Step 2:

Add the custom css class to particular column by using customAttributes property.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' [height]='315'>
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=90></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' [customAttributes]='customAttributes' width=120></e-column>
                        <e-column field='Freight' headerText='Freight' textAlign='Right' format='C2' width=90></e-column>
                        <e-column field='OrderDate' headerText='Order Date' textAlign='Right' format='yMd' width=120></e-column>
                    </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit{

    public data: object[];
    public customAttributes: object;

    ngOnInit(): void{
        this.data = data;
        this.customAttributes = {class: 'customcss'};
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { PageService, SortService, FilterService, GroupService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                GroupService]
})
export class AppModule { }
Copied to clipboard
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Custom Tooltip for Columns

You can achieve the custom tooltip(EJ2 Tooltip) for Grid by using the queryCellInfo event.

Render the ToolTip component for the grid cells by using the following code in the queryCellInfo event.

Copied to clipboard
tooltip (args: QueryCellInfoEventArgs) {
    let tooltip: Tooltip = new Tooltip({
        content: args.data[args.column.field].toString();
    }, args.cell);
}
Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { QueryCellInfoEventArgs } from '@syncfusion/ej2-angular-grids';
import { Tooltip } from '@syncfusion/ej2-popups';
import { data } from './datasource';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' [height]='315' (queryCellInfo)='tooltip($event)' >
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=90></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                        <e-column field='Freight' headerText='Freight' textAlign='Right' format='C2' width=90></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[];

    ngOnInit(): void {
        this.data = data;
    }
    tooltip(args: QueryCellInfoEventArgs) {
        const tooltip: Tooltip = new Tooltip({
            content: args.data[args.column.field].toString()
        }, args.cell as HTMLTableCellElement);
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { TooltipModule } from '@syncfusion/ej2-angular-popups';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ButtonModule,
        TooltipModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
Copied to clipboard
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Render other components in a column

You can render any component in a grid column using the template property.

Initialize the column template for your custom component. The template property renders the custom component.

Copied to clipboard
    <div>
        <ejs-dropdownlist value='Order Placed' [dataSource]='dropData' [popupHeight]='150' [popupWidth]='150' ></ejs-dropdownlist>
    </div>
Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' [height]='300'>
                    <e-columns>
                        <e-column headerText='Order Status'width='200'>
                            <ng-template #template let-data>
                                <div>
                                    <ejs-dropdownlist value='Order Placed' [dataSource]='dropData' [popupHeight]='150' [popupWidth]='150' >
                                    </ejs-dropdownlist>
                                </div>
                            </ng-template>
                        </e-column>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=90></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                        <e-column field='Freight' headerText='Freight' textAlign='Right' format='C2' width=90></e-column>
                        <e-column field='OrderDate' headerText='Order Date' textAlign='Right' format='yMd' width=120></e-column>
                    </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public dropData: string[];

    ngOnInit(): void {
        this.data = data;
        this.dropData = ['Order Placed', 'Processing', 'Delivered'];
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DropDownListComponent } from '@syncfusion/ej2-angular-dropdowns';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ButtonModule
    ],
    declarations: [AppComponent, DropDownListComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
Copied to clipboard
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Change the Orientation of Header Text

You can change the orientation of the header text by using the customAttributes property.

To change the Orientation of Header Text, Ensure the following steps:

Step 1:

Create a css class with orientation style for grid header cell.

Copied to clipboard
.orientationcss .e-headercelldiv {
    transform: rotate(90deg);
}

Step 2:

Add the custom css class to particular column by using customAttributes property.

Copied to clipboard
    <e-column field='Freight' headerText='Freight' textAlign='Center' format='C2' [customAttributes]='customAttributes' width=80></e-column>

Step 3:

Resize the header cell height by using the following code.

Copied to clipboard
setHeaderHeight(args) {
    let textWidth: number = document.querySelector('.orientationcss > div').scrollWidth;//Obtain the width of the headerText content.
    let headerCell: NodeList = document.querySelectorAll('.e-headercell');
    for(let i: number = 0; i < headerCell.length; i++) {
        (<HTMLElement>headerCell.item(i)).style.height = textWidth + 'px'; //Assign the obtained textWidth as the height of the headerCell.
    }
}
Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' [height]='240' (created)='setHeaderHeight($event)' >
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                        <e-column field='Freight' headerText='Freight' textAlign='Center'
                         format='C2' [customAttributes]='customAttributes' width=80></e-column>
                        <e-column field='ShipCity' headerText='Ship City' width=100 ></e-column>
                    </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public customAttributes: object;

    ngOnInit(): void {
        this.data = data;
        this.customAttributes = { class: 'orientationcss' };
    }
    setHeaderHeight(args) {
        const textWidth = document.querySelector('.orientationcss > div').scrollWidth; // Obtain the width of the headerText content.
        const headerCell: NodeList = document.querySelectorAll('.e-headercell');
        for (let i = 0; i < headerCell.length; i++) {
            // Assign the obtained textWidth as the height of the headerCell.
            (headerCell.item(i) as HTMLElement).style.height = textWidth + 'px';
        }
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ButtonModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
Copied to clipboard
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Customize the icon for column menu

You can customize the column menu icon by overriding the default grid class .e-icons.e-columnmenu with a custom property content as mentioned below.

Copied to clipboard
.e-grid .e-columnheader .e-icons.e-columnmenu::before {
              content: "\e941";
      }

In the below sample, grid is rendered with a customized column menu icon.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { ColumnMenuService } from '@syncfusion/ej2-angular-grids';
import { data } from './datasource';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' [height]='315' showColumnMenu='true' >
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' width=90></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                        <e-column field='Freight' headerText='Freight' format='C2' width=90></e-column>
                        <e-column field='ShipName' headerText='Ship Name' width=120></e-column>
                    </e-columns>
                </ejs-grid>`,
   providers: [ColumnMenuService]
})
export class AppComponent implements OnInit {

    public data: object[];

    ngOnInit(): void {
        this.data = data;
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
Copied to clipboard
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Editing

Editing with template column

You can edit template column value by defining field for that particular column.

In the below demo, the ShipCountry column is rendered with the template.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign= 'Right'
                    editType= 'numericedit' width=120 format= 'C2'></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150>
                        <ng-template #template let-data>
                            <a href="#">{{data.ShipCountry}}</a>
                        </ng-template>
                    </e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];

    ngOnInit(): void {
        this.data = data;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true };
        this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Customize the Edit Dialog

You can customize the appearance of the edit dialog in the actionComplete event based on requestType as beginEdit or add.

In the below example, we have changed the dialog’s header text for editing and adding records.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar'
     (actionComplete)="actionComplete($event)" height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign= 'Right'
                     editType= 'numericedit' width=120 format= 'C2'></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];

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

    actionComplete(args) {
        if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
            const dialog = args.dialog;
            const CustomerID = 'CustomerID';
            // change the header of the dialog
            dialog.header = args.requestType === 'beginEdit' ? 'Record of ' + args.rowData[CustomerID] : 'New Customer';
        }
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Show or Hide columns in Dialog editing

You can show hidden columns or hide visible column’s editor in the dialog while editing the grid record using actionBegin and actionComplete events.

In the actionBegin event, based on requestType as beginEdit or add. We can show or hide the editor by using column.visible property.

In the actionComplete event, based on requestType as save. We can reset the properties back to the column state.

In the below example, we have rendered the grid columns CustomerID as hidden column and ShipCountry as visible column. In the edit mode, we have changed the CustomerID column to visible state and ShipCountry column to hidden state.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { data } from './datasource';
import { EditSettingsModel, ToolbarItems, GridComponent, Column, SaveEventArgs, EditEventArgs } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' (actionBegin)="actionBegin($event)"
     (actionComplete)="actionComplete($event)" height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' [visible]='false' width=120></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign= 'Right'
                     editType= 'numericedit' width=120 format= 'C2'></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];
    @ViewChild('grid') grid: GridComponent;

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

    actionBegin(args: EditEventArgs) {
        if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
            for (const cols of this.grid.columns) {
                if ((cols as Column).field === 'CustomerID') {
                    (cols as Column).visible = true;
                } else if ((cols as Column).field === 'ShipCountry') {
                    (cols as Column).visible = false;
                }
            }
        }
    }

    actionComplete(args: SaveEventArgs) {
        if (args.requestType === 'save') {
            for (const cols of this.grid.columns) {
                if ((cols as Column).field === 'CustomerID') {
                    (cols as Column).visible = false;
                } else if ((cols as Column).field === 'ShipCountry') {
                    (cols as Column).visible = true;
                }
            }
        }
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Cascading DropDownList with Grid editing

You can achieve the Cascading DropDownList with grid Editing by using the Cell Edit Template feature.

In the below demo, Cascading DropDownList rendered for ShipCountry and ShipState column.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { DropDownList } from '@syncfusion/ej2-dropdowns';
import { Query, DataManager } from '@syncfusion/ej2-data';
import { cascadeData } from './datasource';
import { EditSettingsModel, ToolbarItems, IEditCell } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit'
                     [edit]='countryParams' width=150></e-column>
                    <e-column field='ShipState' headerText='Ship State' editType= 'dropdownedit' [edit]='stateParams' width=150></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];
    public countryParams: IEditCell;
    public stateParams: IEditCell;

    public countryElem: HTMLElement;
    public countryObj: DropDownList;

    public stateElem: HTMLElement;
    public stateObj: DropDownList;

    public country: object[] = [
        { countryName: 'United States', countryId: '1' },
        { countryName: 'Australia', countryId: '2' }
    ];
    public state: object[] = [
        { stateName: 'New York', countryId: '1', stateId: '101' },
        { stateName: 'Virginia ', countryId: '1', stateId: '102' },
        { stateName: 'Washington', countryId: '1', stateId: '103' },
        { stateName: 'Queensland', countryId: '2', stateId: '104' },
        { stateName: 'Tasmania ', countryId: '2', stateId: '105' },
        { stateName: 'Victoria', countryId: '2', stateId: '106' }
    ];

    ngOnInit(): void {
        this.data = cascadeData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true };
        this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
        this.countryParams = {
            create: () => {
                this.countryElem = document.createElement('input');
                return this.countryElem;
            },
            read: () => {
                return this.countryObj.text;
            },
            destroy: () => {
                this.countryObj.destroy();
            },
            write: () => {
                this.countryObj = new DropDownList({
                    dataSource: new DataManager(this.country),
                    fields: { value: 'countryId', text: 'countryName' },
                    change: () => {
                        this.stateObj.enabled = true;
                        const tempQuery: Query = new Query().where('countryId', 'equal', this.countryObj.value);
                        this.stateObj.query = tempQuery;
                        this.stateObj.text = null;
                        this.stateObj.dataBind();
                    },
                    placeholder: 'Select a country',
                    floatLabelType: 'Never'
                });
                this.countryObj.appendTo(this.countryElem);
            }
        };
        this.stateParams = {
            create: () => {
                this.stateElem = document.createElement('input');
                return this.stateElem;
            },
            read: () => {
                return this.stateObj.text;
            },
            destroy: () => {
                this.stateObj.destroy();
            },
            write: () => {
                this.stateObj = new DropDownList({
                    dataSource: new DataManager(this.state),
                    fields: { value: 'stateId', text: 'stateName' },
                    enabled: false,
                    placeholder: 'Select a state',
                    floatLabelType: 'Never'
                });
                this.stateObj.appendTo(this.stateElem);
            }
        };
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Provide custom data source and enabling filtering to DropDownList

You can provide data source to the DropDownList by using the columns.edit.params property.

While setting new data source using edit params, you must specify a new query property too for the DropDownList as follows,

Copied to clipboard
{
    this.countryParams = {
        params:   {
            allowFiltering: true,
            dataSource: this.country,
            fields: {text:'countryName',value:'countryName'},
            query: new Query(),
            actionComplete: () => false
            }
        }
}

You can also enable filtering for the DropDownList by passing the allowFiltering as true to the edit params.

In the below demo, DropDownList is rendered with custom Datasource for the ShipCountry column and enabled filtering to search DropDownList items.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { DropDownList } from '@syncfusion/ej2-dropdowns';
import { Query, DataManager } from '@syncfusion/ej2-data';
import { cascadeData } from './datasource';
import { EditSettingsModel, ToolbarItems, IEditCell } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit'
                     [edit]='countryParams' width=150></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];
    public countryParams: IEditCell;

    public country: object[] = [
        { countryName: 'United States', countryId: '1' },
        { countryName: 'Australia', countryId: '2' },
        { countryName: 'India', countryId: '3' }
    ];

    ngOnInit(): void {
        this.data = cascadeData;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true };
        this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
        this.countryParams = {
            params: {
                allowFiltering: true,
                dataSource: new DataManager(this.country),
                fields: { text: 'countryName', value: 'countryName' },
                query: new Query(),
                actionComplete: () => false
            }
        };
    }

}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Use Wizard like Dialog Editing

Wizard helps you create intuitive step-by-step forms to fill. You can achieve the wizard like editing by using the dialog template feature. It support your own editing template by defining editSettings.mode as Dialog and editSettingsTemplate as template variable to define the editors.

The following example demonstrate the wizard like editing in the grid with the unobtrusive Validation.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { data } from './datasource';
import { DataUtil } from '@syncfusion/ej2-data';
import { EditSettingsModel, ToolbarItems, GridComponent, DialogEditEventArgs } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    templateUrl: `app/wizardtemplate.html`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];
    public shipCountryDistinctData: object;
    public next = 'Next';
    public currentTab = 0;
    public hidden = true;
    @ViewChild('grid') grid: GridComponent;
    @ViewChild('orderForm') orderForm: FormGroup;

    ngOnInit(): void {
        this.data = data;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' };
        this.toolbar = ['Add', 'Edit', 'Delete'];
        this.shipCountryDistinctData = DataUtil.distinct(data, 'ShipCountry', true);
    }

    actionComplete(args: DialogEditEventArgs) {
        if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
            args.form.ej2_instances[0].rules = {}; // Disable deafault valdation.
            // Set initail Focus
            if (args.requestType === 'beginEdit') {
                (args.form.elements.namedItem('CustomerID') as HTMLInputElement).focus();
            }
            this.currentTab = 0;
            this.hidden = true;
            this.next = 'Next';
        }
    }

    nextBtn(args) {
        if (this.orderForm.valid) {
            if (this.next !== 'SUBMIT') {
                this.currentTab++;
                this.nextpre(this.currentTab);
            } else {
                this.grid.endEdit();
            }
        }
    }

    previousBtn(args) {
        if (this.orderForm.valid) {
            this.currentTab--;
            this.nextpre(this.currentTab);
        }
    }

    nextpre(current) {
        if (current) {
            this.hidden = false;
            this.next = 'SUBMIT';
        } else {
            this.hidden = true;
            this.next = 'NEXT';
        }
    }
}
Copied to clipboard
<ejs-grid #grid [dataSource]='data' allowPaging='true' [editSettings]='editSettings' [toolbar]='toolbar' (actionComplete)='actionComplete($event)'>
    <e-columns>
        <e-column field='OrderID' headerText='Order ID' width='120' textAlign='Right' [isPrimaryKey]='true'></e-column>
        <e-column field='CustomerID' headerText='Customer Name' width='120'></e-column>
        <e-column field='ShipCountry' headerText='Ship Country' width='150'></e-column>
        <e-column field='Verified' headerText='Verified' width='100' type='boolean' [displayAsCheckBox]='true'></e-column>
    </e-columns>
    <ng-template #editSettingsTemplate let-data>
        <div ngForm #orderForm="ngForm">
            <div id="tab0" class='tab' [hidden]="!hidden">
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <div class="e-float-input e-control-wrapper" [ngClass]="{'e-error': OrderID.invalid && (OrderID.dirty || OrderID.touched)}">
                            <input [(ngModel)]="data.OrderID" required id="OrderID" name="OrderID" type="text" [attr.disabled]="!data.isAdd ? '' : null" #OrderID="ngModel">
                            <span class="e-float-line"></span>
                            <label class="e-float-text e-label-top" for="OrderID"> Order ID</label>
                        </div>
                        <div id="OrderIDError" *ngIf='OrderID.invalid && (OrderID.dirty || OrderID.touched)'>
                            <label class="e-error" for="OrderID" id="OrderID-info" style="display: block;">*Order ID is required</label>
                        </div>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <div class="e-float-input e-control-wrapper" [ngClass]="{'e-error': CustomerID.invalid && (CustomerID.dirty || CustomerID.touched)}">
                            <input [(ngModel)]="data.CustomerID" required id="CustomerID" name="CustomerID" type="text" #CustomerID="ngModel">
                            <span class="e-float-line"></span>
                            <label class="e-float-text e-label-top" for="CustomerID">Customer Name</label>
                        </div>
                        <div id="CustomerIDError" *ngIf='CustomerID.invalid && (CustomerID.dirty || CustomerID.touched)'>
                            <label class="e-error" for="CustomerID" id="CustomerID-info" style="display: block;">*Customer Name is required</label>
                        </div>    
                    </div>
                </div>
            </div>
            <div id=tab1 class='tab' [hidden]="hidden" >
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <ejs-dropdownlist id="ShipCountry" name="ShipCountry" [(ngModel)]="data.ShipCountry" [dataSource]='shipCountryDistinctData' [fields]="{text: 'ShipCountry', value: 'ShipCountry' }" placeholder="Ship Country" popupHeight='300px' floatLabelType='Always'></ejs-dropdownlist>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group col-md-6">
                        <ejs-checkbox #Verified name="Verified" id="Verified" label="Verified" [checked]="data.Verified" ></ejs-checkbox>
                    </div>
                </div>
            </div>
            <div id='footer'>
                <button ejs-button type="button" cssClass="e-info e-btn" style="float: left" (click)="previousBtn($event)" [hidden]="hidden">Previous</button>
                <button ejs-button type="button" cssClass="e-info e-btn" style="float: right" (click)='nextBtn($event)' [disabled]='next === "Next" && (CustomerID.invalid || OrderID.invalid)'>{{next}}</button>
            </div>
        </div>
    </ng-template>
</ejs-grid>
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { CheckBoxAllModule, ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        CheckBoxAllModule,
        GridModule,
        ButtonModule,
        DropDownListAllModule, ReactiveFormsModule, FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Using Tab Inside the Dialog Editing

You can use Tab component inside dialog edit UI using dialog template feature. The dialog template feature can be enabled by defining editSettings.mode as Dialog and editSettingsTemplate as template variable to define the editors.

To include tab components in the Dialog, please ensure the following steps:

Step 1:

Initialize the template for your tab component.

Copied to clipboard
        <div id="tab1">
        <div class="form-row">
            <div class="form-group col-md-6">
                <div class="e-float-input e-control-wrapper" [ngClass]="{'e-error': OrderID.invalid && (OrderID.dirty || OrderID.touched)}">
                    <input [(ngModel)]="data.OrderID" required id="OrderID" name="OrderID" type="text" [attr.disabled]="!data.isAdd ? '' : null" #OrderID="ngModel">
                    <span class="e-float-line"></span>
                    <label class="e-float-text e-label-top" for="OrderID"> Order ID</label>
                </div>
                <div id="OrderIDError" *ngIf='OrderID.invalid && (OrderID.dirty || OrderID.touched)'>
                    <label class="e-error" for="OrderID" id="OrderID-info" style="display: block;">*Order ID is required</label>
                </div>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col-md-6">
                <div class="e-float-input e-control-wrapper" [ngClass]="{'e-error': CustomerID.invalid && (CustomerID.dirty || CustomerID.touched)}">
                    <input [(ngModel)]="data.CustomerID" required id="CustomerID" name="CustomerID" type="text" #CustomerID="ngModel">
                    <span class="e-float-line"></span>
                    <label class="e-float-text e-label-top" for="CustomerID">Customer Name</label>
                </div>
                <div id="CustomerIDError" *ngIf='CustomerID.invalid && (CustomerID.dirty || CustomerID.touched)'>
                    <label class="e-error" for="CustomerID" id="CustomerID-info" style="display: block;">*Customer Name is required</label>
                </div>
            </div>
        </div>
        <button ejs-button type="button" cssClass="e-info e-btn" style="float: right" (click)="nextBtn($event)" >next</button>
    </div>

    <div id="tab2" style='display: none'>
        <div class="form-row" >
            <div class="form-group col-md-6">
                <ejs-dropdownlist id="ShipCountry" name="ShipCountry" [(ngModel)]="data.ShipCountry" [dataSource]='shipCountryDistinctData' [fields]="{text: 'ShipCountry', value: 'ShipCountry' }" placeholder="Ship Country" popupHeight='300px' floatLabelType='Always'></ejs-dropdownlist>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col-md-6">
                <ejs-checkbox #Verified name="Verified" id="Verified" label="Verified" [checked]="data.Verified" ></ejs-checkbox>
            </div>
        </div>
        <button ejs-button type="button" cssClass="e-info e-btn" style="float: right" (click)='submitBtn($event)'>submit</button>
    </div>

Step 2:

To render the Tab component, use the editSettingsTemplate of the Grid.

Copied to clipboard
    <ejs-tab #tab id="tab_wizard" showCloseButton=false (selecting)='selecting($event)'>
        <e-tabitems>
            <e-tabitem [header]="{ 'text': 'Details' }" content="#tab1"></e-tabitem>
            <e-tabitem [header]="{ 'text': 'Verify' }" content="#tab2"></e-tabitem>
        </e-tabitems>
    </ejs-tab>

The following example, we have rendered tab control inside the edit dialog. The tab control has two tabs and once you fill the first tab and navigate to second one. The validation for first tab was done before navigate to second.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { DataUtil } from '@syncfusion/ej2-data';
import { data } from './datasource';
import { EditSettingsModel, ToolbarItems, GridComponent, DialogEditEventArgs } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    templateUrl: `./app/tablikeedit.html`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];
    public shipCountryDistinctData: object;
    @ViewChild('grid')
    grid: GridComponent;
    @ViewChild('orderForm')
    orderForm: FormGroup
    @ViewChild('tab')
    tabObj: any;

    ngOnInit(): void {
        this.data = data;
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' };
        this.toolbar = ['Add', 'Edit', 'Delete'];
        this.shipCountryDistinctData = DataUtil.distinct(data, 'ShipCountry', true );
    }

    actionComplete(args: DialogEditEventArgs) {
        if ((args.requestType === 'beginEdit' || args.requestType === 'add')) {
            // Disable deafault valdation.
            args.form.ej2_instances[0].rules = {};
            // Set initail Focus
            if (args.requestType === 'beginEdit') {
                (args.form.elements.namedItem('CustomerID')as HTMLInputElement).focus();
            }
        }
    }

    nextBtn() {
        this.moveNext();
    }

    selecting(e) {
     if(e.isSwiped){
       e.cancel = true;
     }
     if(e.selectingIndex === 1) {
       e.cancel = !this.orderForm.valid;
     }
    }

    moveNext() {
        if (this.orderForm.valid)) {
            this.tabObj.select(1);
        }
    }
    submitBtn() {
        if (this.orderForm.valid) {
            this.grid.endEdit();
        }
    }
}
Copied to clipboard
<ejs-grid #grid [dataSource]='data' allowPaging='true' [editSettings]='editSettings' [toolbar]='toolbar' (actionComplete)='actionComplete($event)'>
    <e-columns>
        <e-column field='OrderID' headerText='Order ID' width='120' textAlign='Right' [isPrimaryKey]='true'></e-column>
        <e-column field='CustomerID' headerText='Customer Name' width='120'></e-column>
        <e-column field='ShipCountry' headerText='Ship Country' width='150'></e-column>
        <e-column field='Verified' headerText='Verified' width='100' type='boolean' [displayAsCheckBox]='true'></e-column>
    </e-columns>
    <ng-template #editSettingsTemplate let-data>
        <div ngForm #orderForm="ngForm">
           <ejs-tab #tab id="tab_wizard" showCloseButton=false (selecting)='selecting($event)'>
        <e-tabitems>
            <e-tabitem [header]="{ 'text': 'Details' }" >
            <ng-template #content>
            <div id="tab1">
        <div class="form-row">
            <div class="form-group col-md-6">
                <div class="e-float-input e-control-wrapper" [ngClass]="{'e-error': OrderID.invalid && (OrderID.dirty || OrderID.touched)}">
                    <input [(ngModel)]="data.OrderID" required id="OrderID" name="OrderID" type="text" [attr.disabled]="!data.isAdd ? '' : null" #OrderID="ngModel">
                    <span class="e-float-line"></span>
                    <label class="e-float-text e-label-top" for="OrderID"> Order ID</label>
                </div>
                <div id="OrderIDError" *ngIf='OrderID.invalid && (OrderID.dirty || OrderID.touched)'>
                    <label class="e-error" for="OrderID" id="OrderID-info" style="display: block;">*Order ID is required</label>
                </div>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col-md-6">
                <div class="e-float-input e-control-wrapper" [ngClass]="{'e-error': CustomerID.invalid && (CustomerID.dirty || CustomerID.touched)}">
                    <input [(ngModel)]="data.CustomerID" required id="CustomerID" name="CustomerID" type="text" #CustomerID="ngModel">
                    <span class="e-float-line"></span>
                    <label class="e-float-text e-label-top" for="CustomerID">Customer Name</label>
                </div>
                <div id="CustomerIDError" *ngIf='CustomerID.invalid && (CustomerID.dirty || CustomerID.touched)'>
                    <label class="e-error" for="CustomerID" id="CustomerID-info" style="display: block;">*Customer Name is required</label>
                </div>
            </div>
        </div>
        <button ejs-button type="button" cssClass="e-info e-btn" style="float: right" (click)="nextBtn($event)" >next</button>
    </div>
            </ng-template></e-tabitem>
            <e-tabitem [header]="{ 'text': 'Verify' }">
            <ng-template #content>
               <div id="tab2" style='display: none'>
        <div class="form-row" >
            <div class="form-group col-md-6">
                <ejs-dropdownlist id="ShipCountry" name="ShipCountry" [(ngModel)]="data.ShipCountry" [dataSource]='shipCountryDistinctData' [fields]="{text: 'ShipCountry', value: 'ShipCountry' }" placeholder="Ship Country" popupHeight='300px' floatLabelType='Always'></ejs-dropdownlist>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col-md-6">
                <ejs-checkbox #Verified name="Verified" id="Verified" label="Verified" [checked]="data.Verified" ></ejs-checkbox>
            </div>
        </div>
        <button ejs-button type="button" cssClass="e-info e-btn" style="float: right" (click)='submitBtn($event)'>submit</button>
    </div>
            </ng-template>
            </e-tabitem>
        </e-tabitems>
    </ejs-tab>
        </div>
    </ng-template>
</ejs-grid>
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { TabAllModule } from '@syncfusion/ej2-angular-navigations';
import { CheckBoxAllModule, ButtonModule } from "@syncfusion/ej2-angular-buttons";

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        ButtonModule,
        CheckBoxAllModule,
        TabAllModule,
        GridModule,
        DropDownListAllModule, ReactiveFormsModule, FormsModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Disable editing for a particular row/cell

You can disable the editing for a particular row by using the actionBegin event of Grid based on requestType as beginEdit.

In the below demo, the rows which are having the value for ShipCountry column as “France” is prevented from editing.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';
import { EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar'
               (actionBegin)="actionBegin($event)" height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign= 'Right' editType= 'numericedit'
                     width=120 format= 'C2'></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];

    ngOnInit(): void {
        this.data = data;
        this.editSettings = { allowEditing: true };
        this.toolbar = ['Edit', 'Update', 'Cancel'];
    }

    actionBegin(args) {
        if (args.requestType === 'beginEdit') {
            if (args.rowData.ShipCountry === 'France') {
                args.cancel = true;
            }
        }
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

For batch mode of editing, you can use cellEdit event of Grid. In the below demo, the cells which are having the value as “France” is prevented from editing.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';
import { EditSettingsModel, ToolbarItems, CellEditArgs } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' (cellEdit)="cellEdit($event)" height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign= 'Right'
                     editType= 'numericedit' width=120 format= 'C2'></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];

    ngOnInit(): void {
        this.data = data;
        this.editSettings = { allowEditing: true, mode: 'Batch' };
        this.toolbar = ['Edit', 'Update', 'Cancel'];
    }

    cellEdit(args: CellEditArgs) {
        if (args.value === 'France') {
            args.cancel = true;
        }
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Perform Grid actions by keyboard shortcut keys

Using keyboard shortcuts, Grid performs navigation and actions.

In addition, You can also perform grid actions with custom keyboard shortcuts. This operation has to be achieved outside of the grid with the help of keydown event.

The following example demonstrates on Adding a new row when Enter key is pressed in the grid.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { cascadeData } from './datasource';
import { EditSettingsModel, ToolbarItems, GridComponent } from '@syncfusion/ej2-angular-grids';

@Component({
    selector: 'app-root',
    template: `<ejs-grid  #grid [dataSource]='data' (load)="load()" [editSettings]='editSettings' [toolbar]='toolbar' height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' width=150></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];
    @ViewChild('grid') Grid: GridComponent;
    load() {
        document.getElementsByClassName('e-grid')[0].addEventListener('keydown', this.keyDownHandler.bind(this));
    }

    keyDownHandler(e: any) {
        if (e.keyCode === 13) {
            this.Grid.addRecord();
        }
    }

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

}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Make a cell editable on a single click with batch editing

You can make a cell editable on a single click with batch mode of editing in Grid, by using the editCell method.

Bind the click event for the Grid and in the click event handler call the editCell method, based on the clicked target element.

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

@Component({
    selector: 'app-root',
    template: `<ejs-grid #Grid [dataSource]='data' (click)='click($event)' [editSettings]='editSettings' [toolbar]='toolbar' height='273px'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign= 'Right'
                     editType= 'numericedit' width=120 format= 'C2'></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' editType= 'dropdownedit' width=150></e-column>
                </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data: object[];
    public editSettings: EditSettingsModel;
    public toolbar: ToolbarItems[];
    @ViewChild('Grid') public grid: GridComponent;

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

    click(event: any) {
        if ((event.target as any).classList.contains('e-rowcell')) {
            const index: number = parseInt((event.target as any).getAttribute('Index'), 10);
            const colindex: number = parseInt((event.target as any).getAttribute('aria-colindex'), 10);
            const field: string = this.grid.getColumns()[colindex].field;
            this.grid.editModule.editCell(index, field);
        }
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Sort

Perform single/multi sorting dynamically

You can perform single-column or multi-column sorting dynamically through an external button.

To perform single-column sorting, use the sortColumn method of Grid.

Copied to clipboard
    public SingleSort():void {
      this.grid.sortColumn("OrderID","Descending")
    }

To perform multi-column sorting, you need to push the columns to be sorted into the sortSettings.columns.

Copied to clipboard
    public MultiSort():void {
        this.grid.sortSettings.columns.push({ field: 'CustomerID',  direction: 'Ascending' },{ field: 'ShipName', direction: 'Descending' });
        this.grid.refresh();
    }

In the below demo, click on the corresponding button to perform single-column or multi-column sorting.

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

@Component({
    selector: 'app-root',
    template: `<button ejs-button (click)="SingleSort()"  cssClass="e-flat">Sort <b>OrderID</b> column</button>
               <button ejs-button (click)="MultiSort()"  cssClass="e-flat">Sort <b>CustomerID</b> and <b>ShipName</b> columns</button>
               <div id="GridParent">
                    <ejs-grid #Grid [dataSource]='data' allowSorting='true' [toolbar]='toolbar' height='273px'>
                        <e-columns>
                            <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                            <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                            <e-column field='Freight' headerText='Freight' textAlign= 'Right'
                             editType= 'numericedit' width=120 format= 'C2'></e-column>
                            <e-column field='ShipName' headerText='Ship Name' editType= 'dropdownedit' width=150></e-column>
                        </e-columns>
                    </ejs-grid>
               </div>`
})
export class AppComponent implements OnInit {

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

    ngOnInit(): void {
        this.data = data;
    }
    public SingleSort(): void {
        this.grid.sortColumn('OrderID', 'Descending');
    }
    public MultiSort(): void {
        this.grid.sortSettings.columns.push({ field: 'CustomerID', direction: 'Ascending' },
            { field: 'ShipName', direction: 'Descending' });
        this.grid.refresh();
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Dynamically clear sort for particular/entire sorted columns in Grid

You can clear the sorting for a particular column or the entire sorted columns in Grid dynamically through an external button.

To clear sort for a particular column, you need to splice the particular column from the sortSettings.columns.

Copied to clipboard
    public SingleClearSort():void {
        let column: any = this.grid.sortSettings.columns;
        for(let i=0;i < column.length;i++) {
            if(column[i].field == "OrderID") {
                column.splice(i,1);
                this.grid.refresh();
            }
        }
    }

To clear sorting for all the sorted columns, use the clearSorting method of Grid.

Copied to clipboard
    public MultiClearSort():void {
        this.grid.clearSorting();
    }

In the below demo, click on the corresponding button to clear sort for particular or entire sorted columns in Grid.

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

@Component({
    selector: 'app-root',
    template: `<button ejs-button (click)="SingleClearSort()"  cssClass="e-flat">Clear the sort for <b>OrderID</b> column</button>
               <button ejs-button (click)="MultiClearSort()"  cssClass="e-flat">Clear sorting for entire sorted columns</button>
               <div id="GridParent">
                    <ejs-grid #Grid [dataSource]='data' [sortSettings]='sortOptions' allowSorting='true' [toolbar]='toolbar' height='273px'>
                        <e-columns>
                            <e-column field='OrderID' headerText='Order ID' textAlign='Right' isPrimaryKey='true' width=100></e-column>
                            <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                            <e-column field='Freight' headerText='Freight' textAlign= 'Right'
                             editType= 'numericedit' width=120 format= 'C2'></e-column>
                            <e-column field='ShipName' headerText='Ship Name' editType= 'dropdownedit' width=150></e-column>
                        </e-columns>
                    </ejs-grid>
               </div>`
})
export class AppComponent implements OnInit {

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

    ngOnInit(): void {
        this.data = data;
        this.sortOptions = { columns: [{ field: 'OrderID', direction: 'Ascending' }, { field: 'CustomerID', direction: 'Descending' }] };
    }
    public SingleClearSort(): void {
        const column: any = this.grid.sortSettings.columns;
        for (let i = 0; i < column.length; i++) {
            if (column[i].field === 'OrderID') {
                column.splice(i, 1);
                this.grid.refresh();
            }
        }
    }
    public MultiClearSort(): void {
        this.grid.clearSorting();
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, EditService, ToolbarService, SortService, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { DatePickerAllModule } from '@syncfusion/ej2-angular-calendars';
import { TimePickerModule } from '@syncfusion/ej2-angular-calendars';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { TextBoxModule } from '@syncfusion/ej2-angular-inputs';
import { MultiSelectModule } from '@syncfusion/ej2-angular-dropdowns';
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        DatePickerAllModule,
        FormsModule,
        TimePickerModule,
        FormsModule,
        TextBoxModule,
        MultiSelectModule,
        AutoCompleteModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [EditService, ToolbarService, SortService, PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Foreign Key

Use Edit Template in Foreign Key Column

By default, foreign key column uses dropdown component for editing. You can render other than the dropdown by using the column.edit property. The following example demonstrates the way of using edit template in foreign column.

In the following example, The Employee Name is a foreign key column and while editing, AutoComplete component is rendered instead of DropDownList.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { createElement } from '@syncfusion/ej2-base';
import { ForeignKeyService, EditService, IEditCell, EditSettingsModel, ToolbarService, Column } from '@syncfusion/ej2-angular-grids';
import { DataManager, Query } from '@syncfusion/ej2-data';
import { AutoComplete } from '@syncfusion/ej2-angular-dropdowns';
import { data, employeeData } from './datasource';


@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' [height]='270' [editSettings]='editoption' [toolbar]='toolbar'>
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' isPrimaryKey='true' textAlign='Right' width=100></e-column>
                        <e-column field='EmployeeID' headerText='Employee Name' width=120
                        foreignKeyValue='FirstName' [dataSource]='employeeData' [edit]='edit'></e-column>
                        <e-column field='Freight' headerText='Freight' textAlign='Right' width=80></e-column>
                        <e-column field='ShipCity' headerText='Ship City' width=130></e-column>
                    </e-columns>
                </ejs-grid>`,
    providers: [ForeignKeyService, EditService, ToolbarService]
})
export class AppComponent implements OnInit {

    public data: object[];
    public employeeData: object[];
    public editoption: EditSettingsModel = { allowEditing: true };
    public autoComplete: AutoComplete;
    toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
    public edit: IEditCell = {
        create: () => { // to create input element
            return createElement('input');
        },
        read: () => { // return edited value to update data source
            const EmployeeID = 'EmployeeID';
            const value = new DataManager(employeeData).executeLocal(new Query().where('FirstName', 'equal', this.autoComplete.value));
            return value.length && value[0][EmployeeID]; // to convert foreign key value to local value.
        },
        destroy: () => { // to destroy the custom component.
            this.autoComplete.destroy();
        },
        write: (args: { rowData: object, column: Column, foreignKeyData: object,
             element: HTMLTableCellElement }) => { // to show the value for date picker
            this.autoComplete = new AutoComplete({
                dataSource: employeeData,
                fields: { value: args.column.foreignKeyValue },
                value: args.foreignKeyData[0][args.column.foreignKeyValue]
            });
            this.autoComplete.appendTo(args.element);
        }
    }

    ngOnInit(): void {
        this.data = data;
        this.employeeData = employeeData;
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ForeignKeyService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Customizing filter menu operators list

You can customize the default filter operator list by defining the filterSettings.operators property. The available options are:

  • stringOperator- defines customized string operator list.
  • numberOperator - defines customized number operator list.
  • dateOperator - defines customized date operator list.
  • booleanOperator - defines customized boolean operator list.

In the following sample, we have customized string filter operators.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';
import { FilterSettingsModel } from '@syncfusion/ej2-angular-grids';

@Component({
selector: 'app-root',
template: `<ejs-grid [dataSource]='data' [allowFiltering]='true' [filterSettings]='filterOptions' height='273px'>
            <e-columns>
                <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                <e-column field='ShipName' headerText='Ship Name' width=100></e-column>
            </e-columns>
            </ejs-grid>`
})
export class AppComponent implements OnInit {

public data: object[];
public filterOptions: FilterSettingsModel;

ngOnInit(): void {
    this.data = data;
    this.filterOptions = {
       type: 'Menu',
       operators: {
           stringOperator: [
               { value: 'startsWith', text: 'starts with' },
               { value: 'endsWith', text: 'ends with' },
               { value: 'contains', text: 'contains' }
            ],
        }
    };
}
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, FilterService, PageService} from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';
import { MultiSelectModule, CheckBoxSelectionService,DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns';
import { CheckBoxModule } from '@syncfusion/ej2-angular-buttons';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        MultiSelectModule,
        DropDownListAllModule,
        CheckBoxModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [FilterService, PageService,CheckBoxSelectionService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Customize filter UI in foreign key column

You can create your own filtering UI by using column.filter property. The following example demonstrates the way to create a custom filtering UI in the foreign column.

In the following example, The Employee Name is a foreign key column. DropDownList is rendered using Filter UI.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { createElement } from '@syncfusion/ej2-base';
import { GridComponent, ForeignKeyService, FilterService, IFilter, FilterSettingsModel, Filter } from '@syncfusion/ej2-angular-grids';
import { DataManager } from '@syncfusion/ej2-data';
import { DropDownList } from '@syncfusion/ej2-angular-dropdowns';
import { data, fEmployeeData } from './datasource';

@Component({
selector: 'app-root',
template: `<ejs-grid #grid [dataSource]='data' [height]='315' [allowFiltering]='true'
    [filterSettings]='filteroption'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                    <e-column field='EmployeeID' headerText='Employee Name' width=120
                    foreignKeyValue='FirstName' [dataSource]='employeeData' [filter]='filter'></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign='Right' width=80></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=130  ></e-column>
                </e-columns>
            </ejs-grid>`,
providers: [ForeignKeyService, FilterService]
})
export class AppComponent implements OnInit {

public data: object[];
@ViewChild('grid') public grid: GridComponent;
public employeeData: object[];
public dropInstance: DropDownList;
public filteroption: FilterSettingsModel = { type: 'Menu'};
public filter: IFilter = {
    ui: {
        create: (args: { target: Element, column: object }) => {
            const flValInput: HTMLElement = createElement('input', { className: 'flm-input' });
            args.target.appendChild(flValInput);
            this.dropInstance = new DropDownList({
                dataSource: new DataManager(fEmployeeData),
                fields: { text: 'FirstName', value: 'EmployeeID' },
                placeholder: 'Select a value',
                popupHeight: '200px'
            });
            this.dropInstance.appendTo(flValInput);
        },
        write: (args: {
            column: object, target: Element, parent: any,
            filteredValue: number | string
        }) => {
            this.dropInstance.text = args.filteredValue as string || '';
        },
        read: (args: { target: Element, column: any, operator: string, fltrObj: Filter }) => {
            args.fltrObj.filterByColumn(args.column.field, args.operator, this.dropInstance.text);
        }
    }
};
ngOnInit(): void {
    this.data = data;
    this.employeeData = fEmployeeData;
}
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ForeignKeyService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Use filter bar template in foreign key column

You can use the filter bar template in foreign key column by defining the column.filterBarTemplate property. The following example demonstrates the way to use filter bar template in foreign column.

In the following example, The Employee Name is a foreign key column. This column header shows the custom filter bar template and you can select filter value by using the DropDown options.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { createElement } from '@syncfusion/ej2-base';
import { GridComponent, ForeignKeyService, FilterService, IFilterUI, Column } from '@syncfusion/ej2-angular-grids';
import { DataManager } from '@syncfusion/ej2-data';
import { DropDownList } from '@syncfusion/ej2-angular-dropdowns';
import { data, fEmployeeData } from './datasource';

@Component({
selector: 'app-root',
template: `<ejs-grid #grid [dataSource]='data' [height]='260' [allowFiltering]='true'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                    <e-column field='EmployeeID' headerText='Employee Name' width=120
                    foreignKeyValue='FirstName' [dataSource]='employeeData' [filterBarTemplate]='filter'></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign='Right' width=80></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=130  ></e-column>
                </e-columns>
            </ejs-grid>`,
providers: [ForeignKeyService, FilterService]
})
export class AppComponent implements OnInit {

public data: object[];
@ViewChild('grid') public grid: GridComponent;
public employeeData: object[];
public filter: IFilterUI = {
    create: (args: { element: Element, column: Column }) => {
        return createElement('input', { className: 'flm-input' });
    },
    write: (args: { element: Element, column: Column }) => {
        fEmployeeData.splice(0, 0, {FirstName: 'All'}); // for clear filtering
        const dropInstance: DropDownList = new DropDownList({
            dataSource: new DataManager(fEmployeeData),
            fields: { text: 'FirstName' },
            placeholder: 'Select a value',
            popupHeight: '200px',
            index: 0,
            change: (e) => {
                if (e.value !== 'All') {
                    this.grid.filterByColumn('EmployeeID', 'equal', e.value);
                } else {
                    this.grid.removeFilteredColsByField('EmployeeID');
                }
            }
        });
        dropInstance.appendTo(args.element as HTMLTableCellElement);
    }
};
ngOnInit(): void {
    this.data = data;
    this.employeeData = fEmployeeData;
}
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ForeignKeyService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Perform aggregation in Foreign Key Column

Default aggregations are not supported in a foreign key column. You can achieve aggregation for the foreign key column by using custom the aggregates. The following example demonstrates the way to achieve aggregation in foreign key column.

In the following example, The Employee Name is a foreign key column and the aggregation for the foreign column was calculated in customAggregateFn.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { ForeignKeyService, AggregateService, getForeignData, CustomSummaryType,
 AggregateColumnModel, GridComponent } from '@syncfusion/ej2-angular-grids';
import { data, employeeData } from './datasource';
import { getValue } from '@syncfusion/ej2-base';

@Component({
selector: 'app-root',
template: `<ejs-grid #grid [dataSource]='data' [height]='280'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                    <e-column field='EmployeeID' headerText='Employee Name' width=120
                     foreignKeyValue='FirstName' [dataSource]='employeeData'></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign='Right' width=80></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=130  ></e-column>
                </e-columns>
                <e-aggregates>
                    <e-aggregate>
                        <e-columns>
                            <e-column field="EmployeeID" type="Custom" [customAggregate]= 'customAggregateFn'>
                                <ng-template #footerTemplate let-data>
                                    Count of Margaret:  {{data.Custom}}
                                </ng-template>
                            </e-column>
                        </e-columns>
                    </e-aggregate>
                </e-aggregates>
            </ejs-grid>`,
providers: [ForeignKeyService, AggregateService]
})
export class AppComponent implements OnInit {

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

// Custom Aggregate function for foreign column
public customAggregateFn: CustomSummaryType = (data1: any, column: AggregateColumnModel) => {
    return data1.result.filter((dObj: object) => {
        return getValue('FirstName', getForeignData(this.grid.getColumnByField(column.field), dObj)[0]) === 'Margaret';
    }).length;
}

ngOnInit(): void {
    this.data = data;
    this.employeeData = employeeData;
}
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ForeignKeyService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Bind foreign key dataSource on dropdown edit

When editing, you can bind foreign key datasource to a dropdown list by using column.dataSource property.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { ForeignKeyService, EditSettingsModel, ToolbarItems, EditService, ToolbarService } from '@syncfusion/ej2-angular-grids';
import { data, employeeData } from './datasource';

@Component({
selector: 'app-root',
template: `<ejs-grid #grid [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar' [height]='315'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=100></e-column>
                    <e-column field='EmployeeID' headerText='Employee Name' width=120
                    foreignKeyValue='FirstName' [dataSource]='employeeData'></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign='Right' width=80></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=130  ></e-column>
                </e-columns>
            </ejs-grid>`,
providers: [ForeignKeyService, EditService, ToolbarService]
})
export class AppComponent implements OnInit {

public data: object[];
public employeeData: object[];
public editSettings: EditSettingsModel;
public toolbar: ToolbarItems[];

ngOnInit(): void {
    this.data = data;
    this.employeeData = employeeData;
    this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true };
    this.toolbar = ['Add', 'Edit', 'Delete', 'Update', 'Cancel'];
}
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ForeignKeyService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ForeignKeyService]
})
export class AppModule { }
Copied to clipboard
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0,
        Employee: {
            EmployeeID: 1
        },
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1,
        Employee: {
            'EmployeeID': 2
        },
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0,
        Employee: {
            EmployeeID: 3
        },
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0,
        Employee: {
            EmployeeID: 4
        },
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0,
        Employee: {
            EmployeeID: 5
        }
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];

export let employeeData: Object[] = [{
    'EmployeeID': 1,
    'LastName': 'Davolio',
    'FirstName': 'Nancy',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-664743600000),
    'HireDate': new Date(704692800000),
    'Address': '507 - 20th Ave. E.\r\nApt. 2A',
    'City': 'Seattle',
    'Region': 'WA',
    'PostalCode': '98122',
    'Country': 'USA',
    'HomePhone': '(206) 555-9857',
    'Extension': '5467',
    'Photo': { 'Length': 21626 },

    'Notes': 'Education includes a BA in psychology from Colorado State University in 1970.  She also completed\
    \'The Art of the Cold Call.\'  Nancy is a member of Toastmasters International.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 2,
    'LastName': 'Fuller',
    'FirstName': 'Andrew',
    'Title': 'Vice President, Sales',
    'TitleOfCourtesy': 'Dr.',
    'BirthDate': new Date(-563828400000),
    'HireDate': new Date(713764800000),
    'Address': '908 W. Capital Way',
    'City': 'Tacoma',
    'Region': 'WA',
    'PostalCode': '98401',
    'Country': 'USA',
    'HomePhone': '(206) 555-9482',
    'Extension': '3457',
    'Photo': { 'Length': 21626 },

    'Notes': 'Andrew received his BTS commercial in 1974 and a Ph.D. in international marketing from the University of \
    Dallas in 1981.  He is fluent in French and Italian and reads German.  He joined the company as a sales representative, \
    was promoted to sales manager in January 1992 and to vice president of sales in March 1993.  Andrew is a member of the \
    Sales Management Roundtable, the Seattle Chamber of Commerce, and the Pacific Rim Importers Association.',
    'ReportsTo': 0,
    'PhotoPath': 'http://accweb/emmployees/fuller.bmp'
},
{
    'EmployeeID': 3,
    'LastName': 'Leverling',
    'FirstName': 'Janet',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-200088000000),
    'HireDate': new Date(702104400000),
    'Address': '722 Moss Bay Blvd.',
    'City': 'Kirkland',
    'Region': 'WA',
    'PostalCode': '98033',
    'Country': 'USA',
    'HomePhone': '(206) 555-3412',
    'Extension': '3355',
    'Photo': { 'Length': 21722 },

    'Notes': 'Janet has a BS degree in chemistry from Boston College (1984). \
     She has also completed a certificate program in food retailing management.\
     Janet was hired as a sales associate in 1991 and promoted to sales representative in February 1992.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/leverling.bmp'
},
{
    'EmployeeID': 4,
    'LastName': 'Peacock',
    'FirstName': 'Margaret',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mrs.',
    'BirthDate': new Date(-1018814400000),
    'HireDate': new Date(736401600000),
    'Address': '4110 Old Redmond Rd.',
    'City': 'Redmond',
    'Region': 'WA',
    'PostalCode': '98052',
    'Country': 'USA',
    'HomePhone': '(206) 555-8122',
    'Extension': '5176',
    'Photo': { 'Length': 21626 },

    'Notes': 'Margaret holds a BA in English literature from Concordia College (1958) and an MA from the American \
    Institute of Culinary Arts (1966).  She was assigned to the London office temporarily from July through November 1992.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/peacock.bmp'
},
{
    'EmployeeID': 5,
    'LastName': 'Buchanan',
    'FirstName': 'Steven',
    'Title': 'Sales Manager',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-468010800000),
    'HireDate': new Date(750830400000),
    'Address': '14 Garrett Hill',
    'City': 'London',
    'Region': null,
    'PostalCode':
    'SW1 8JR',
    'Country': 'UK',
    'HomePhone': '(71) 555-4848',
    'Extension': '3453',
    'Photo': { 'Length': 21626 },

    'Notes': 'Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976.  Upon joining the company as \
    a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent \
    post in London.  He was promoted to sales manager in March 1993.  Mr. Buchanan has completed the courses \'Successful \
    Telemarketing\' and \'International Sales Management.\'  He is fluent in French.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/buchanan.bmp'
},
{
    'EmployeeID': 6,
    'LastName': 'Suyama',
    'FirstName': 'Michael',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-205185600000),
    'HireDate': new Date(750830400000),
    'Address': 'Coventry House\r\nMiner Rd.',
    'City': 'London',
    'Region': null,
    'PostalCode': 'EC2 7JR',
    'Country': 'UK',
    'HomePhone': '(71) 555-7773',
    'Extension': '428',
    'Photo': { 'Length': 21626 },

    'Notes': 'Michael is a graduate of Sussex University (MA, economics, 1983) and the University of California at Los Angeles \
    (MBA, marketing, 1986).  He has also taken the courses \'Multi-Cultural Selling\' and \'Time Management for the Sales Professional.\'  \
    He is fluent in Japanese and can read and write French, Portuguese, and Spanish.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 7,
    'LastName': 'King',
    'FirstName': 'Robert',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-302731200000),
    'HireDate': new Date(757486800000),
    'Address': 'Edgeham Hollow\r\nWinchester Way',
    'City': 'London',
    'Region': null,
    'PostalCode': 'RG1 9SP',
    'Country': 'UK',
    'HomePhone': '(71) 555-5598',
    'Extension': '465',
    'Photo': { 'Length': 21626 },

    'Notes': 'Robert King served in the Peace Corps and traveled extensively before completing his degree in English at the \
    University of Michigan in 1992, the year he joined the company.  After completing a course entitled \'Selling in Europe,\' \
    he was transferred to the London office in March 1993.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 8,
    'LastName': 'Callahan',
    'FirstName': 'Laura',
    'Title': 'Inside Sales Coordinator',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-377982000000),
    'HireDate': new Date(762843600000),
    'Address': '4726 - 11th Ave. N.E.',
    'City': 'Seattle',
    'Region': 'WA',
    'PostalCode': '98105',
    'Country': 'USA',
    'HomePhone': '(206) 555-1189',
    'Extension': '2344',
    'Photo': { 'Length': 21626 },

    'Notes': 'Laura received a BA in psychology from the University of Washington.  She has also completed a course in business \
    French.  She reads and writes French.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 9,
    'LastName': 'Dodsworth',
    'FirstName': 'Anne',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-123966000000),
    'HireDate': new Date(784875600000),
    'Address': '7 Houndstooth Rd.',
    'City': 'London',
    'Region': null,
    'PostalCode': 'WG2 7LT',
    'Country': 'UK',
    'HomePhone': '(71) 555-4444',
    'Extension': '452',
    'Photo': { 'Length': 21626 },

    'Notes': 'Anne has a BA degree in English from St. Lawrence College.  She is fluent in French and German.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
}];

export let fEmployeeData: Object[] = [{
    'EmployeeID': 1,
    'LastName': 'Davolio',
    'FirstName': 'Nancy',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-664743600000),
    'HireDate': new Date(704692800000),
    'Address': '507 - 20th Ave. E.\r\nApt. 2A',
    'City': 'Seattle',
    'Region': 'WA',
    'PostalCode': '98122',
    'Country': 'USA',
    'HomePhone': '(206) 555-9857',
    'Extension': '5467',
    'Photo': { 'Length': 21626 },

    'Notes': 'Education includes a BA in psychology from Colorado State University in 1970.  She also completed\
    \'The Art of the Cold Call.\'  Nancy is a member of Toastmasters International.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},

{
    'EmployeeID': 3,
    'LastName': 'Leverling',
    'FirstName': 'Janet',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-200088000000),
    'HireDate': new Date(702104400000),
    'Address': '722 Moss Bay Blvd.',
    'City': 'Kirkland',
    'Region': 'WA',
    'PostalCode': '98033',
    'Country': 'USA',
    'HomePhone': '(206) 555-3412',
    'Extension': '3355',
    'Photo': { 'Length': 21722 },

    'Notes': 'Janet has a BS degree in chemistry from Boston College (1984). \
     She has also completed a certificate program in food retailing management.\
     Janet was hired as a sales associate in 1991 and promoted to sales representative in February 1992.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/leverling.bmp'
},
{
    'EmployeeID': 4,
    'LastName': 'Peacock',
    'FirstName': 'Margaret',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mrs.',
    'BirthDate': new Date(-1018814400000),
    'HireDate': new Date(736401600000),
    'Address': '4110 Old Redmond Rd.',
    'City': 'Redmond',
    'Region': 'WA',
    'PostalCode': '98052',
    'Country': 'USA',
    'HomePhone': '(206) 555-8122',
    'Extension': '5176',
    'Photo': { 'Length': 21626 },

    'Notes': 'Margaret holds a BA in English literature from Concordia College (1958) and an MA from the American \
    Institute of Culinary Arts (1966).  She was assigned to the London office temporarily from July through November 1992.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/peacock.bmp'
},
{
    'EmployeeID': 5,
    'LastName': 'Buchanan',
    'FirstName': 'Steven',
    'Title': 'Sales Manager',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-468010800000),
    'HireDate': new Date(750830400000),
    'Address': '14 Garrett Hill',
    'City': 'London',
    'Region': null,
    'PostalCode':
    'SW1 8JR',
    'Country': 'UK',
    'HomePhone': '(71) 555-4848',
    'Extension': '3453',
    'Photo': { 'Length': 21626 },

    'Notes': 'Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976.  Upon joining the company as \
    a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent \
    post in London.  He was promoted to sales manager in March 1993.  Mr. Buchanan has completed the courses \'Successful \
    Telemarketing\' and \'International Sales Management.\'  He is fluent in French.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/buchanan.bmp'
},
{
    'EmployeeID': 6,
    'LastName': 'Suyama',
    'FirstName': 'Michael',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Mr.',
    'BirthDate': new Date(-205185600000),
    'HireDate': new Date(750830400000),
    'Address': 'Coventry House\r\nMiner Rd.',
    'City': 'London',
    'Region': null,
    'PostalCode': 'EC2 7JR',
    'Country': 'UK',
    'HomePhone': '(71) 555-7773',
    'Extension': '428',
    'Photo': { 'Length': 21626 },
    'Notes': 'Michael is a graduate of Sussex University (MA, economics, 1983) and the University of California at Los Angeles \
    (MBA, marketing, 1986).  He has also taken the courses \'Multi-Cultural Selling\' and \'Time Management for the Sales Professional.\'  \
    He is fluent in Japanese and can read and write French, Portuguese, and Spanish.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 8,
    'LastName': 'Callahan',
    'FirstName': 'Laura',
    'Title': 'Inside Sales Coordinator',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-377982000000),
    'HireDate': new Date(762843600000),
    'Address': '4726 - 11th Ave. N.E.',
    'City': 'Seattle',
    'Region': 'WA',
    'PostalCode': '98105',
    'Country': 'USA',
    'HomePhone': '(206) 555-1189',
    'Extension': '2344',
    'Photo': { 'Length': 21626 },

    'Notes': 'Laura received a BA in psychology from the University of Washington.  She has also completed a course in business \
    French.  She reads and writes French.',
    'ReportsTo': 2,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
},
{
    'EmployeeID': 9,
    'LastName': 'Dodsworth',
    'FirstName': 'Anne',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-123966000000),
    'HireDate': new Date(784875600000),
    'Address': '7 Houndstooth Rd.',
    'City': 'London',
    'Region': null,
    'PostalCode': 'WG2 7LT',
    'Country': 'UK',
    'HomePhone': '(71) 555-4444',
    'Extension': '452',
    'Photo': { 'Length': 21626 },

    'Notes': 'Anne has a BA degree in English from St. Lawrence College.  She is fluent in French and German.',
    'ReportsTo': 5,
    'PhotoPath': 'http://accweb/emmployees/davolio.bmp'
}];

export const customerData: Object[] = [
    {
        "CustomerID": "ALFKI",
        "ContactName": "Maria ",
        "CompanyName": "Alfreds Futterkiste",
        "Address": "Obere Str. 57",
        "Country": "Germany"
    },
    {
        "CustomerID": "ANATR",
        "ContactName": "Ana Trujillo",
        "CompanyName": "Ana Trujillo Emparedados y helados",
        "Address": "Avda. de la Constitución 2222",
        "Country": "Mexico"
    },
    {
        "CustomerID": "ANTON",
        "ContactName": "Antonio Moreno",
        "CompanyName": "Antonio Moreno Taquería",
        "Address": "Mataderos  2312",
        "Country": "Mexico"
    },
    {
        "CustomerID": "AROUT",
        "ContactName": "Thomas Hardy",
        "CompanyName": "Around the Horn",
        "Address": "120 Hanover Sq.",
        "Country": "UK"
    },
    {
        "CustomerID": "BERGS",
        "ContactName": "Christina Berglund",
        "CompanyName": "Berglunds snabbköp",
        "Address": "Berguvsvägen  8",
        "Country": "Sweden"
    },
    {
        "CustomerID": "BLAUS",
        "ContactName": "Hanna Moos",
        "CompanyName": "Blauer See Delikatessen",
        "Address": "Forsterstr. 57",
        "Country": "Germany"
    },
    {
        "CustomerID": "BLONP",
        "ContactName": "Frédérique Citeaux",
        "CompanyName": "Blondesddsl père et fils",
        "Address": "24, place Kléber",
        "Country": "France"
    },
    {
        "CustomerID": "BOLID",
        "ContactName": "Martín Sommer",
        "CompanyName": "Bólido Comidas preparadas",
        "Address": "C/ Araquil, 67",
        "Country": "Spain"
    },
    {
        "CustomerID": "BONAP",
        "ContactName": "Laurence Lebihan",
        "CompanyName": "Bon app'",
        "Address": "12, rue des Bouchers",
        "Country": "France"
    },
    {
        "CustomerID": "BOTTM",
        "ContactName": "Elizabeth Lincoln",
        "CompanyName": "Bottom-Dollar Markets",
        "Address": "23 Tsawassen Blvd.",
        "Country": "Canada"
    },
    {
        "CustomerID": "BSBEV",
        "ContactName": "Victoria Ashworth",
        "CompanyName": "B's Beverages",
        "Address": "Fauntleroy Circus",
        "Country": "UK"
    },
    {
        "CustomerID": "CACTU",
        "ContactName": "Patricio Simpson",
        "CompanyName": "Cactus Comidas para llevar",
        "Address": "Cerrito 333",
        "Country": "Argentina"
    },
    {
        "CustomerID": "CENTC",
        "ContactName": "Francisco Chang",
        "CompanyName": "Centro comercial Moctezuma",
        "Address": "Sierras de Granada 9993",
        "Country": "Mexico"
    },
    {
        "CustomerID": "CHOPS",
        "ContactName": "Yang Wang",
        "CompanyName": "Chop-suey Chinese",
        "Address": "Hauptstr. 29",
        "Country": "Switzerland"
    },
    {
        "CustomerID": "COMMI",
        "ContactName": "Pedro Afonso",
        "CompanyName": "Comércio Mineiro",
        "Address": "Av. dos Lusíadas, 23",
        "Country": "Brazil"
    },
    {
        "CustomerID": "CONSH",
        "ContactName": "Elizabeth Brown",
        "CompanyName": "Consolidated Holdings",
        "Address": "Berkeley Gardens 12  Brewery",
        "Country": "UK"
    },
    {
        "CustomerID": "DRACD",
        "ContactName": "Sven Ottlieb",
        "CompanyName": "Drachenblut Delikatessen",
        "Address": "Walserweg 21",
        "Country": "Germany"
    },
    {
        "CustomerID": "DUMON",
        "ContactName": "Janine Labrune",
        "CompanyName": "Du monde entier",
        "Address": "67, rue des Cinquante Otages",
        "Country": "France"
    },
    {
        "CustomerID": "EASTC",
        "ContactName": "Ann Devon",
        "CompanyName": "Eastern Connection",
        "Address": "35 King George",
        "Country": "UK"
    },
    {
        "CustomerID": "ERNSH",
        "ContactName": "Roland Mendel",
        "CompanyName": "Ernst Handel",
        "Address": "Kirchgasse 6",
        "Country": "Austria"
    },
    {
        "CustomerID": "FAMIA",
        "ContactName": "Aria Cruz",
        "CompanyName": "Familia Arquibaldo",
        "Address": "Rua Orós, 92",
        "Country": "Brazil"
    },
    {
        "CustomerID": "FISSA",
        "ContactName": "Diego Roel",
        "CompanyName": "FISSA Fabrica Inter. Salchichas S.A.",
        "Address": "C/ Moralzarzal, 86",
        "Country": "Spain"
    },
    {
        "CustomerID": "FOLIG",
        "ContactName": "Martine Rancé",
        "CompanyName": "Folies gourmandes",
        "Address": "184, chaussée de Tournai",
        "Country": "France"
    },
    {
        "CustomerID": "FOLKO",
        "ContactName": "Maria Larsson",
        "CompanyName": "Folk och fä HB",
        "Address": "Åkergatan 24",
        "Country": "Sweden"
    },
    {
        "CustomerID": "FRANK",
        "ContactName": "Peter Franken",
        "CompanyName": "Frankenversand",
        "Address": "Berliner Platz 43",
        "Country": "Germany"
    },
    {
        "CustomerID": "FRANR",
        "ContactName": "Carine Schmitt",
        "CompanyName": "France restauration",
        "Address": "54, rue Royale",
        "Country": "France"
    },
    {
        "CustomerID": "FRANS",
        "ContactName": "Paolo Accorti",
        "CompanyName": "Franchi S.p.A.",
        "Address": "Via Monte Bianco 34",
        "Country": "Italy"
    },
    {
        "CustomerID": "FURIB",
        "ContactName": "Lino Rodriguez",
        "CompanyName": "Furia Bacalhau e Frutos do Mar",
        "Address": "Jardim das rosas n. 32",
        "Country": "Portugal"
    },
    {
        "CustomerID": "GALED",
        "ContactName": "Eduardo Saavedra",
        "CompanyName": "Galería del gastrónomo",
        "Address": "Rambla de Cataluña, 23",
        "Country": "Spain"
    },
    {
        "CustomerID": "GODOS",
        "ContactName": "José Pedro Freyre",
        "CompanyName": "Godos Cocina Típica",
        "Address": "C/ Romero, 33",
        "Country": "Spain"
    },
    {
        "CustomerID": "GOURL",
        "ContactName": "André Fonseca",
        "CompanyName": "Gourmet Lanchonetes",
        "Address": "Av. Brasil, 442",
        "Country": "Brazil"
    },
    {
        "CustomerID": "GREAL",
        "ContactName": "Howard Snyder",
        "CompanyName": "Great Lakes Food Market",
        "Address": "2732 Baker Blvd.",
        "Country": "USA"
    },
    {
        "CustomerID": "GROSR",
        "ContactName": "Manuel Pereira",
        "CompanyName": "GROSELLA-Restaurante",
        "Address": "5ª Ave. Los Palos Grandes",
        "Country": "Venezuela"
    },
    {
        "CustomerID": "HANAR",
        "ContactName": "Mario Pontes",
        "CompanyName": "Hanari Carnes",
        "Address": "Rua do Paço, 67",
        "Country": "Brazil"
    },
    {
        "CustomerID": "HILAA",
        "ContactName": "Carlos Hernández",
        "CompanyName": "HILARION-Abastos",
        "Address": "Carrera 22 con Ave. Carlos Soublette #8-35",
        "Country": "Venezuela"
    },
    {
        "CustomerID": "HUNGC",
        "ContactName": "Yoshi Latimer",
        "CompanyName": "Hungry Coyote Import Store",
        "Address": "City Center Plaza 516 Main St.",
        "Country": "USA"
    },
    {
        "CustomerID": "HUNGO",
        "ContactName": "Patricia McKenna",
        "CompanyName": "Hungry Owl All-Night Grocers",
        "Address": "8 Johnstown Road",
        "Country": "Ireland"
    },
    {
        "CustomerID": "ISLAT",
        "ContactName": "Helen Bennett",
        "CompanyName": "Island Trading",
        "Address": "Garden House Crowther Way",
        "Country": "UK"
    },
    {
        "CustomerID": "KOENE",
        "ContactName": "Philip Cramer",
        "CompanyName": "Königlich Essen",
        "Address": "Maubelstr. 90",
        "Country": "Germany"
    },
    {
        "CustomerID": "LACOR",
        "ContactName": "Daniel Tonini",
        "CompanyName": "La corne d'abondance",
        "Address": "67, avenue de l'Europe",
        "Country": "France"
    },
    {
        "CustomerID": "LAMAI",
        "ContactName": "Annette Roulet",
        "CompanyName": "La maison d'Asie",
        "Address": "1 rue Alsace-Lorraine",
        "Country": "France"
    },
    {
        "CustomerID": "LAUGB",
        "ContactName": "Yoshi Tannamuri",
        "CompanyName": "Laughing Bacchus Wine Cellars",
        "Address": "1900 Oak St.",
        "Country": "Canada"
    },
    {
        "CustomerID": "LAZYK",
        "ContactName": "John Steel",
        "CompanyName": "Lazy K Kountry Store",
        "Address": "12 Orchestra Terrace",
        "Country": "USA"
    },
    {
        "CustomerID": "LEHMS",
        "ContactName": "Renate Messner",
        "CompanyName": "Lehmanns Marktstand",
        "Address": "Magazinweg 7",
        "Country": "Germany"
    },
    {
        "CustomerID": "LETSS",
        "ContactName": "Jaime Yorres",
        "CompanyName": "Let's Stop N Shop",
        "Address": "87 Polk St. Suite 5",
        "Country": "USA"
    },
    {
        "CustomerID": "LILAS",
        "ContactName": "Carlos González",
        "CompanyName": "LILA-Supermercado",
        "Address": "Carrera 52 con Ave. Bolívar #65-98 Llano Largo",
        "Country": "Venezuela"
    },
    {
        "CustomerID": "LINOD",
        "ContactName": "Felipe Izquierdo",
        "CompanyName": "LINO-Delicateses",
        "Address": "Ave. 5 de Mayo Porlamar",
        "Country": "Venezuela"
    },
    {
        "CustomerID": "LONEP",
        "ContactName": "Fran Wilson",
        "CompanyName": "Lonesome Pine Restaurant",
        "Address": "89 Chiaroscuro Rd.",
        "Country": "USA"
    },
    {
        "CustomerID": "MAGAA",
        "ContactName": "Giovanni Rovelli",
        "CompanyName": "Magazzini Alimentari Riuniti",
        "Address": "Via Ludovico il Moro 22",
        "Country": "Italy"
    },
    {
        "CustomerID": "MAISD",
        "ContactName": "Catherine Dewey",
        "CompanyName": "Maison Dewey",
        "Address": "Rue Joseph-Bens 532",
        "Country": "Belgium"
    },
    {
        "CustomerID": "MEREP",
        "ContactName": "Jean Fresnière",
        "CompanyName": "Mère Paillarde",
        "Address": "43 rue St. Laurent",
        "Country": "Canada"
    },
    {
        "CustomerID": "MORGK",
        "ContactName": "Alexander Feuer",
        "CompanyName": "Morgenstern Gesundkost",
        "Address": "Heerstr. 22",
        "Country": "Germany"
    },
    {
        "CustomerID": "NORTS",
        "ContactName": "Simon Crowther",
        "CompanyName": "North/South",
        "Address": "South House 300 Queensbridge",
        "Country": "UK"
    },
    {
        "CustomerID": "OCEAN",
        "ContactName": "Yvonne Moncada",
        "CompanyName": "Océano Atlántico Ltda.",
        "Address": "Ing. Gustavo Moncada 8585 Piso 20-A",
        "Country": "Argentina"
    },
    {
        "CustomerID": "OLDWO",
        "ContactName": "Rene Phillips",
        "CompanyName": "Old World Delicatessen",
        "Address": "2743 Bering St.",
        "Country": "USA"
    },
    {
        "CustomerID": "OTTIK",
        "ContactName": "Henriette Pfalzheim",
        "CompanyName": "Ottilies Käseladen",
        "Address": "Mehrheimerstr. 369",
        "Country": "Germany"
    },
    {
        "CustomerID": "PARIS",
        "ContactName": "Marie Bertrand",
        "CompanyName": "Paris spécialités",
        "Address": "265, boulevard Charonne",
        "Country": "France"
    },
    {
        "CustomerID": "PERIC",
        "ContactName": "Guillermo Fernández",
        "CompanyName": "Pericles Comidas clásicas",
        "Address": "Calle Dr. Jorge Cash 321",
        "Country": "Mexico"
    },
    {
        "CustomerID": "PICCO",
        "ContactName": "Georg Pipps",
        "CompanyName": "Piccolo und mehr",
        "Address": "Geislweg 14",
        "Country": "Austria"
    },
    {
        "CustomerID": "PRINI",
        "ContactName": "Isabel de Castro",
        "CompanyName": "Princesa Isabel Vinhos",
        "Address": "Estrada da saúde n. 58",
        "Country": "Portugal"
    },
    {
        "CustomerID": "QUEDE",
        "ContactName": "Bernardo Batista",
        "CompanyName": "Que Delícia",
        "Address": "Rua da Panificadora, 12",
        "Country": "Brazil"
    },
    {
        "CustomerID": "QUEEN",
        "ContactName": "Lúcia Carvalho",
        "CompanyName": "Queen Cozinha",
        "Address": "Alameda dos Canàrios, 891",
        "Country": "Brazil"
    },
    {
        "CustomerID": "QUICK",
        "ContactName": "Horst Kloss",
        "CompanyName": "QUICK-Stop",
        "Address": "Taucherstraße 10",
        "Country": "Germany"
    },
    {
        "CustomerID": "RANCH",
        "ContactName": "Sergio Gutiérrez",
        "CompanyName": "Rancho grande",
        "Address": "Av. del Libertador 900",
        "Country": "Argentina"
    },
    {
        "CustomerID": "RATTC",
        "ContactName": "Paula Wilson",
        "CompanyName": "Rattlesnake Canyon Grocery",
        "Address": "2817 Milton Dr.",
        "Country": "USA"
    },
    {
        "CustomerID": "REGGC",
        "ContactName": "Maurizio Moroni",
        "CompanyName": "Reggiani Caseifici",
        "Address": "Strada Provinciale 124",
        "Country": "Italy"
    },
    {
        "CustomerID": "RICAR",
        "ContactName": "Janete Limeira",
        "CompanyName": "Ricardo Adocicados",
        "Address": "Av. Copacabana, 267",
        "Country": "Brazil"
    },
    {
        "CustomerID": "RICSU",
        "ContactName": "Michael Holz",
        "CompanyName": "Richter Supermarkt",
        "Address": "Grenzacherweg 237",
        "Country": "Switzerland"
    },
    {
        "CustomerID": "ROMEY",
        "ContactName": "Alejandra Camino",
        "CompanyName": "Romero y tomillo",
        "Address": "Gran Vía, 1",
        "Country": "Spain"
    },
    {
        "CustomerID": "SANTG",
        "ContactName": "Jonas Bergulfsen",
        "CompanyName": "Santé Gourmet",
        "Address": "Erling Skakkes gate 78",
        "Country": "Norway"
    },
    {
        "CustomerID": "SAVEA",
        "ContactName": "Jose Pavarotti",
        "CompanyName": "Save-a-lot Markets",
        "Address": "187 Suffolk Ln.",
        "Country": "USA"
    },
    {
        "CustomerID": "SEVES",
        "ContactName": "Hari Kumar",
        "CompanyName": "Seven Seas Imports",
        "Address": "90 Wadhurst Rd.",
        "Country": "UK"
    },
    {
        "CustomerID": "SIMOB",
        "ContactName": "Jytte Petersen",
        "CompanyName": "Simons bistro",
        "Address": "Vinbæltet 34",
        "Country": "Denmark"
    },
    {
        "CustomerID": "SPECD",
        "ContactName": "Dominique Perrier",
        "CompanyName": "Spécialités du monde",
        "Address": "25, rue Lauriston",
        "Country": "France"
    },
    {
        "CustomerID": "SPLIR",
        "ContactName": "Art Braunschweiger",
        "CompanyName": "Split Rail Beer & Ale",
        "Address": "P.O. Box 555",
        "Country": "USA"
    },
    {
        "CustomerID": "SUPRD",
        "ContactName": "Pascale Cartrain",
        "CompanyName": "Suprêmes délices",
        "Address": "Boulevard Tirou, 255",
        "Country": "Belgium"
    },
    {
        "CustomerID": "THEBI",
        "ContactName": "Liz Nixon",
        "CompanyName": "The Big Cheese",
        "Address": "89 Jefferson Way Suite 2",
        "Country": "USA"
    },
    {
        "CustomerID": "THECR",
        "ContactName": "Liu Wong",
        "CompanyName": "The Cracker Box",
        "Address": "55 Grizzly Peak Rd.",
        "Country": "USA"
    },
    {
        "CustomerID": "TOMSP",
        "ContactName": "Karin Josephs",
        "CompanyName": "Toms Spezialitäten",
        "Address": "Luisenstr. 48",
        "Country": "Germany"
    },
    {
        "CustomerID": "TORTU",
        "ContactName": "Miguel Angel Paolino",
        "CompanyName": "Tortuga Restaurante",
        "Address": "Avda. Azteca 123",
        "Country": "Mexico"
    },
    {
        "CustomerID": "TRADH",
        "ContactName": "Anabela Domingues",
        "CompanyName": "Tradição Hipermercados",
        "Address": "Av. Inês de Castro, 414",
        "Country": "Brazil"
    },
    {
        "CustomerID": "TRAIH",
        "ContactName": "Helvetius Nagy",
        "CompanyName": "Trail's Head Gourmet Provisioners",
        "Address": "722 DaVinci Blvd.",
        "Country": "USA"
    },
    {
        "CustomerID": "VAFFE",
        "ContactName": "Palle Ibsen",
        "CompanyName": "Vaffeljernet",
        "Address": "Smagsloget 45",
        "Country": "Denmark"
    },
    {
        "CustomerID": "VICTE",
        "ContactName": "Mary Saveley",
        "CompanyName": "Victuailles en stock",
        "Address": "2, rue du Commerce",
        "Country": "France"
    },
    {
        "CustomerID": "VINET",
        "ContactName": "Paul Henriot",
        "CompanyName": "Vins et alcools Chevalier",
        "Address": "59 rue de l'Abbaye",
        "Country": "France"
    },
    {
        "CustomerID": "WANDK",
        "ContactName": "Rita Müller",
        "CompanyName": "Die Wandernde Kuh",
        "Address": "Adenauerallee 900",
        "Country": "Germany"
    },
    {
        "CustomerID": "WARTH",
        "ContactName": "Pirkko Koskitalo",
        "CompanyName": "Wartian Herkku",
        "Address": "Torikatu 38",
        "Country": "Finland"
    },
    {
        "CustomerID": "WELLI",
        "ContactName": "Paula Parente",
        "CompanyName": "Wellington Importadora",
        "Address": "Rua do Mercado, 12",
        "Country": "Brazil"
    },
    {
        "CustomerID": "WHITC",
        "ContactName": "Karl Jablonski",
        "CompanyName": "White Clover Markets",
        "Address": "305 - 14th Ave. S. Suite 3B",
        "Country": "USA"
    },
    {
        "CustomerID": "WILMK",
        "ContactName": "Matti Karttunen",
        "CompanyName": "Wilman Kala",
        "Address": "Keskuskatu 45",
        "Country": "Finland"
    },
    {
        "CustomerID": "WOLZA",
        "ContactName": "Zbyszek Piestrzeniewicz",
        "CompanyName": "Wolski  Zajazd",
        "Address": "ul. Filtrowa 68",
        "Country": "Poland"
    }
];

let order = JSON.stringify([
    {
       "OrderID":10248,
       "CustomerID":"VINET",
       "CustomerName": "Maria ",
       "OrderDate":"1996-07-04T00:00:00.000Z",
       "ShippedDate":"1996-07-16T00:00:00.000Z",
       "Freight":32.38,
       "ShipName":"Vins et alcools Chevalier",
       "ShipAddress":"59 rue de l'Abbaye",
       "ShipCity":"Reims",
       "ShipRegion":null,
       "ShipCountry":"France",
       'EmployeeID': 3
    },
    {
       "OrderID":10249,
       "CustomerID":"TOMSP",
       "CustomerName": "Ana Trujillo",
       "OrderDate":"1996-07-05T00:00:00.000Z",
       "ShippedDate":"1996-07-10T00:00:00.000Z",
       "Freight":11.61,
       "ShipName":"Toms Spezialitäten",
       "ShipAddress":"Luisenstr. 48",
       "ShipCity":"Münster",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 5
    },
    {
       "OrderID":10250,
       "CustomerID":"HANAR",
       "CustomerName": "Antonio Moreno",
       "OrderDate":"1996-07-08T00:00:00.000Z",
       "ShippedDate":"1996-07-12T00:00:00.000Z",
       "Freight":65.83,
       "ShipName":"Hanari Carnes",
       "ShipAddress":"Rua do Paço, 67",
       "ShipCity":"Rio de Janeiro",
       "ShipRegion":"RJ",
       "ShipCountry":"Brazil",
       'EmployeeID': 1
    },
    {
       "OrderID":10251,
       "CustomerID":"VICTE",
       "CustomerName": "Thomas Hardy",
       "OrderDate":"1996-07-08T00:00:00.000Z",
       "ShippedDate":"1996-07-15T00:00:00.000Z",
       "Freight":41.34,
       "ShipName":"Victuailles en stock",
       "ShipAddress":"2, rue du Commerce",
       "ShipCity":"Lyon",
       "ShipRegion":null,
       "ShipCountry":"France",
       'EmployeeID': 6
    },
    {
       "OrderID":10252,
       "CustomerID":"SUPRD",
       "CustomerName": "Christina Berglund",
       "OrderDate":"1996-07-09T00:00:00.000Z",
       "ShippedDate":"1996-07-11T00:00:00.000Z",
       "Freight":51.3,
       "ShipName":"Suprêmes délices",
       "ShipAddress":"Boulevard Tirou, 255",
       "ShipCity":"Charleroi",
       "ShipRegion":null,
       "ShipCountry":"Belgium",
       'EmployeeID': 2
    },
    {
       "OrderID":10253,
       "CustomerID":"HANAR",
       "CustomerName": "Hanna Moos",
       "OrderDate":"1996-07-10T00:00:00.000Z",
       "ShippedDate":"1996-07-16T00:00:00.000Z",
       "Freight":58.17,
       "ShipName":"Hanari Carnes",
       "ShipAddress":"Rua do Paço, 67",
       "ShipCity":"Rio de Janeiro",
       "ShipRegion":"RJ",
       "ShipCountry":"Brazil",
       'EmployeeID': 4
    },
    {
       "OrderID":10254,
       "CustomerID":"CHOPS",
       "CustomerName": "Frédérique Citeaux",
       "OrderDate":"1996-07-11T00:00:00.000Z",
       "ShippedDate":"1996-07-23T00:00:00.000Z",
       "Freight":22.98,
       "ShipName":"Chop-suey Chinese",
       "ShipAddress":"Hauptstr. 31",
       "ShipCity":"Bern",
       "ShipRegion":null,
       "ShipCountry":"Switzerland",
       'EmployeeID': 9
    },
    {
       "OrderID":10255,
       "CustomerID":"RICSU",
       "CustomerName": "Martín Sommer",
       "OrderDate":"1996-07-12T00:00:00.000Z",
       "ShippedDate":"1996-07-15T00:00:00.000Z",
       "Freight":148.33,
       "ShipName":"Richter Supermarkt",
       "ShipAddress":"Starenweg 5",
       "ShipCity":"Genève",
       "ShipRegion":null,
       "ShipCountry":"Switzerland",
       'EmployeeID': 7
    },
    {
       "OrderID":10256,
       "CustomerID":"WELLI",
       "CustomerName": "Laurence Lebihan",
       "OrderDate":"1996-07-15T00:00:00.000Z",
       "ShippedDate":"1996-07-17T00:00:00.000Z",
       "Freight":13.97,
       "ShipName":"Wellington Importadora",
       "ShipAddress":"Rua do Mercado, 12",
       "ShipCity":"Resende",
       "ShipRegion":"SP",
       "ShipCountry":"Brazil",
       'EmployeeID': 8
    },
    {
       "OrderID":10257,
       "CustomerID":"HILAA",
       "CustomerName": "Elizabeth Lincoln",
       "OrderDate":"1996-07-16T00:00:00.000Z",
       "ShippedDate":"1996-07-22T00:00:00.000Z",
       "Freight":81.91,
       "ShipName":"HILARION-Abastos",
       "ShipAddress":"Carrera 22 con Ave. Carlos Soublette #8-35",
       "ShipCity":"San Cristóbal",
       "ShipRegion":"Táchira",
       "ShipCountry":"Venezuela",
       'EmployeeID': 5
    },
    {
       "OrderID":10258,
       "CustomerID":"ERNSH",
       "CustomerName": "Victoria Ashworth",
       "OrderDate":"1996-07-17T00:00:00.000Z",
       "ShippedDate":"1996-07-23T00:00:00.000Z",
       "Freight":140.51,
       "ShipName":"Ernst Handel",
       "ShipAddress":"Kirchgasse 6",
       "ShipCity":"Graz",
       "ShipRegion":null,
       "ShipCountry":"Austria",
       'EmployeeID': 1
    },
    {
       "OrderID":10259,
       "CustomerID":"CENTC",
       "CustomerName": "Patricio Simpson",
       "OrderDate":"1996-07-18T00:00:00.000Z",
       "ShippedDate":"1996-07-25T00:00:00.000Z",
       "Freight":3.25,
       "ShipName":"Centro comercial Moctezuma",
       "ShipAddress":"Sierras de Granada 9993",
       "ShipCity":"México D.F.",
       "ShipRegion":null,
       "ShipCountry":"Mexico",
       'EmployeeID': 6
    },
    {
       "OrderID":10260,
       "CustomerID":"OTTIK",
       "CustomerName": "Francisco Chang",
       "OrderDate":"1996-07-19T00:00:00.000Z",
       "ShippedDate":"1996-07-29T00:00:00.000Z",
       "Freight":55.09,
       "ShipName":"Ottilies Käseladen",
       "ShipAddress":"Mehrheimerstr. 369",
       "ShipCity":"Köln",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 2
    },
    {
       "OrderID":10261,
       "CustomerID":"QUEDE",
       "CustomerName": "Yang Wang",
       "OrderDate":"1996-07-19T00:00:00.000Z",
       "ShippedDate":"1996-07-30T00:00:00.000Z",
       "Freight":3.05,
       "ShipName":"Que Delícia",
       "ShipAddress":"Rua da Panificadora, 12",
       "ShipCity":"Rio de Janeiro",
       "ShipRegion":"RJ",
       "ShipCountry":"Brazil",
       'EmployeeID': 7
    },
    {
       "OrderID":10262,
       "CustomerID":"RATTC",
       "CustomerName": "Pedro Afonso",
       "OrderDate":"1996-07-22T00:00:00.000Z",
       "ShippedDate":"1996-07-25T00:00:00.000Z",
       "Freight":48.29,
       "ShipName":"Rattlesnake Canyon Grocery",
       "ShipAddress":"2817 Milton Dr.",
       "ShipCity":"Albuquerque",
       "ShipRegion":"NM",
       "ShipCountry":"USA",
       'EmployeeID': 4
    },
    {
       "OrderID":10263,
       "CustomerID":"ERNSH",
       "CustomerName": "Elizabeth Brown",
       "OrderDate":"1996-07-23T00:00:00.000Z",
       "ShippedDate":"1996-07-31T00:00:00.000Z",
       "Freight":146.06,
       "ShipName":"Ernst Handel",
       "ShipAddress":"Kirchgasse 6",
       "ShipCity":"Graz",
       "ShipRegion":null,
       "ShipCountry":"Austria",
       'EmployeeID': 3
    },
    {
       "OrderID":10264,
       "CustomerID":"FOLKO",
       "CustomerName": "Sven Ottlieb",
       "OrderDate":"1996-07-24T00:00:00.000Z",
       "ShippedDate":"1996-08-23T00:00:00.000Z",
       "Freight":3.67,
       "ShipName":"Folk och fä HB",
       "ShipAddress":"Åkergatan 24",
       "ShipCity":"Bräcke",
       "ShipRegion":null,
       "ShipCountry":"Sweden",
       'EmployeeID': 8
    },
    {
       "OrderID":10265,
       "CustomerID":"BLONP",
       "CustomerName": "Ann Devon",
       "OrderDate":"1996-07-25T00:00:00.000Z",
       "ShippedDate":"1996-08-12T00:00:00.000Z",
       "Freight":55.28,
       "ShipName":"Blondel père et fils",
       "ShipAddress":"24, place Kléber",
       "ShipCity":"Strasbourg",
       "ShipRegion":null,
       "ShipCountry":"France",
       'EmployeeID': 3
    },
    {
       "OrderID":10266,
       "CustomerID":"WARTH",
       "CustomerName": "Roland Mendel",
       "OrderDate":"1996-07-26T00:00:00.000Z",
       "ShippedDate":"1996-07-31T00:00:00.000Z",
       "Freight":25.73,
       "ShipName":"Wartian Herkku",
       "ShipAddress":"Torikatu 38",
       "ShipCity":"Oulu",
       "ShipRegion":null,
       "ShipCountry":"Finland",
       'EmployeeID': 2
    },
    {
       "OrderID":10267,
       "CustomerID":"FRANK",
       "CustomerName": "Aria Cruz",
       "OrderDate":"1996-07-29T00:00:00.000Z",
       "ShippedDate":"1996-08-06T00:00:00.000Z",
       "Freight":208.58,
       "ShipName":"Frankenversand",
       "ShipAddress":"Berliner Platz 43",
       "ShipCity":"München",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 4
    },
    {
       "OrderID":10268,
       "CustomerID":"GROSR",
       "CustomerName": "Diego Roel",
       "OrderDate":"1996-07-30T00:00:00.000Z",
       "ShippedDate":"1996-08-02T00:00:00.000Z",
       "Freight":66.29,
       "ShipName":"GROSELLA-Restaurante",
       "ShipAddress":"5ª Ave. Los Palos Grandes",
       "ShipCity":"Caracas",
       "ShipRegion":"DF",
       "ShipCountry":"Venezuela",
       'EmployeeID': 2
    },
    {
       "OrderID":10269,
       "CustomerID":"WHITC",
       "CustomerName": "Martine Rancé",
       "OrderDate":"1996-07-31T00:00:00.000Z",
       "ShippedDate":"1996-08-09T00:00:00.000Z",
       "Freight":4.56,
       "ShipName":"White Clover Markets",
       "ShipAddress":"1029 - 12th Ave. S.",
       "ShipCity":"Seattle",
       "ShipRegion":"WA",
       "ShipCountry":"USA",
       'EmployeeID': 1
    },
    {
       "OrderID":10270,
       "CustomerID":"WARTH",
       "CustomerName": "Maria Larsson",
       "OrderDate":"1996-08-01T00:00:00.000Z",
       "ShippedDate":"1996-08-02T00:00:00.000Z",
       "Freight":136.54,
       "ShipName":"Wartian Herkku",
       "ShipAddress":"Torikatu 38",
       "ShipCity":"Oulu",
       "ShipRegion":null,
       "ShipCountry":"Finland",
       'EmployeeID': 4
    },
    {
       "OrderID":10271,
       "CustomerID":"SPLIR",
       "CustomerName": "Peter Franken",
       "OrderDate":"1996-08-01T00:00:00.000Z",
       "ShippedDate":"1996-08-30T00:00:00.000Z",
       "Freight":4.54,
       "ShipName":"Split Rail Beer & Ale",
       "ShipAddress":"P.O. Box 555",
       "ShipCity":"Lander",
       "ShipRegion":"WY",
       "ShipCountry":"USA",
       'EmployeeID': 5
    },
    {
       "OrderID":10272,
       "CustomerID":"RATTC",
       "CustomerName": "Carine Schmitt",
       "OrderDate":"1996-08-02T00:00:00.000Z",
       "ShippedDate":"1996-08-06T00:00:00.000Z",
       "Freight":98.03,
       "ShipName":"Rattlesnake Canyon Grocery",
       "ShipAddress":"2817 Milton Dr.",
       "ShipCity":"Albuquerque",
       "ShipRegion":"NM",
       "ShipCountry":"USA",
       'EmployeeID': 3
    },
    {
       "OrderID":10273,
       "CustomerID":"QUICK",
       "CustomerName": "Paolo Accorti",
       "OrderDate":"1996-08-05T00:00:00.000Z",
       "ShippedDate":"1996-08-12T00:00:00.000Z",
       "Freight":76.07,
       "ShipName":"QUICK-Stop",
       "ShipAddress":"Taucherstraße 10",
       "ShipCity":"Cunewalde",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 6
    },
    {
       "OrderID":10274,
       "CustomerID":"VINET",
       "CustomerName": "Lino Rodriguez",
       "OrderDate":"1996-08-06T00:00:00.000Z",
       "ShippedDate":"1996-08-16T00:00:00.000Z",
       "Freight":6.01,
       "ShipName":"Vins et alcools Chevalier",
       "ShipAddress":"59 rue de l'Abbaye",
       "ShipCity":"Reims",
       "ShipRegion":null,
       "ShipCountry":"France",
       'EmployeeID': 1
    },
    {
       "OrderID":10275,
       "CustomerID":"MAGAA",
       "CustomerName": "Eduardo Saavedra",
       "OrderDate":"1996-08-07T00:00:00.000Z",
       "ShippedDate":"1996-08-09T00:00:00.000Z",
       "Freight":26.93,
       "ShipName":"Magazzini Alimentari Riuniti",
       "ShipAddress":"Via Ludovico il Moro 22",
       "ShipCity":"Bergamo",
       "ShipRegion":null,
       "ShipCountry":"Italy",
       'EmployeeID': 3
    },
    {
       "OrderID":10276,
       "CustomerID":"TORTU",
       "CustomerName": "José Pedro Freyre",
       "OrderDate":"1996-08-08T00:00:00.000Z",
       "ShippedDate":"1996-08-14T00:00:00.000Z",
       "Freight":13.84,
       "ShipName":"Tortuga Restaurante",
       "ShipAddress":"Avda. Azteca 123",
       "ShipCity":"México D.F.",
       "ShipRegion":null,
       "ShipCountry":"Mexico",
       'EmployeeID': 5
    },
    {
       "OrderID":10277,
       "CustomerID":"MORGK",
       "CustomerName": "André Fonseca",
       "OrderDate":"1996-08-09T00:00:00.000Z",
       "ShippedDate":"1996-08-13T00:00:00.000Z",
       "Freight":125.77,
       "ShipName":"Morgenstern Gesundkost",
       "ShipAddress":"Heerstr. 22",
       "ShipCity":"Leipzig",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 7
    },
    {
       "OrderID":10278,
       "CustomerID":"BERGS",
       "CustomerName": "Howard Snyder",
       "OrderDate":"1996-08-12T00:00:00.000Z",
       "ShippedDate":"1996-08-16T00:00:00.000Z",
       "Freight":92.69,
       "ShipName":"Berglunds snabbköp",
       "ShipAddress":"Berguvsvägen  8",
       "ShipCity":"Luleå",
       "ShipRegion":null,
       "ShipCountry":"Sweden",
       'EmployeeID': 9
    },
    {
       "OrderID":10279,
       "CustomerID":"LEHMS",
       "CustomerName": "Manuel Pereira",
       "OrderDate":"1996-08-13T00:00:00.000Z",
       "ShippedDate":"1996-08-16T00:00:00.000Z",
       "Freight":25.83,
       "ShipName":"Lehmanns Marktstand",
       "ShipAddress":"Magazinweg 7",
       "ShipCity":"Frankfurt a.M.",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 2
    },
    {
       "OrderID":10280,
       "CustomerID":"BERGS",
       "CustomerName": "Mario Pontes",
       "OrderDate":"1996-08-14T00:00:00.000Z",
       "ShippedDate":"1996-09-12T00:00:00.000Z",
       "Freight":8.98,
       "ShipName":"Berglunds snabbköp",
       "ShipAddress":"Berguvsvägen  8",
       "ShipCity":"Luleå",
       "ShipRegion":null,
       "ShipCountry":"Sweden",
       'EmployeeID': 4
    },
    {
       "OrderID":10281,
       "CustomerID":"ROMEY",
       "CustomerName": "Carlos Hernández",
       "OrderDate":"1996-08-14T00:00:00.000Z",
       "ShippedDate":"1996-08-21T00:00:00.000Z",
       "Freight":2.94,
       "ShipName":"Romero y tomillo",
       "ShipAddress":"Gran Vía, 1",
       "ShipCity":"Madrid",
       "ShipRegion":null,
       "ShipCountry":"Spain",
       'EmployeeID': 6
    },
    {
       "OrderID":10282,
       "CustomerID":"ROMEY",
       "CustomerName": "Yoshi Latimer",
       "OrderDate":"1996-08-15T00:00:00.000Z",
       "ShippedDate":"1996-08-21T00:00:00.000Z",
       "Freight":12.69,
       "ShipName":"Romero y tomillo",
       "ShipAddress":"Gran Vía, 1",
       "ShipCity":"Madrid",
       "ShipRegion":null,
       "ShipCountry":"Spain",
       'EmployeeID': 8
    },
    {
       "OrderID":10283,
       "CustomerID":"LILAS",
       "CustomerName": "Patricia McKenna",
       "OrderDate":"1996-08-16T00:00:00.000Z",
       "ShippedDate":"1996-08-23T00:00:00.000Z",
       "Freight":84.81,
       "ShipName":"LILA-Supermercado",
       "ShipAddress":"Carrera 52 con Ave. Bolívar #65-98 Llano Largo",
       "ShipCity":"Barquisimeto",
       "ShipRegion":"Lara",
       "ShipCountry":"Venezuela",
       'EmployeeID': 9
    },
    {
       "OrderID":10284,
       "CustomerID":"LEHMS",
       "CustomerName": "Helen Bennett",
       "OrderDate":"1996-08-19T00:00:00.000Z",
       "ShippedDate":"1996-08-27T00:00:00.000Z",
       "Freight":76.56,
       "ShipName":"Lehmanns Marktstand",
       "ShipAddress":"Magazinweg 7",
       "ShipCity":"Frankfurt a.M.",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 6
    },
    {
       "OrderID":10285,
       "CustomerID":"QUICK",
       "CustomerName": "Philip Cramer",
       "OrderDate":"1996-08-20T00:00:00.000Z",
       "ShippedDate":"1996-08-26T00:00:00.000Z",
       "Freight":76.83,
       "ShipName":"QUICK-Stop",
       "ShipAddress":"Taucherstraße 10",
       "ShipCity":"Cunewalde",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 3
    },
    {
       "OrderID":10286,
       "CustomerID":"QUICK",
       "CustomerName": "Daniel Tonini",
       "OrderDate":"1996-08-21T00:00:00.000Z",
       "ShippedDate":"1996-08-30T00:00:00.000Z",
       "Freight":229.24,
       "ShipName":"QUICK-Stop",
       "ShipAddress":"Taucherstraße 10",
       "ShipCity":"Cunewalde",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       'EmployeeID': 1
    },
    {
       "OrderID":10287,
       "CustomerID":"RICAR",
       "CustomerName": "Annette Roulet",
       "OrderDate":"1996-08-22T00:00:00.000Z",
       "ShippedDate":"1996-08-28T00:00:00.000Z",
       "Freight":12.76,
       "ShipName":"Ricardo Adocicados",
       "ShipAddress":"Av. Copacabana, 267",
       "ShipCity":"Rio de Janeiro",
       "ShipRegion":"RJ",
       "ShipCountry":"Brazil",
       'EmployeeID': 8
    },
    {
       "OrderID":10288,
       "CustomerID":"REGGC",
       "CustomerName": "Yoshi Tannamuri",
       "OrderDate":"1996-08-23T00:00:00.000Z",
       "ShippedDate":"1996-09-03T00:00:00.000Z",
       "Freight":7.45,
       "ShipName":"Reggiani Caseifici",
       "ShipAddress":"Strada Provinciale 124",
       "ShipCity":"Reggio Emilia",
       "ShipRegion":null,
       "ShipCountry":"Italy",
       'EmployeeID': 4
    },
    {
       "OrderID":10289,
       "CustomerID":"BSBEV",
       "CustomerName": "John Steel",
       "OrderDate":"1996-08-26T00:00:00.000Z",
       "ShippedDate":"1996-08-28T00:00:00.000Z",
       "Freight":22.77,
       "ShipName":"B's Beverages",
       "ShipAddress":"Fauntleroy Circus",
       "ShipCity":"London",
       "ShipRegion":null,
       "ShipCountry":"UK",
       'EmployeeID': 2
    },
    {
       "OrderID":10290,
       "CustomerID":"COMMI",
       "CustomerNames": "Renate Messner",
       "OrderDate":"1996-08-27T00:00:00.000Z",
       "ShippedDate":"1996-09-03T00:00:00.000Z",
       "Freight":79.7,
       "ShipName":"Comércio Mineiro",
       "ShipAddress":"Av. dos Lusíadas, 23",
       "ShipCity":"Sao Paulo",
       "ShipRegion":"SP",
       "ShipCountry":"Brazil",
       'EmployeeID': 5
    },
    {
       "OrderID":10291,
       "CustomerID":"QUEDE",
       "CustomerName": "Jaime Yorres",
       "OrderDate":"1996-08-27T00:00:00.000Z",
       "ShippedDate":"1996-09-04T00:00:00.000Z",
       "Freight":6.4,
       "ShipName":"Que Delícia",
       "ShipAddress":"Rua da Panificadora, 12",
       "ShipCity":"Rio de Janeiro",
       "ShipRegion":"RJ",
       "ShipCountry":"Brazil",
       'EmployeeID': 7
    },
    {
       "OrderID":10292,
       "CustomerID":"TRADH",
       "CustomerName": "Carlos González",
       "OrderDate":"1996-08-28T00:00:00.000Z",
       "ShippedDate":"1996-09-02T00:00:00.000Z",
       "Freight":1.35,
       "ShipName":"Tradiçao Hipermercados",
       "ShipAddress":"Av. Inês de Castro, 414",
       "ShipCity":"Sao Paulo",
       "ShipRegion":"SP",
       "ShipCountry":"Brazil",
       'EmployeeID': 3
    },
    {
       "OrderID":10293,
       "CustomerID":"TORTU",
       "CustomerName": "Felipe Izquierdo",
       "OrderDate":"1996-08-29T00:00:00.000Z",
       "ShippedDate":"1996-09-11T00:00:00.000Z",
       "Freight":21.18,
       "ShipName":"Tortuga Restaurante",
       "ShipAddress":"Avda. Azteca 123",
       "ShipCity":"México D.F.",
       "ShipRegion":null,
       "ShipCountry":"Mexico",
       'EmployeeID': 1
    },
    {
       "OrderID":10294,
       "CustomerID":"RATTC",
       "CustomerName": "Fran Wilson",
       "OrderDate":"1996-08-30T00:00:00.000Z",
       "ShippedDate":"1996-09-05T00:00:00.000Z",
       "Freight":147.26,
       "ShipName":"Rattlesnake Canyon Grocery",
       "ShipAddress":"2817 Milton Dr.",
       "ShipCity":"Albuquerque",
       "ShipRegion":"NM",
       "ShipCountry":"USA",
       'EmployeeID': 2
    },
    {
       "OrderID":10295,
       "CustomerID":"VINET",
       "CustomerName": "Giovanni Rovelli",
       "OrderDate":"1996-09-02T00:00:00.000Z",
       "ShippedDate":"1996-09-10T00:00:00.000Z",
       "Freight":1.15,
       "ShipName":"Vins et alcools Chevalier",
       "ShipAddress":"59 rue de l'Abbaye",
       "ShipCity":"Reims",
       "ShipRegion":null,
       "ShipCountry":"France",
       'EmployeeID': 3
    },
    {
       "OrderID":10296,
       "CustomerID":"LILAS",
       "CustomerName": "Catherine Dewey",
       "OrderDate":"1996-09-03T00:00:00.000Z",
       "ShippedDate":"1996-09-11T00:00:00.000Z",
       "Freight":0.12,
       "ShipName":"LILA-Supermercado",
       "ShipAddress":"Carrera 52 con Ave. Bolívar #65-98 Llano Largo",
       "ShipCity":"Barquisimeto",
       "ShipRegion":"Lara",
       "ShipCountry":"Venezuela",
       'EmployeeID': 4
    },
    {
       "OrderID":10297,
       "CustomerID":"BLONP",
       "CustomerName": "Jean Fresnière",
       "OrderDate":"1996-09-04T00:00:00.000Z",
       "ShippedDate":"1996-09-10T00:00:00.000Z",
       "Freight":5.74,
       "ShipName":"Blondel père et fils",
       "ShipAddress":"24, place Kléber",
       "ShipCity":"Strasbourg",
       "ShipRegion":null,
       "ShipCountry":"France",
       'EmployeeID': 5
    },
    {
       "OrderID":10298,
       "CustomerID":"HUNGO",
       "CustomerName": "Alexander Feuer",
       "OrderDate":"1996-09-05T00:00:00.000Z",
       "ShippedDate":"1996-09-11T00:00:00.000Z",
       "Freight":168.22,
       "ShipName":"Hungry Owl All-Night Grocers",
       "ShipAddress":"8 Johnstown Road",
       "ShipCity":"Cork",
       "ShipRegion":"Co. Cork",
       "ShipCountry":"Ireland",
       'EmployeeID': 6
    },
    {
       "OrderID":10299,
       "CustomerID":"RICAR",
       "CustomerName": "Simon Crowther",
       "OrderDate":"1996-09-06T00:00:00.000Z",
       "ShippedDate":"1996-09-13T00:00:00.000Z",
       "Freight":29.76,
       "ShipName":"Ricardo Adocicados",
       "ShipAddress":"Av. Copacabana, 267",
       "ShipCity":"Rio de Janeiro",
       "ShipRegion":"RJ",
       "ShipCountry":"Brazil",
       "EmployeeID": 7
   },
   {
       "OrderID":10300,
       "CustomerID":"MAGAA",
       "CustomerNames":"Yvonne Moncada",
       "OrderDate":"1996-09-09T00:00:00.000Z",
       "ShippedDate":"1996-09-18T00:00:00.000Z",
       "Freight":17.68,
       "ShipName":"Magazzini Alimentari Riuniti",
       "ShipAddress":"Via Ludovico il Moro 22",
       "ShipCity":"Bergamo",
       "ShipRegion":null,
       "ShipCountry":"Italy",
       "EmployeeID": 8
   },
   {
       "OrderID":10301,
       "CustomerID":"WANDK",
       "CustomerName": "Rene Phillips",
       "OrderDate":"1996-09-09T00:00:00.000Z",
       "ShippedDate":"1996-09-17T00:00:00.000Z",
       "Freight":45.08,
       "ShipName":"Die Wandernde Kuh",
       "ShipAddress":"Adenauerallee 900",
       "ShipCity":"Stuttgart",
       "ShipRegion":null,
       "ShipCountry":"Germany",
       "EmployeeID": 9
   },
   {
       "OrderID":10302,
       "CustomerID":"SUPRD",
       "CustomerName": "Pirkko Koskitalo",
       "OrderDate":"1996-09-10T00:00:00.000Z",
       "ShippedDate":"1996-10-09T00:00:00.000Z",
       "Freight":6.27,
       "ShipName":"Suprêmes délices",
       "ShipAddress":"Boulevard Tirou, 255",
       "ShipCity":"Charleroi",
       "ShipRegion":null,
       "ShipCountry":"Belgium",
       "EmployeeID": 2
   },
   {
       "OrderID":10303,
       "CustomerID":"GODOS",
       "CustomerName": "Paula Parente",
       "OrderDate":"1996-09-11T00:00:00.000Z",
       "ShippedDate":"1996-09-18T00:00:00.000Z",
       "Freight":107.83,
       "ShipName":"Godos Cocina Típica",
       "ShipAddress":"C/ Romero, 33",
       "ShipCity":"Sevilla",
       "ShipRegion":null,
       "ShipCountry":"Spain",
       "EmployeeID": 4
   },
   {
       "OrderID":10304,
       "CustomerID":"TORTU",
       "CustomerName": "Karl Jablonski",
       "OrderDate":"1996-09-12T00:00:00.000Z",
       "ShippedDate":"1996-09-17T00:00:00.000Z",
       "Freight":63.79,
       "ShipName":"Tortuga Restaurante",
       "ShipAddress":"Avda. Azteca 123",
       "ShipCity":"México D.F.",
       "ShipRegion":null,
       "ShipCountry":"Mexico",
       "EmployeeID": 8
   },
   {
       "OrderID":10305,
       "CustomerID":"OLDWO",
       "CustomerName": "Matti Karttunen",
       "OrderDate":"1996-09-13T00:00:00.000Z",
       "ShippedDate":"1996-10-09T00:00:00.000Z",
       "Freight":257.62,
       "ShipName":"Old World Delicatessen",
       "ShipAddress":"2743 Bering St.",
       "ShipCity":"Anchorage",
       "ShipRegion":"AK",
       "ShipCountry":"USA",
       "EmployeeID": 6
   },
   {
       "OrderID":10306,
       "CustomerID":"ROMEY",
       "CustomerName": "Zbyszek Piestrzeniewicz",
       "OrderDate":"1996-09-16T00:00:00.000Z",
       "ShippedDate":"1996-09-23T00:00:00.000Z",
       "Freight":7.56,
       "ShipName":"Romero y tomillo",
       "ShipAddress":"Gran Vía, 1",
       "ShipCity":"Madrid",
       "ShipRegion":null,
       "ShipCountry":"Spain",
       "EmployeeID": 3
   },
   {
       "OrderID":10307,
       "CustomerID":"LONEP",
       "CustomerName": "Zbyszek Piestrzeniewicz",
       "OrderDate":"1996-09-17T00:00:00.000Z",
       "ShippedDate":"1996-09-25T00:00:00.000Z",
       "Freight":0.56,
       "ShipName":"Lonesome Pine Restaurant",
       "ShipAddress":"89 Chiaroscuro Rd.",
       "ShipCity":"Portland",
       "ShipRegion":"OR",
       "ShipCountry":"USA",
       "EmployeeID": 1
   }]);
   export const orderDetails : Object[] = JSON.parse(order, (field: string, value: any) => {
   let dupValue: any = value;
   if (typeof value === 'string' && /^(\d{4}\-\d\d\-\d\d([tT][\d:\.]*){1})([zZ]|([+\-])(\d\d):?(\d\d))?$/.test(value)) {
       let arr: any = dupValue.split(/[^0-9]/);
       let a: any = parseInt(arr[0], 10);
       let b: any = parseInt(arr[1], 10) - 1;
       let c: any = parseInt(arr[2], 10);
       let d: any = parseInt(arr[3], 10);
       value = new Date(a, b, c, d, parseInt(arr[4], 10), parseInt(arr[5], 10));
   }
   return value;
 });
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
  • By default, the foreign key column’s editType will be set as dropdownedit.

Exporting

Exporting Grid in Cordova application

Cordova application does not support direct file download. So we have to use the Blob stream to export the Grid. You can use corresponding exporting methods and exportComplete events to get the Blob stream.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { data } from './datasource';
import {
GridComponent, ToolbarItems, ToolbarService, ExcelExportService, PdfExportService,
ExcelExportCompleteArgs, PdfExportCompleteArgs
} from '@syncfusion/ej2-angular-grids';
import { ClickEventArgs } from '@syncfusion/ej2-angular-navigations';

@Component({
selector: 'app-root',
template: `<ejs-grid #grid id='Grid' [dataSource]='data' [toolbar]='toolbarOptions' height='272px' [allowExcelExport]='true'
(excelExportComplete)='excelExpComplete($event)' (pdfExportComplete)='pdfExpComplete($event)'
  [allowPdfExport]='true' (toolbarClick)='toolbarClick($event)'>
            <e-columns>
                <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=120></e-column>
                <e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
                <e-column field='ShipCity' headerText='Ship City' width=150></e-column>
            </e-columns>
            </ejs-grid>`,
providers: [ToolbarService, ExcelExportService, PdfExportService]
})
export class AppComponent implements OnInit {

public data: object[];
public toolbarOptions: ToolbarItems[];
@ViewChild('grid') public grid: GridComponent;
public exportBlob = (blob: Blob) => {
    const a: HTMLAnchorElement = document.createElement('a');
    document.body.appendChild(a);
    a.style.display = 'none';
    const url: string = (window.URL as any).createobjectURL(blob);
    a.href = url;
    a.download = 'Export';
    a.click();
    (window.URL as any).revokeobjectURL(url);
    document.body.removeChild(a);
}

ngOnInit(): void {
    this.data = data;
    this.toolbarOptions = ['PdfExport', 'ExcelExport'];
}

toolbarClick(args: ClickEventArgs) {
    if (args.item.id === 'Grid_pdfexport') {
        this.grid.pdfExport(null, null, null, true);
    }
    if (args.item.id === 'Grid_excelexport') {
        this.grid.excelExport(null, null, null, true);
    }
}

excelExpComplete(args: ExcelExportCompleteArgs) {
    // This event will be triggered when excel exporting.
    args.promise.then((e: { blobData: Blob }) => {
        // In this `then` function, we can get blob data through the arguments after promise resolved.
        this.exportBlob(e.blobData);
    });
}

pdfExpComplete(args: PdfExportCompleteArgs) {
    // This event will be triggered when pdf exporting.
    args.promise.then((e: { blobData: Blob }) => {
        // In this `then` function, we can get blob data through the arguments after promise resolved.
        this.exportBlob(e.blobData);
    });
}
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, ToolbarService, PdfExportService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Exporting Filtered Data Only

You can export the filtered data by defining the resulted data in exportProperties.dataSource before export.

In the below Pdf exporting demo, We have gotten the filtered data by applying filter query to the grid data and then defines the resulted data in exportProperties.dataSource and pass it to pdfExport method.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { data } from './datasource';
import { GridComponent, ToolbarItems, ToolbarService, PdfExportService,
 PageService, FilterService } from '@syncfusion/ej2-angular-grids';
import { ClickEventArgs } from '@syncfusion/ej2-angular-navigations';
import {DataManager} from '@syncfusion/ej2-data';

@Component({
  selector: 'app-root',
  template: `<ejs-grid #grid id='Grid' [dataSource]='data' [toolbar]='toolbarOptions'
   [allowFiltering]='true' [allowPaging]='true' [pageSettings]='initialPage' [allowPdfExport]='true'
   (toolbarClick)='toolbarClick($event)'>
          <e-columns>
              <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=120></e-column>
              <e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
              <e-column field='ShipCity' headerText='Ship City' width=150></e-column>
          </e-columns>
          </ejs-grid>`,
  providers: [ToolbarService, PdfExportService, PageService, FilterService]
})
export class AppComponent implements OnInit {

  public data: object[];
  public toolbarOptions: ToolbarItems[];
  public initialPage: object;
  @ViewChild('grid')
  public grid: GridComponent;
  ngOnInit(): void {
this.data = data;
this.toolbarOptions = ['PdfExport'];
this.initialPage = { pageCount: 5, pageSize: 5 };
  }

  toolbarClick(args: ClickEventArgs) {
if (args.item.id === 'Grid_pdfexport') {
  let pdfdata;
  const query = this.grid.renderModule.data.generateQuery(); // get grid corresponding query
  for (let i = 0; i < query.queries.length; i++) {
    if (query.queries[i].fn === 'onPage') {
      query.queries.splice(i, 1);       // remove page query to get all records
      break;
    }
  }
  const fdata = new DataManager({ json: data }).executeQuery(query).then((e: any) => {
    pdfdata = e.result as object[];  // get all filtered records
    const exportProperties = {
      dataSource: pdfdata,
    };
    this.grid.pdfExport(exportProperties);
  }).catch((e) => true);
}
  }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, FreezeService, SelectionService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Pager

Customize Pager DropDown

To customize default values of pager dropdown, you need to define pageSizes as array of strings.

Copied to clipboard
import { Component, OnInit } from '@angular/core';
import { data } from './datasource';

@Component({
selector: 'app-root',
template: `<ejs-grid [dataSource]='data' allowPaging='true' [pageSettings]='initialPage'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=90></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
                    <e-column field='Freight' headerText='Freight' textAlign='Right' format='C2' width=90></e-column>
                    <e-column field='OrderDate' headerText='Order Date' textAlign='Right' format='yMd' width=120></e-column>
                </e-columns>
            </ejs-grid>`
})
export class AppComponent implements OnInit {

public data: object[];
public initialPage: object;

ngOnInit(): void {
    this.data = data;
    this.initialPage = { pageSizes: ['5', '10', 'All'], };
}
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { PageService, SortService, FilterService, GroupService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                GroupService]
})
export class AppModule { }
Copied to clipboard
export let data: Object[] = [
    {
        OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date(8364186e5),
        ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye',
        ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0
    },
    {
        OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date(836505e6),
        ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48',
        ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1
    },
    {
        OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date(8367642e5),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0
    },
    {
        OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5),
        ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce',
        ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0
    },
    {
        OrderID: 10252, CustomerID: 'SUPRD', EmployeeID: 4, OrderDate: new Date(8368506e5),
        ShipName: 'Suprêmes délices', ShipCity: 'Charleroi', ShipAddress: 'Boulevard Tirou, 255',
        ShipRegion: 'CJ', ShipPostalCode: 'B-6000', ShipCountry: 'Belgium', Freight: 51.3, Verified: !0
    },
    {
        OrderID: 10253, CustomerID: 'HANAR', EmployeeID: 3, OrderDate: new Date(836937e6),
        ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67',
        ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 58.17, Verified: !0
    },
    {
        OrderID: 10254, CustomerID: 'CHOPS', EmployeeID: 5, OrderDate: new Date(8370234e5),
        ShipName: 'Chop-suey Chinese', ShipCity: 'Bern', ShipAddress: 'Hauptstr. 31',
        ShipRegion: 'CJ', ShipPostalCode: '3012', ShipCountry: 'Switzerland', Freight: 22.98, Verified: !1
    },
    {
        OrderID: 10255, CustomerID: 'RICSU', EmployeeID: 9, OrderDate: new Date(8371098e5),
        ShipName: 'Richter Supermarkt', ShipCity: 'Genève', ShipAddress: 'Starenweg 5',
        ShipRegion: 'CJ', ShipPostalCode: '1204', ShipCountry: 'Switzerland', Freight: 148.33, Verified: !0
    },
    {
        OrderID: 10256, CustomerID: 'WELLI', EmployeeID: 3, OrderDate: new Date(837369e6),
        ShipName: 'Wellington Importadora', ShipCity: 'Resende', ShipAddress: 'Rua do Mercado, 12',
        ShipRegion: 'SP', ShipPostalCode: '08737-363', ShipCountry: 'Brazil', Freight: 13.97, Verified: !1
    },
    {
        OrderID: 10257, CustomerID: 'HILAA', EmployeeID: 4, OrderDate: new Date(8374554e5),
        ShipName: 'HILARION-Abastos', ShipCity: 'San Cristóbal', ShipAddress: 'Carrera 22 con Ave. Carlos Soublette #8-35',
        ShipRegion: 'Táchira', ShipPostalCode: '5022', ShipCountry: 'Venezuela', Freight: 81.91, Verified: !0
    },
    {
        OrderID: 10258, CustomerID: 'ERNSH', EmployeeID: 1, OrderDate: new Date(8375418e5),
        ShipName: 'Ernst Handel', ShipCity: 'Graz', ShipAddress: 'Kirchgasse 6',
        ShipRegion: 'CJ', ShipPostalCode: '8010', ShipCountry: 'Austria', Freight: 140.51, Verified: !0
    },
    {
        OrderID: 10259, CustomerID: 'CENTC', EmployeeID: 4, OrderDate: new Date(8376282e5),
        ShipName: 'Centro comercial Moctezuma', ShipCity: 'México D.F.', ShipAddress: 'Sierras de Granada 9993',
        ShipRegion: 'CJ', ShipPostalCode: '05022', ShipCountry: 'Mexico', Freight: 3.25, Verified: !1
    },
    {
        OrderID: 10260, CustomerID: 'OTTIK', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Ottilies Käseladen', ShipCity: 'Köln', ShipAddress: 'Mehrheimerstr. 369',
        ShipRegion: 'CJ', ShipPostalCode: '50739', ShipCountry: 'Germany', Freight: 55.09, Verified: !0
    },
    {
        OrderID: 10261, CustomerID: 'QUEDE', EmployeeID: 4, OrderDate: new Date(8377146e5),
        ShipName: 'Que Delícia', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua da Panificadora, 12',
        ShipRegion: 'RJ', ShipPostalCode: '02389-673', ShipCountry: 'Brazil', Freight: 3.05, Verified: !1
    },
    {
        OrderID: 10262, CustomerID: 'RATTC', EmployeeID: 8, OrderDate: new Date(8379738e5),
        ShipName: 'Rattlesnake Canyon Grocery', ShipCity: 'Albuquerque', ShipAddress: '2817 Milton Dr.',
        ShipRegion: 'NM', ShipPostalCode: '87110', ShipCountry: 'USA', Freight: 48.29, Verified: !0
    }];
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Hide the expand/collapse icon in parent row when no records in child grid

By default, the expand/collapse icon will be visible even if the child grid is empty.

You can use rowDataBound event to hide the icon when there are no records in child grid.

To hide the expand/collapse icon in parent row when no records in child grid, follow the given steps:

Step 1:

Create CSS class with custom style to override the default style of Grid.

Copied to clipboard
.e-row[aria-selected="true"] .e-customizedExpandcell {
    background-color: #e0e0e0;
}

.e-grid.e-gridhover tr[role='row']:hover {
    background-color: #eee;
}

Step 2:

Add the CSS class to the Grid in the rowDataBound event handler of Grid.

Copied to clipboard
public rowDataBound(args:any){
    let filter:string = args.data.EmployeeID;
    let childrecord: any = new DataManager(this.Grid.childGrid.dataSource).executeLocal(new Query().where('EmployeeID', 'equal', parseInt(filter), true));
    if(childrecord.length == 0) {
        //here hide which parent row has no child records
        args.row.querySelector('td').innerHTML=' ';
        args.row.querySelector('td').className = 'e-customizedExpandcell';
    }
}

In the below demo, the expand/collapse icon in the row with EmployeeID as 1 is hidden as it does not have record in child Grid.

Copied to clipboard
import { Component, OnInit, ViewChild } from '@angular/core';
import { employeeData } from './datasource';
import { GridComponent, RowDataBoundEventArgs } from '@syncfusion/ej2-angular-grids';
import { DataManager, Query, DataResult } from '@syncfusion/ej2-data';

@Component({
selector: 'app-root',
template: `<ejs-grid #Grid [dataSource]='data' [childGrid]='childGrid' (rowDataBound)="rowDataBound($event)">
                <e-columns>
                    <e-column field='EmployeeID' headerText='EmployeeID' width='120' ></e-column>
                    <e-column field='FirstName' headerText='First Name'  width='150' ></e-column>
                    <e-column field='Title' headerText='Title' width='120' textAlign='Right'></e-column>
                    <e-column field='City' headerText='City' width='120' textAlign='Right'></e-column>
                    <e-column field='Country' headerText='Country' width='120' textAlign='Right'></e-column>
                </e-columns>
            </ejs-grid>`
})
export class AppComponent implements OnInit {

public data: object[];
@ViewChild('Grid') public Grid: GridComponent;
public childGrid: object;
public dataManger: object[] = [{Order: 100, ShipName: 'Berlin', EmployeeID: 2},
                             {Order: 101, ShipName: 'Capte', EmployeeID: 3},
                             {Order: 102, ShipName: 'Marlon', EmployeeID: 4},
                             {Order: 103, ShipName: 'Black pearl', EmployeeID: 5},
                             {Order: 104, ShipName: 'Pearl', EmployeeID: 6},
                             {Order: 105, ShipName: 'Noth bay', EmployeeID: 7},
                             {Order: 106, ShipName: 'baratna', EmployeeID: 8},
                             {Order: 107, ShipName: 'Charge', EmployeeID: 9}];

ngOnInit(): void {
  this.data = employeeData;
  this.childGrid = {
      dataSource: new DataManager(this.dataManger),
      queryString: 'EmployeeID',
      allowPaging: true,
      columns: [
          { field: 'Order', headerText: 'Order ID', textAlign: 'Right', width: 120 },
          { field: 'EmployeeID', headerText: 'Employee ID', textAlign: 'Right', width: 120 },
          { field: 'ShipName', headerText: 'Ship Name', width: 150 }
      ]
  };
}
public rowDataBound(args: RowDataBoundEventArgs) {
    const EmployeeID = 'EmployeeID';
    const filter: string = args.data[EmployeeID];
    const childrecord: any = new DataManager(this.Grid.childGrid.dataSource as JSON[]).
    executeLocal(new Query().where('EmployeeID', 'equal', parseInt(filter, 10), true));
    if (childrecord.length === 0) {
        // here hide which parent row has no child records
        args.row.querySelector('td').innerHTML = ' ';
        args.row.querySelector('td').className = 'e-customizedExpandcell';
    }
}
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { PageService, SortService, FilterService, GroupService } from '@syncfusion/ej2-angular-grids';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        ButtonModule,
        GridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService,
                SortService,
                FilterService,
                GroupService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);