LIDOR SYSTEMS

Advanced User Interface Controls and Components

Overview of IntegralUI ContextMenu for Angular 2

Created: 20 September 2016

Updated: 24 March 2017

IntegralUI ContextMenu is a native Angular 2 directive that sllows you to attach a custom context menu to any HTML element or Angular 2 component. Whenever element is right-clicked, a context menu will popup showing data provided on your side. In following sections, you can find details about various features available in the ContextMenu directive.

ContextMenu component is part of IntegralUI Web
a suite of UI Components for development of web apps

In above demonstration, whenever the block is right-clicked, a context menu will appear with options from where you can change the font style of the block content. These options are divided in two groups using a separator. Options in the first group have a checkbox, while in the second have a radio button. Depending on which option is active, the font style of the block content changes accordingly.

How to Use IntegralUI ContextMenu in Angular 2

The ContextMenu directive is simple to use. You only need to apply the directive name to the HTML element and set its behavior using these properties:

  • settings - specifies an object that holds all options available

All above properties are specified using an object that is applied to the directive name. For example:

//

// main.ts file

//

 

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

 

const platform = platformBrowserDynamic();

platform.bootstrapModule(AppModule);

 

 

 

//

// app.module.ts file

//

 

import { NgModule } from '@angular/core';

import { FormsModule } from '@angular/forms';

import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

import { IntegralUIModule } from 'integralui/integralui.module';

 

@NgModule({

imports: [ BrowserModule, FormsModule, IntegralUIModule ],

declarations: [ AppComponent ],

bootstrap: [ AppComponent ]

})

export class AppModule { }

 

 

 

//

// app.component.ts file

//

 

import { Component, ViewContainerRef, ViewChild } from '@angular/core';

 

@Component({

selector: 'iui-app',

templateUrl: 'app.template.html',

styleUrls: ['contextmenu-overview.css']

})

export class AppComponent {

// Get a reference of application view

@ViewChild('application', {read: ViewContainerRef}) applicationRef: ViewContainerRef;

 

// ContextMenu settings

private menuSettings = {

appRef: null,

items: []

}

 

// Font settings that are applied to the block element

private fontWeight = 'bold';

private fontStyle = 'normal';

private fontSize = '1';

private textDecoration = 'none';

 

constructor(){

}

 

// Initialize items after application view is initialized

ngAfterViewInit(){

this.menuSettings = {

appRef: this.applicationRef,

items: [

{ id: 2, text: "Bold", icon: 'icons-medium check-mark', checked: true },

{ id: 3, text: "Italic", icon: 'icons-medium empty' },

{ id: 4, text: "Strikethrough", icon: 'icons-medium empty' },

{ id: 5, type: "separator" },

{ id: 6, text: "x1", icon: 'icons-medium radio-mark-filled' },

{ id: 7, text: "x1.5", icon: 'icons-medium radio-mark-empty' },

{ id: 8, text: "x2", icon: 'icons-medium radio-mark-empty' }

]

}

}

 

// Handle clicks from menu items. Depending on their id, a different action is executed

menuItemClick(e){

if (e.item){

if (e.item.id < 5)

e.item.checked = e.item.checked != undefined ? !e.item.checked : true;

else

e.item.checked = true;

 

switch (e.item.id){

case 2:

this.fontWeight = e.item.checked != false ? 'bold' : 'normal';

break;

case 3:

this.fontStyle = e.item.checked != false ? 'italic' : 'normal';

break;

case 4:

this.textDecoration = e.item.checked != false ? 'line-through' : 'none';

break;

case 6:

this.fontSize = e.item.checked != false ? '1' : '1';

break;

case 7:

this.fontSize = e.item.checked != false ? '1.5' : '1';

break;

case 8:

this.fontSize = e.item.checked != false ? '2' : '1';

break;

}

 

if (e.item.id < 5)

e.item.icon = e.item.checked != false ? 'icons-medium check-mark' : 'icons-medium empty';

else {

for (let i = 4; i < this.menuSettings.items.length; i++){

if (this.menuSettings.items[i] != e.item)

this.menuSettings.items[i].checked = false;

 

this.menuSettings.items[i].icon = this.menuSettings.items[i].checked != false ? 'icons-medium radio-mark-filled' : 'icons-medium radio-mark-empty';

}

}

}

}

}

 

