Search results

How To

Populate menu items with data source

To bind local data source to the ContextMenu, menu items are populated from data source and mapped to items property.

The below example demonstrates how to bind local data source to the ContextMenu.

Source
Preview
app.component.ts
app.module.ts
datasource.ts
main.ts
import { Component } from '@angular/core';
import { MenuEventArgs, MenuItemModel } from '@syncfusion/ej2-navigations';
import { Record, data } from './datasource';

@Component({
  selector: 'my-app',
  template: `<!--target element-->
            <div id="target">Right click / Touch hold to open the ContextMenu</div>

            <!-- To Render ContextMenu. -->
            <ejs-contextmenu id='contextmenu' target='#target' [items]= 'items'
            (beforeItemRender)='itemRender($event)'></ejs-contextmenu>`
})

export class AppComponent {
    public items: MenuItemModel[] = this.Items();
    public Items() {
    let record: Record;
    let menuItems: any[] = [];
    for (let i = 0; i < data.length; i++) {
        record = data[i] as Record;
        if (record.parentId) {
            if (!menuItems[record.parentId - 1].items) {
                menuItems[record.parentId - 1].items = []
            }
            menuItems[record.parentId - 1].items.push({ text: record.text });
        } else {
            menuItems.push({ text: record.text });
            }
        }
        return menuItems;
    }
    public itemRender(args: MenuEventArgs ) {
            if (!args.item.text) {
                args.element.classList.add('e-separator');
            }
        }
    }
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContextMenuModule } from '@syncfusion/ej2-ng-navigations';
import { ButtonModule } from '@syncfusion/ej2-ng-buttons';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        ContextMenuModule,
        ButtonModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
export let data: Record[] = [
    { id: 1, parentId: null, text: 'View' },
    { id: 2, parentId: null, text: 'Sort by' },
    { id: 3, parentId: null, text: 'New' },
    { id: 4, parentId: null, text: 'Display Settings' },
    { id: 5, parentId: null, text: 'Personalize' },
    //first level child
    { id: 6, parentId: 1, text: 'Large Icons' },
    { id: 7, parentId: 1, text: 'Medium Icons' },
    { id: 8, parentId: 1, text: 'Small Icons' },
    { id: 9, parentId: 2, text: 'Name' },
    { id: 10, parentId: 2, text: 'Size' },
    { id: 11, parentId: 4, text: 'Folder' },
    { id: 12, parentId: 4, text: 'Shortcut' },
    { id: 13, parentId: 4, text: 'Contact' }
];

export interface Record {
    id: number,
    parentId: number,
    text: string
}
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

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

Open and Close Context Menu

Open and close the ContextMenu manually whenever required by using open and close methods.

In the following sample, the ContextMenu is opened using the open method at the specified position with X and Y coordinates and to close the ContextMenu, close method is called internally on ContextMenu item click or document click.

Source
Preview
app.component.ts
app.module.ts
main.ts
import { Component } from '@angular/core';
import { MenuItemModel } from '@syncfusion/ej2-navigations';

@Component({
  selector: 'my-app',
  template: `<!-- To Render ContextMenu. -->
            <ejs-contextmenu id='contextmenu' [items]= 'menuItems'></ejs-contextmenu>
            <!-- To Render Button. -->
            <button ejs-button (click)="btnClick()">Open ContextMenu</button>`,
})

export class AppComponent  {
    // Initialize action items.
    public menuItems: MenuItemModel[] = [
        {
            text: 'Cut'
        },
        {
            text: 'Copy'
        },
        {
            text: 'Paste'
        }];

