Context menu in Angular Grid component

26 Oct 202324 minutes to read

The Syncfusion Angular Grid component comes equipped with a context menu feature, which is triggered when a user right-clicks anywhere within the grid. This feature serves to enrich the user experience by offering immediate access to a variety of supplementary actions and operations that can be executed on the data displayed in the grid.

In essence, the context menu provides a convenient and efficient way for users to interact with and manipulate the grid’s content, enabling them to perform tasks such as sorting, filtering, editing, or any other relevant actions without the need for navigating through the grid’s interface. This user-friendly feature streamlines the overall usability of the Angular Grid, making it a powerful tool for data management and manipulation.

To activate the context menu within the grid, you have an option to configure the grid’s contextMenuItems property. You can set this property to either include the default context menu items or define your own custom context menu items, tailoring the menu options to suit your specific needs. This customization allows you to enhance the grid’s functionality by providing context-sensitive actions for interacting with your data.

To use the context menu, you need to inject the ContextMenuService in the provider section of AppModule.

The context menu is triggered when you right-click on different areas of the grid, including:

  • Header: When you right-click on the grid’s header section.
  • Content: When you right-click on the grid’s main content area.
  • Pager: When you right-click on the pager section.

The context menu items that appear vary depending on the area you have clicked. For instance, the items available in the context menu when clicking on the header area differ from those in the content area or pager.

The default context menu items in the header area of the grid are as follows:

Items Description
AutoFit Automatically adjust the column width to fit the content.
AutoFitAll Automatically adjust all column widths to fit their content.
Group Group the data based on the current column.
Ungroup Remove grouping for the current column.
SortAscending Sort the current column in ascending order.
SortDescending Sort the current column in descending order.

The default context menu items in the content area of the grid are as follows:

Items Description
Edit Edit the currently selected record in the grid.
Delete Delete the currently selected record.
Save Save the changes made to the edited record.
Cancel Cancel the edit state and revert changes made to the edited record.
Copy Copy the selected records to the clipboard.
PdfExport Export the grid data as a PDF document.
ExcelExport Export the grid data as an Excel document.
CsvExport Export the grid data as a CSV document.

The default context menu items in the pager area of the grid are as follows:

Items Description
FirstPage Navigate to the first page of the grid.
PrevPage Navigate to the previous page of the grid.
LastPage Navigate to the last page of the grid.
NextPage Navigate to the next page of the grid.