bootstrap(AppComponent);

//

// app.template.html file

//

 

<div #application class="block" [iuiContextMenu]="menuSettings" (itemClick)="menuItemClick($event)" [ngStyle]="{ 'font-weight': fontWeight, 'font-style': fontStyle, 'font-size': fontSize + 'em', 'text-decoration': textDecoration }">

<span>Right click to open the context menu</span>

</div>

/*

contextmenu-overview.css file

*/

.block

{

background: white;

border: thin solid gray;

width: 600px;

height: 300px;

}

.block span

{

color: #808080;

cursor: default;

display: block;

margin: 130px auto;

text-align: center;

}

.icons-medium

{

background: url(../resources/icons-x24.png) no-repeat 0 0;

display: inline-block;

overflow: hidden;

padding: 0;

margin: 0 7px 0 1px;

width: 24px;

height: 24px;

vertical-align: middle;

}

.check-mark

{

background-position: -192px -120px;

}

.radio-mark-empty

{

background-position: -192px -144px;

}

.radio-mark-filled

{

background-position: -216px -144px;

}

Note Multi leveling is supported, you only need to add a list of child items to the specified menu item.

As you can see from above HTML code, we are using the iuiContextMenu name to attach a context menu to the <div> block. To bind the object that holds the menu settings, we only need to enclose the directive name with standard Angular binding brackets []. Next, you need to apply the object to the right of the directive name.

To apply data to the context menu, you can use the items field of the menu settings object. When creating your data structure, make sure that each item has at least these fields set:

  • icon - specifies the icon that is displayed in front of item label
  • id - specifies a unique identifier for the item
  • items - holds a reference to the list of child items, used for multi-leveling
  • pid - specifies the identifier of parent item of this item
  • text - specifies the item label
  • type - specifies the item type

Note Item type can contain one of the following values: 'item' or 'separator'. By default, all items are of 'item' type, so this value is not necessary.

In this example, we have 7 menu items, of which only one item act as separator. When item is set as separator, it cannot be clicked or hovered.

Supported Events

When interacting with the ContextMenu component, depending on the action, a corresponding event is fired. For example clicking an item will fire itemClick event, opening or closing of the menu will fire the opened or closed events, etc.

Here is a list of available events:

  • itemClick - occurs when menu item is clicked

By handling these events in your code, you can add custom actions that may alter the default behavior of the ContextMenu component. For example, by handling the itemClick event, you can add a specific action that will execute when item is clicked (see above code for menuItemClick).

In this example, the same event handler is used for all items. Depending on the item id, a various action takes place:

  • The font of block content is set to bold, italic or strikeout
  • The font size changes by x1, x1.5 or x2 factor

In addition, depending on which option is active, a corresponding icon is applied: a check mark or a radio button mark.

How to Customize the ContextMenu Appearance

Each part of IntegralUI ContextMenu component is fully customizable. There are different CSS classes for each component part. Although changing the attributes of built-in classes is possible, you can completely override them using the controlStyle property.

The controlStyle property accepts an object that holds all or partial list of CSS class names that will override the default CSS class names. For each component part, a different CSS class governs its appearance. This allows you to specify a set of different CSS classes for each component part and alter the appearance of the ContextMenu in whole. In this way, you can make it more suitable for your application requirements.

Conclusion

IntegralUI ContextMenu component allows you to create and apply a custom context menu to HTML elements or other Angular components that may need one. You can use an arbitrary data to populate the context menu, either from local or remote data source. You can customize the appearance of context menu by specifying custom CSS classes to the controlStyle property.

Multi leveling is supported, by applying a tree hierarchy as a data source. You can have a context menu with options in multiple levels.

By default, each item contains an icon and a label. Future versions will allow you to specify a template where you can add any custom HTML elements or Angular 2 components.

The ContextMenu component is part of IntegralUI Web.

Did you Like this Article?


Enter your e-mail address below and you will receive latest articles as well as news on upcoming events and special offers.