LIDOR SYSTEMS

Advanced User Interface Controls and Components

AngularJS Context Menu to Custom HTML Elements

Created: 26 February 2015

By default HTML elements don’t have a context menu, and whenever a user clicks over element space using the right mouse button, the standard context menu for html page appears. In order to solve this problem, we can handle the right-click mouse button event and set to appear a custom popup window which will function as a context menu. However, this is time consuming process.

The ContextMenu directive for AngularJS solves this problem. It allows you to easily create and add a custom context menu to any other HTML element or directive. In following sections of this article we will show you how to create and add a different context menu to several different HTML elements: a button, an input element and a standard block element.

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

Similar: Custom ContextMenu Component for Angular 4

The use of ContextMenu directive is very simple. This directive is an attribute only directive, which means that it cannot act on its own, and must be applied to an existing HTML element or other directive in the DOM. Here is basic declaration of this directive:

<div iui-contextmenu menu-items="menuItems"></div>

As it can be seen from above declaration, in order to add menu items to the context menu directive we are using the menu-items attribute. This attribute accepts any array with menu item objects with following fields:

  • key – an unique key used to distigues the menu item object from other menu items
  • text – the title of the menu item
  • type – type of the menu item, it can be: header, separator or item
  • enabled – determines whether menu item is enabled or disabled
  • itemClick – a function which is called whenever a menu item is clicked

Here is an example:

// Context menu

$scope.menuItems = [

{ text: "Container", type: "header" },

{ key: "MENU_ITEM1", text: "Menu Item 1", itemClick: function(e){ alert('Menu Item 1 clicked!') } },

{ key: "MENU_ITEM2", text: "Menu Item 2", itemClick: function(e){ alert('Menu Item 2 clicked!'} },

{ key: "MENU_ITEM3", text: "Menu Item 3", itemClick: function(e){ alert('Menu Item 3 clicked!') } }

]

The itemClick function has one parameter e, which contains the menu item object. By using this object, we can determine which item is clicked. Let’s see how this works with real example.

Related: How to Display Context Menu in TreeView AngularJS

HTML Input Element with a ContextMenu

In case of input element, we will create a context menu which will copy/paste the text of the input field.

<input type="text" iui-contextmenu menu-items="editContextMenu" ng-model="sampleText" ng-disabled="editDisabled" ng-hide="isHidden"/>

An example of context menu for the input element:

$scope.sampleText = "Hello World!";

$scope.editDisabled = false;

$scope.isHidden = false;

 

// Context menu for input element

$scope.editContextMenu = [

{ text: "Text Editor", type: "header" },

{ key: 'EDIT_CUT', text: "Cut", itemClick: function(e){ return $scope.processEditClicks(e.item); } },

{ key: 'EDIT_COPY', text: "Copy", itemClick: function(e){ return $scope.processEditClicks(e.item); } },

{ key: 'EDIT_PASTE', text: "Paste", itemClick: function(e){ return $scope.processEditClicks(e.item); } }

]

 

// A function which processes all clicks in context menu for a input element

$scope.processEditClicks = function(item){

if (item){

if (localStorage){

switch (item.key){

case 'EDIT_CUT':

localStorage.setItem("sampleText", $scope.sampleText);

$scope.sampleText = '';

$scope.$apply();

break;

 

case 'EDIT_COPY':

localStorage.setItem("sampleText", $scope.sampleText);

break;

 

case 'EDIT_PASTE':

$scope.sampleText = localStorage.getItem("sampleText");

$scope.$apply();

break;

}

}

}

}

Depending on which menu item is clicked, the value of input field will be cut, copy or paste. Instead of using the window clipboard in our case we are using the HTML5 local storage functionality.

HTML Button Element with a ContextMenu

In case of a button element, in order to assign a context menu to it, we need to set the ContextMenu directive in the button declaration:

<button type="button" iui-contextmenu menu-items="btnContextMenu" ng-hide="isHidden">Button</button>

And the structure of context menu for the button will look like:

// Context menu data for Button

$scope.btnContextMenu = [

{ text: "Button", type: "header" },

{ key: 'EDIT_ENABLE', text: "Enable Editor", enabled: false, itemClick: function(e){ return $scope.processButtonClicks(e.item); } },

{ key: 'EDIT_DISABLE', text: "Disable Editor", itemClick: function(e){ return $scope.processButtonClicks(e.item); } },

{ type: "separator" },

{ key: 'EDIT_RESET', text: "Reset", itemClick: function(e){ return $scope.processButtonClicks(e.item); } }

]

 

// A function which processes all clicks in context menu for a button element

$scope.processButtonClicks = function(item){

if (item){

switch (item.key){

case 'EDIT_ENABLE':

$scope.editDisabled = false;

$scope.$apply();

 

item.enabled = false;

$scope.btnContextMenu[2].enabled = true;

break;

 

case 'EDIT_DISABLE':

$scope.editDisabled = true;

$scope.$apply();

 

item.enabled = false;

$scope.btnContextMenu[1].enabled = true;

break;

 

case 'EDIT_RESET':

$scope.sampleText = 'Hello World!';

$scope.editDisabled = false;

$scope.$apply();

 

$scope.btnContextMenu[1].enabled = false;

$scope.btnContextMenu[2].enabled = true;

break;

}

}

}

In our example, whenever a menu item from context menu of the button is clicked, input element will become enabled, disabled or restored to initial settings.

HTML Div Element with a ContextMenu

At last the input and button elements are placed inside a container element (we are using the <div> element).

<div class="block" iui-contextmenu menu-items="blockContextMenu">

<input type="text" iui-contextmenu menu-items="editContextMenu" ng-model="sampleText" ng-disabled="editDisabled" ng-hide="isHidden"/>

<button type="button" iui-contextmenu menu-items="btnContextMenu" ng-hide="isHidden">Button</button>

</div>

.block

{

background: #f5f5f5;

border: thin solid gray;

padding: 20px;

width: 300px;

height: 75px;

}

For this element we are going to use a different context menu, which looks like:

// Context menu for Div element

$scope.blockContextMenu = [

{ text: "Container", type: "header" },

{ key: 'ELEM_SHOW', text: "Show Content", enabled: false, itemClick: function(e){ return $scope.processContainerClicks(e.item); } },

{ key: 'ELEM_HIDE', text: "Hide Content", itemClick: function(e){ return $scope.processContainerClicks(e.item); } }

]

 

// A function which processes all clicks in context menu for a div element

$scope.processContainerClicks = function(item){

if (item){

switch (item.key){

case 'ELEM_SHOW':

$scope.isHidden = false;

$scope.$apply();

 

item.enabled = false;

$scope.blockContextMenu[2].enabled = true;

break;

 

case 'ELEM_HIDE':

$scope.isHidden = true;

$scope.$apply();

 

item.enabled = false;

$scope.blockContextMenu[1].enabled = true;

break;

}

}

}

This context menu shows or hides the child elements of the div element. For this purpose, we are using the isHidden variable in our application scope, which is linked to the ng-hide attribute of input and button elements.

As it is shown in above demonstration, whenever a right-click is made over input, button or div element, different context menu will pop-up. The appearance of the menu is determined by small set of CSS styles which can be changed and further customized to better match the appearance of your application.

Newsletter


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.