    btnClick(e) {
        var contextmenuObj = document.getElementById("contextmenu_0").ej2_instances[0];
        contextmenuObj.open(40, 20);
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContextMenuModule } from '@syncfusion/ej2-ng-navigations';
import { ButtonModule } from '@syncfusion/ej2-ng-buttons';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

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

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

Change menu items dynamically

The items visible in the ContextMenu can be changed dynamically based on the target in which you open the ContextMenu. To achieve this behavior, initialize ContextMenu with all items using items property and then based on the context you open hide/show required items using hideItems/ showItems method in beforeOpen event.

In the following example, the datasource for Clipboard div is Cut, Copy, Paste and for the Editor div is Add, Edit, Delete is changed on beforeOpen event using hideItems and showItems method.

Source
Preview
app.component.ts
app.module.ts
main.ts
import { Component, ViewChild } from '@angular/core';
import { MenuItemModel, BeforeOpenCloseMenuEventArgs, ContextMenuComponent } from '@syncfusion/ej2-navigations';

@Component({
  selector: 'my-app',
  template: `<!--target element-->
            <div id="target">
              <div id='left' class='e-div'>Clipboard</div>
              <div id='right' class='e-div'>Editor</div>
            </div>
            <!-- To Render ContextMenu. -->
            <ejs-contextmenu #contextmenu target='#target .e-div' [items]= 'menuItems' (beforeOpen)='beforeOpen($event)'></ejs-contextmenu>`
})

export class AppComponent {
    @ViewChild('contextmenu')
    public cmenu: ContextMenuComponent;
    // Initialize menu items.
    public menuItems: MenuItemModel[] = [
    {
        text: 'Cut'
    },
    {
        text: 'Copy'
    },
    {
        text: 'Paste'
    },
    {
        text: 'Add'
    },
    {
        text: 'Edit'
    },
    {
        text: 'Delete'
    }];

    public beforeOpen (args: BeforeOpenCloseMenuEventArgs) {
       // To hide/show items on right click.
       if ((args.event.target as HTMLElement).id === 'right') {
          this.cmenu.hideItems(['Cut', 'Copy', 'Paste']);
          this.cmenu.showItems(['Add', 'Edit', 'Delete']);
       } else if (args.event.target.id === 'left') {
          this.cmenu.showItems(['Cut', 'Copy', 'Paste']);
          this.cmenu.hideItems(['Add','Edit','Delete']);
       }
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContextMenuModule } from '@syncfusion/ej2-ng-navigations';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

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

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

Template

Show table in sub ContextMenu

Menu items of the ContextMenu can be customized according to the requirement. The section explains about how to customize table template in sub menu item.

This can be achieved by appending table layout while li rendering by using beforeItemRender event.

Source
Preview
app.component.ts
app.module.ts
main.ts
import { Component } from '@angular/core';
import { ContextMenu, BeforeOpenCloseMenuEventArgs, MenuEventArgs, MenuItemModel } from '@syncfusion/ej2-navigations';
import { createCheckBox } from '@syncfusion/ej2-buttons';
import { closest } from '@syncfusion/ej2-base';

@Component({
  selector: 'my-app',
  template: `
  <div id="target">Right click / Touch hold to open the ContextMenu</div>
  <ejs-contextmenu id='contextmenu' [target]='target' [items]= 'menuItems' (beforeItemRender)='itemRender($event)'></ejs-contextmenu>`
})

export class AppComponent  {
public target: string = '#target';

public menuItems: MenuItemModel[] = [
{
    text: 'Cut',
    iconCss: 'e-cm-icons e-cut'
},
{
    text: 'Copy',
    iconCss: 'e-icons e-copy'
},
{
    text: 'Paste',
    iconCss: 'e-cm-icons e-paste'
},
{
    separator: true
},
{
    text: 'Link',
    iconCss: 'e-icons e-link'
},
{
    text: 'Table',
    iconCss: 'e-icons e-table',
    items: [
        {
            id: 'table'
        }
    ]
}];

public itemRender(args:MenuEventArgs ) {
   if (args.item.id === 'table') {
     args.element.classList.add('bg-transparent');
     args.element.appendChild(this.createHeader());
     args.element.appendChild(this.createTable());
   }
}

public createHeader() {
  let header: HTMLElement = document.createElement('h4');
  header.textContent = 'Insert Table';
  return header;
}
public createTable() {
    let table: HTMLElement = document.createElement('table');
    for (let i: number = 0; i < 5; i++) {
        let row: HTMLElement = document.createElement('tr');
        table.appendChild(row);
    for (let j: number = 0; j < 6; j++) {
        let col: HTMLElement = document.createElement('td');
        row.appendChild(col);
    col.setAttribute('class', 'e-data');
    }
}
return table;
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContextMenuModule } from '@syncfusion/ej2-ng-navigations';
import { ButtonModule } from '@syncfusion/ej2-ng-buttons';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

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

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

Show UI components in ContextMenu

UI components can also be placed inside the each li element of ContextMenu.

In the following example, CheckBox component is placed inside each li element and this can be achieved by creating CheckBox component in beforeItemRender event and appending it into the li element.

Source
Preview
app.component.ts
app.module.ts
main.ts
import { Component } from '@angular/core';
import { ContextMenu, BeforeOpenCloseMenuEventArgs, MenuEventArgs, MenuItemModel } from '@syncfusion/ej2-navigations';
import { createCheckBox } from '@syncfusion/ej2-buttons';
import { closest } from '@syncfusion/ej2-base';

@Component({
  selector: 'my-app',
  template: `
  <div id="target">Right click / Touch hold to open the ContextMenu</div>
  <ejs-contextmenu id='contextmenu' [target]='target' [items]= 'menuItems' (beforeItemRender)='itemRender($event)' (beforeClose)='beforeClose($event)'></ejs-contextmenu>`
})

export class AppComponent  {
   public target: string = '#target';
   public menuItems: MenuItemModel[] = [
    { text: 'Option 1' },
    { text: 'Option 2' },
    { text: 'Option 3' }
   ];