The following example demonstrates how to enable context menu feature in the grid.

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

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' id="gridcomp" allowPaging='true' [allowExcelExport]='true'
    [allowPdfExport]='true' height='220px' [allowSorting]='true' [allowGrouping]='true' [contextMenuItems]="contextMenuItems" 
    [editSettings]='editing'>
        <e-columns>
            <e-column field='OrderID' headerText='Order ID' width='90' textAlign="Right" isPrimaryKey='true'></e-column>
            <e-column field='CustomerID' headerText='Customer Name' width='100'></e-column>
            <e-column field='Freight' headerText='Freight' format='C2' textAlign="Right" editType='numericedit' 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 contextMenuItems?: ContextMenuItem[];
    public editing?: EditSettingsModel;

    ngOnInit(): void {
        this.data = data;
        this.editing = { allowEditing: true, allowDeleting: true };
        this.contextMenuItems = ['AutoFit',
            'AutoFitAll',
            'SortAscending',
            'SortDescending',
            'Copy',
            'Edit',
            'Delete',
            'Save',
            'Cancel',
            'PdfExport',
            'ExcelExport',
            'CsvExport',
            'FirstPage',
            'PrevPage',
            'LastPage',
            'NextPage',
            'Group',
            'Ungroup'
        ]
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import {
    ContextMenuService, PageService, ResizeService, SortService, GroupService, EditService,
    PdfExportService, ExcelExportService
} from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

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

Custom context menu items

The Syncfusion Angular Grid empowers you to enhance your user experience by incorporating custom context menu items into the default context menu. These customized options enable you to tailor the context menu to meet the unique requirements of your application.

By adding custom context menu items, you can introduce additional actions or operations that are directly relevant to your specific use case. This flexibility allows you to create a highly personalized and efficient interaction with your grid, making it a powerful tool for data management and manipulation.

To add custom context menu items by defining the contextMenuItems property as a collection of contextMenuItemModel. You can also define actions for these customized items using the contextMenuClick event.

To incorporate custom context menu items in the Syncfusion Angular Grid, you can achieve this by specifying the contextMenuItems property as a collection of contextMenuItemModel. This allows you to define and customize the appearance and behavior of these additional context menu items according to your requirements.

Furthermore, you can assign actions to these custom items by utilizing the contextMenuClick event. This event provides you with the means to handle user interactions with the custom context menu items, enabling you to execute specific actions or operations when these items are clicked.

The following example demonstrates how to add custom context menu items in the Grid component.

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

@Component({
    selector: 'app-root',
    template: `<ejs-grid #grid id='grid' [dataSource]='data' [allowSelection]='true' 
                [allowPaging]='true'height='265px' [contextMenuItems]='contextMenuItems' 
                (contextMenuClick)='contextMenuClick($event)'>
                    <e-columns>
                        <e-column field='EmployeeID' [isPrimaryKey]='true' 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>`,
})
export class AppComponent implements OnInit {

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

    ngOnInit(): void {
        this.data = employeeData;
        this.contextMenuItems=[{ text: 'Copy with headers', target: '.e-content', id: 'copywithheader' }];
    }

    contextMenuClick(args: MenuEventArgs): void {
        if (args.item.id === 'copywithheader') {
            (this.grid as GridComponent).copy(true);
        }
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { PageService, ContextMenuService,  } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

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

Show context menu on left click

The Syncfusion Angular Grid provides the ability to show the context menu items on a left mouse click instead of the default right mouse click action.

This can be achieved by using the created event and the context menu’s beforeOpen event of the Grid.

By using the onclick event listener of the Grid, you can obtain the clicked position values through the ngAfterViewInit method. This method is appropriate for interacting with the Document Object Model (DOM) and performing operations that require access to the rendered elements. The obtained positions are then sent to the open method of the context menu within the onclick event of the Grid. Additionally, the default action of right-clicking to open the context menu items items is prevented by utilizing the created event of the Grid.

The following example demonstrates how to show context menu on left click using created event.

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

@Component({
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' #grid id="Grid" [allowPaging]='true' [pageSettings]='pageSettings' [allowExcelExport]='true' [allowPdfExport]='true' 
                [allowSorting]='true' [contextMenuItems]="contextMenuItems" (created)="created()">
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' width='90' textAlign="Right" isPrimaryKey='true'></e-column>
                        <e-column field='CustomerID' headerText='Customer Name' width='100'></e-column>
                        <e-column field='ShipCountry' headerText='Ship Country' width='100'></e-column>
                        <e-column field='ShipCity' headerText='Ship City' width='100'></e-column>
                    </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {

    public values?: any;
    public data?: object[];
    public contextMenuItems?: ContextMenuItem[];
    public pageSettings?: PageSettingsModel;
    @ViewChild('grid')
    public grid?: GridComponent;

    ngOnInit(): void {
        this.data = data;
        this.contextMenuItems = [
            'SortAscending',
            'SortDescending',
            'FirstPage',
            'PrevPage',
            'LastPage',
            'NextPage',
            'PdfExport',
            'ExcelExport',
        ];
        this.pageSettings = { pageSize: 8 };
    }

    ngAfterViewInit(): void {
        const gridElement = document.getElementById('Grid');
            (gridElement as HTMLElement).onclick = (event: MouseEvent) => {
                this.values = event;
                (this.grid as GridComponent).contextMenuModule.contextMenu.open(
                    this.values.pageY + pageYOffset,
                    this.values.pageX + pageXOffset
                );
        }
        
    }

    created(): void {
        (this.grid as GridComponent).contextMenuModule.contextMenu.beforeOpen = (
            args: BeforeOpenCloseMenuEventArgs
          ) => {
            if (args.event instanceof MouseEvent && args.event.which === 3) {
              args.cancel = true;
            }
            args.event = this.values;
            (this.grid as any).contextMenuModule.contextMenuBeforeOpen(
                args
              );
          };
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { ContextMenuService, PageService, SortService, ExcelExportService, PdfExportService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

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

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

You can hide or show an item in context menu for specific area inside of grid by defining the target property.

Enable or disable context menu items

With the Syncfusion Angular Grid, you have the ability to manage the activation or deactivation of both default and custom context menu items. This feature provides you with the flexibility to tailor the behavior of context menu items to suit specific conditions or individual interactions within your application.

By enabling or disabling context menu items, you can ensure that certain options are available or restricted based on the context of the data or the needs of your users. This level of control allows you to create a more dynamic and user-centric experience with the grid, aligning it with your application’s requirements and enhancing usability.

This can be achieved using the enableItems method of the context menu. By setting the enable parameter in the enableItems method to true, you can enable context menu items, and by setting it to false, you can disable them. Based on your specific condition or requirements, you can enable or disable the context menu item using the enableItems method.

In the following example, the EJ2 Toggle Switch Button component is added to enable and disable the context menu items using enableItems method. When the switch is toggled, the change event is triggered, and the Copy items is updated accordingly.

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

@Component({
    selector: 'app-root',
    template: `
    <div>
    <label style="padding: 10px 10px">
    Enable or disable context menu items
    </label>
    <ejs-switch id="switch" (change)="switchChange($event)"></ejs-switch>
    </div>
    <ejs-grid  #grid style="padding: 10px 10px" [dataSource]='data' id="grid" allowPaging='true' height='265px'
            [contextMenuItems]="contextMenuItems" [editSettings]='editing' >
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' width='90' textAlign="Right" isPrimaryKey='true'></e-column>
                    <e-column field='CustomerID' headerText='Customer Name' width='100'></e-column>
                    <e-column field='Freight' headerText='Freight' format='C2' textAlign="Right" editType='numericedit' width='90'></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width='150'></e-column>
                </e-columns>
            </ejs-grid>`,
})
export class AppComponent implements OnInit {

    public data?: object[];
    public contextMenuItems?: ContextMenuItem[];
    @ViewChild('grid')
    public grid?: GridComponent;
    public editing?: EditSettingsModel;

    ngOnInit(): void {
        this.data = data;
        this.contextMenuItems = ['Copy', 'Edit', 'Delete'];
        this.editing = { allowAdding: true, allowDeleting: true, allowEditing: true };
    }

    switchChange(args: ChangeEventArgs) {
        if (args.checked) {
            (this.grid as GridComponent).contextMenuModule.contextMenu.enableItems(['Copy'], false);
        } else {
            (this.grid as GridComponent).contextMenuModule.contextMenu.enableItems(['Copy'], true);
        }
    }

}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { ContextMenuService, PageService, EditService } from '@syncfusion/ej2-angular-grids';
import {
    ButtonModule,
    CheckBoxModule,
    RadioButtonModule,
    SwitchModule,
} from '@syncfusion/ej2-angular-buttons';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ButtonModule,
        CheckBoxModule,
        RadioButtonModule,
        SwitchModule,
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ContextMenuService, PageService, EditService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

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

Show or hide context menu items

The Syncfusion Angular Grid provides the flexibility to show or hide both default and custom context menu items. This feature allows you to customize the context menu items based on various conditions or individuals interactions.

This can be achieved using the showItems and hideItems methods of the context menu by specifying the item you want to show or hide as an argument.

In the following example, the EJ2 Toggle Switch Button component is added to show or hide the context menu items using showItems and hideItems methods. When the switch is toggled, the change event is triggered, and the Copy items is updated accordingly.

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

@Component({
  selector: 'app-root',
  template: `
    <div>
    <label style="padding: 10px 10px">
    Show or hide context menu items
    </label>
    <ejs-switch id="switch" (change)="switchChange($event)"></ejs-switch>
    </div>
    <ejs-grid  #grid style="padding: 10px 10px" [dataSource]='data' id="grid" allowPaging='true' height='265px'
            [contextMenuItems]="contextMenuItems" [editSettings]='editing' >
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' width='90' textAlign="Right" isPrimaryKey='true'></e-column>
                    <e-column field='CustomerID' headerText='Customer Name' width='100'></e-column>
                    <e-column field='Freight' headerText='Freight' format='C2' textAlign="Right" editType='numericedit' width='90'></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width='150'></e-column>
                </e-columns>
            </ejs-grid>`,
})
export class AppComponent implements OnInit {

  public data?: object[];
  public contextMenuItems?: ContextMenuItem[];
  @ViewChild('grid')
  public grid?: GridComponent;
  public editing?: EditSettingsModel;

  ngOnInit(): void {
    this.data = data;
    this.contextMenuItems = ['Copy', 'Edit', 'Delete'];
    this.editing = { allowAdding: true, allowDeleting: true, allowEditing: true };
  }

  switchChange(args: ChangeEventArgs) {
    if (args.checked) {
      (this.grid as GridComponent).contextMenuModule.contextMenu.hideItems([
        'Edit Record',
        'Delete Record',
      ]);
    } else {
      (this.grid as GridComponent).contextMenuModule.contextMenu.showItems([
        'Edit Record',
        'Delete Record',
      ]);
    }
  }

}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule } from '@syncfusion/ej2-angular-grids';
import { ContextMenuService, PageService, EditService } from '@syncfusion/ej2-angular-grids';
import {
    ButtonModule,
    CheckBoxModule,
    RadioButtonModule,
    SwitchModule,
} from '@syncfusion/ej2-angular-buttons';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule,
        ButtonModule,
        CheckBoxModule,
        RadioButtonModule,
        SwitchModule,
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [ContextMenuService, PageService, EditService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

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