LIDOR SYSTEMS

Advanced User Interface Controls and Components

Multi Level Context Menu in AngularJS

Created: 04 September 2015

Usually most of context menu are single level menus. When context menu contains many options, it is better to create a multi level context menu. IntegralUI ContextMenu is a native AngularJS directive that allows you to create cascading context menus of multiple layers. This directive when attached to a HTML element, will create a context menu that will appear whenever the element is right-clicked.

The demonstration below displays a multi-level context menu, with different kinds of menu items: header, item and separator. Whenever the HTML element (in our case a simple div element) is right-clicked, a context menu will popup.

Related: AngularJS Context Menu to Custom HTML Elements

Right click to open the context menu
ContextMenu directive is part of IntegralUI Studio for Web
a suite of UI Components for development of web apps

How to Create Multi Level Context Menu

As above demo shows, we have a context menu with submenus attached to specific menus. Whenever mouse cursor hovers longer than 500ms over a menu item, a submenu will appear, if it is present. By default, submenus at subsequent levels appear to the right of their parent menu.

Note By setting the rtl property value to true, submenus will appear on the left side.

Similar: Dark Colored Angular Context Menu

The data structure of context menu that consists of multiple layers is simple. Each menu item is represented by an item object, which contains information about item's id, icon, label, type, key etc. A submenu is represented by an array of menu item objects applied to the specific parent menu item object. Here how this looks like in AngularJS code:

angular

.module("appModule", ["integralui"])

.controller("appCtrl", function($scope){

// ContextMenu data source

$scope.data = [

{ id: 1, text: "Context Menu", type: "header" },

{

id: 2,

text: "New",

icon: "icons-medium new-document",

items: [

{ id: 21, pid: 1, text: "Project", icon: "icons-medium solution" },

{ id: 22, pid: 1, text: "Window" }

]

},

{ id: 3, text: "Open" },

{ id: 4, text: "Save As...", icon: "icons-medium save" },

{ id: 5, text: "Save All" },

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

{

id: 7,

text: "Social",

icon: "icons-medium people",

items: [

{ id: 71, pid: 1, text: "Facebook", icon: "icons-medium facebook" },

{ id: 72, pid: 1, text: "Google Plus", icon: "icons-medium google-plus" },

{ id: 73, pid: 1, text: "Twitter", icon: "icons-medium twitter" }

]

},

{ id: 8, text: "Favorites" },

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

{ id: 10, text: "Page Setup" },

{ id: 11, text: "Print", icon: "icons-medium print" },

];

 

// Settings for ContextMenu

$scope.menuOptions = {

itemIcon: 'icons-medium empty',

items: $scope.data

}

});

<!DOCTYPE html>

<html>

<head>

<link rel="stylesheet" href="css/integralui.contextmenu.css" />

<link rel="stylesheet" href="css/themes/theme-flat-blue.css" />

<script type="text/javascript" src="external/angular.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.contextmenu.min.js"></script>

</head>

<body>

<div ng-app="appModule" ng-controller="appCtrl">

<div class="block" iui-contextmenu="menuOptions">

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

</div>

</div>

</body>

</html>

/* Div CSS styles */

.block

{

background: #f5f5f5;

border: thin solid gray;

margin: 20px auto;

padding: 20px;

width: 300px;

height: 75px;

}

.block span

{

color: #808080;

cursor: default;

display: block;

margin: 30px auto;

text-align: center;

}

 

/* ContextMenu Directive CSS styles */

.iui-contextmenu-item

{

width: 150px;

}

.iui-contextmenu-item-header

{

background: #1e4691;

border-radius: 3px;

color: white;

padding: 5px 0;

text-align: center;

}

.header-item

{

margin-top: 2px;

}

Note You can create infinite levels of context menus, as long there is a space to show them.

Context Menu directive is fully customizable. For each part of the menu, there are corresponding CSS classes. By modifying attributes of these classes, you can create custom multi-level context menus in your application. In our demonstration, some of these classes are modifying in themes-flat-blue theme and as part of this sample.

Different Types of Context Menu Items

Each context menu item can be one of following types:

  • header - non-clickable menu item which provides group information about subsequent items
  • item - a clickable normal menu item
  • separator - non-clickable menu item used to divide the content of context menu in multiple groups

As above demo shows, there are few headers and separators, while majority of menu items are normal clickable items.

Note To change the menu item type, just change item's type field value.

How to Handle Clicks on Menu Items

Whenever a menu item is clicked, the itemClick event is fired. This event can be handled in your app code, by adding an event handler. You can use the same event handler for all menu items, and to distinguish which item is clicked, use the item's key field to set a unique value. For example:

$scope.menuOptions = {

items: $scope.data,

itemClick: function(e){

alert("Menu Item: " + e.item.text + " is clicked.");

}

}

In our case itemClick event handler is added to the menuOptions and it will fire for all clickable menu items. You can also add an individual event handler for this event, by addign a function to the itemClick field of menu item object.

In our example, whenever a menu item is clicked a popup window will appear showing a message stating the clicked menu item.

The complete source code of this demo is available as part of IntegralUI Studio for Web.

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.