    public beforeClose(args:BeforeOpenCloseMenuEventArgs ) {
        if (args.event.target.closest('.e-menu-item')) {
            args.cancel = true;
            let selectedElem: NodeList = args.element.querySelectorAll('.e-selected');
            for(let i:number=0; i < selectedElem.length; i++){
                let ele: Element = selectedElem[i];
                ele.classList.remove('e-selected');
            }
            let checkbox: HTMLElement = closest(args.event.target as Element, '.e-checkbox-wrapper') as HTMLElement;
            let frame: HTMLElement = checkbox.querySelector('.e-frame'));
            if (checkbox && frame.classList.contains('e-check')) {
                frame.classList.remove('e-check');
            } else if (checkbox) {
                frame.classList.add('e-check');
            }
        }
    }

    public itemRender(args: MenuEventArgs ) {
        let check: Element = createCheckBox(false, {
            label: args.item.text,
            checked: (args.item.text == 'Option 2') ? true : false
        });
        args.element.innerHTML = '';
        args.element.appendChild(check);
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContextMenuModule } from '@syncfusion/ej2-ng-navigations';
import { ButtonModule } from '@syncfusion/ej2-ng-buttons';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

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

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

Underline a character in the item text

To underline a particular character in a text, it can be handled in beforeItemRender event by adding <u> tag in between the text and given as innerHTML in li rendering.

Source
Preview
app.component.ts
app.module.ts
main.ts
import { Component } from '@angular/core';
import { MenuItemModel, MenuEventArgs } from '@syncfusion/ej2-navigations';

@Component({
  selector: 'my-app',
  template: `<div id="target">Right click / Touch hold to open the ContextMenu</div>
            <ejs-contextmenu id='contextmenu' target='#target' [items]= 'menuItems' (beforeItemRender)='itemRender($event)'></ejs-contextmenu>`
})

export class AppComponent {
    public menuItems: MenuItemModel[] = [
        {
            text: 'Cut'
        },
        {
            text: 'Copy'
        },
        {
            text: 'Paste'
        }];
    public itemRender(args: MenuEventArgs ) {
       if (args.item.text === "Copy") {
            args.element.innerHTML = '<u>C</u>opy';
       }
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContextMenuModule } from '@syncfusion/ej2-ng-navigations';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

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

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

Open a dialog on ContextMenu item click

This section explains about how to open a dialog on ContextMenu item click. This can be achieved by handling dialog open in select event of the ContextMenu.

In the following sample, Dialog will open while clicking Save As... item:

Source
Preview
app.component.ts
app.module.ts
main.ts
import { Component, ViewChild } from '@angular/core';
import { MenuItemModel, MenuEventArgs } from '@syncfusion/ej2-navigations';
import { DialogComponent } from '@syncfusion/ej2-ng-popups';

@Component({
  selector: 'my-app',
  template: `<div id="target">Right click / Touch hold to open the ContextMenu</div>
  <ejs-dialog #dialog [buttons]='alertDlgButtons' [visible]='visible' content='This file can be saved as PDF' width='200px' height='110px' [position]='position'>
  </ejs-dialog>
  <ejs-contextmenu target="#target" [items]="data" (select)="itemSelect($event)"></ejs-contextmenu>`
})

export class AppComponent {
  @ViewChild('dialog')
  public alertDialog: DialogComponent;

  name = 'Angular';
  data= [
  {
    text: 'Back'
  },
  {
    text: 'Forward'
  },
  {
    text: 'Reload'
  },
  {
    separator: true
  },
  {
    text: 'Save As...'
  },
  {
    text: 'Print'
  },
  {
    text: 'Cast'
  }
  ];

  public visible: Boolean = false;

  public position: any = {X: 100, Y: 100};

  public alertDlgButtons: Object[] = [{
        buttonModel: {
            isPrimary: true,
            content: 'Submit',
            cssClass: 'e-flat',
        },
        click: function () {
            this.hide();
        }
    }];

  public itemSelect(args: MenuEventArgs): void {
    if (args.item.text === "Save As...") {
      this.alertDialog.show();
    }
  }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContextMenuModule } from '@syncfusion/ej2-ng-navigations';
import { DialogModule } from '@syncfusion/ej2-ng-popups';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

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

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

Change animation settings

To change the animation of the ContextMenu, animationSettings property is used. The supported effects for ContextMenu are,

Effect Functionality
None Specifies the sub menu transform with no animation effect.
SlideDown Specifies the sub menu transform with slide down effect.
ZoomIn Specifies the sub menu transform with zoom in effect.
FadeIn Specifies the sub menu transform with fade in effect.

The following sample illustrates how to open ContextMenu with FadeIn effect with the duration of 800ms.

Source
Preview
app.component.ts
app.module.ts
main.ts
import { Component } from '@angular/core';
import { createElement } from '@syncfusion/ej2-base';
import { MenuItemModel } from '@syncfusion/ej2-navigations';

@Component({
  selector: 'my-app',
  template: `<!--target element-->
            <div id="target">Right click / Touch hold to open the ContextMenu</div>
            <!-- To Render ContextMenu. -->
            <ejs-contextmenu id='contextmenu' #contextmenu target='#target' [items]='menuItems' [animationSettings]='animation'></ejs-contextmenu>`
})

export class AppComponent {
    public animation = {
        effect: 'FadeIn',
        duration: 800
    };
    public menuItems: MenuItemModel[] = [
        {
            text: 'Show All Bookmarks'
        },
        {
            text: 'Bookmarks Toolbar',
            items: [
                {
                    text: 'Most Visited',
                    items:[
                        {
                            text: 'Gmail'
                        },
                        {
                            text: 'Google'
                        }
                    ]
                },
                {
                    text: 'Recently Added'
                }
            ]
        }];

}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContextMenuModule } from '@syncfusion/ej2-ng-navigations';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

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

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