Template and multilevel nesting in EJ2 JavaScript Context menu

4 Sep 202613 minutes to read

Item template

The itemTemplate property in the ContextMenu component allows you to define custom templates for displaying menu items within the context menu. This feature is especially useful when you want to customize the appearance or layout of the menu items beyond the default text-based list.

ej.base.enableRipple(true);

var menuItems = [
    {
        answerType: 'Selection',
        description: "Choose from options",
        iconCss: 'e-icons e-list-unordered'
    },
    {
        answerType: 'Yes / No',
        description: "Select Yes or No",
        iconCss: 'e-icons e-check-box'
    },
    {
        answerType: 'Text',
        description: "Type own answer",
        iconCss: 'e-icons e-caption',
        items: [
            {
                answerType: 'Single line',
                description: "Type answer in a single line",
                iconCss: 'e-icons e-text-form'
            },
            {
                answerType: 'Multiple line',
                description: "Type answer in multiple line",
                iconCss: 'e-icons e-text-wrap'
            }
        ]
    },
    {
        answerType: 'None',
        iconCss: 'e-icons e-mouse-pointer',
        description: "No answer required"
    }
];

var menuOptions = {
    target: '#contextmenutarget',
    items: menuItems,
    itemTemplate: "#cmenuTemplate",
    beforeOpen: function (args) {
        if (args.element.classList.contains('e-ul')) {
            args.element.classList.add('e-contextMenu-template');
        }
    }
};

var menuObj = new ej.navigations.ContextMenu(menuOptions, '#contextmenu');

if (ej.base.Browser.isDevice) {
    ej.base.select('#contextmenutarget').textContent = 'Right-click or touch and hold to open the Context Menu and select the answer type';
    menuObj.animationSettings.effect = 'ZoomIn';
} else {
    ej.base.select('#contextmenutarget').textContent = 'Right click/Touch hold to open the Context Menu and select the answer type';
    menuObj.animationSettings.effect = 'SlideDown';
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="description" content="Essential JS 2">
    <meta name="author" content="Syncfusion">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-buttons/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-lists/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-inputs/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-popups/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-navigations/styles/bootstrap5.3.css" rel="stylesheet">

    <!--style reference from app-->
    <link href="styles.css" rel="stylesheet">

    <!--system js reference and configuration-->
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/dist/ej2.min.js" type="text/javascript"></script>
</head>

<body>
    <div class="control-section" id="container">
        <div class="contextmenu-control">
            <div id='contextmenutarget'></div>
            <ul id='contextmenu' class="e-contextMenu-template"></ul>
            <script id="cmenuTemplate" type="text/x-template">
                <div class="menu-wrapper">
                    <span class="${iconCss} icon-right"></span>
                    <div class="text-content">
                        <span class="text">${answerType}</span>
                        <span class="description">${description}</span>
                    </div>
                </div>
            </script>
        </div>
    </div>
    <script>
        var ele = document.getElementById('container');
        if (ele) {
            ele.style.visibility = "visible";
        }   
    </script>
    <script src="index.js" type="text/javascript"></script>
</body>

</html>

Customize the specific menu items

ContextMenu items can be customized using the beforeItemRender event. The item render event triggers while each menu item is being rendered, and its event arguments are used to identify the menu item and customize it based on your requirement. In the following sample, each menu item is rendered with the associated keyboard shortcut for the specified action. Here, the keycode is specified for Save as, View page source, and Inspect in the right-side corner of the menu items by adding a span element in the beforeItemRender event.

ej.base.enableRipple(true);

var menuItems = [
    {
        text: 'Save as...'
    },
    {
        text: 'View page source'
    },
    {
        text: 'Inspect'
    }];
var menuOptions = {
        target: '#target',
        items: menuItems,
        beforeItemRender: beforeItemRender
    };

var menuObj = new ej.navigations.ContextMenu(menuOptions, '#contextmenu');

function beforeItemRender(args) {
    var shortCutSpan = ej.base.createElement('span');
    var text = args.item.text;
    var shortCutText = text === 'Save as...' ? 'Ctrl + S' : (text === 'View page source' ? 'Ctrl + U' : 'Ctrl + Shift + I');
    shortCutSpan.textContent = shortCutText;
    args.element.appendChild(shortCutSpan);
    shortCutSpan.setAttribute('class','shortcut');
}
<!DOCTYPE html><html lang="en"><head>
    <title>Essential JS 2</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="description" content="Essential JS 2">
    <meta name="author" content="Syncfusion">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-buttons/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-lists/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-inputs/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-popups/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-navigations/styles/bootstrap5.3.css" rel="stylesheet">

    <!--style reference from app-->
    <link href="styles.css" rel="stylesheet">

    <!--system js reference and configuration-->
    
    
<script src="https://cdn.syncfusion.com/ej2/34.2.2/dist/ej2.min.js" type="text/javascript"></script>
</head>

<body>
    
    <div id="container">
        <!--target element-->
        <div id="target">Right click / Touch hold to open the ContextMenu</div>
        <!--element which is going to render-->
        <ul id="contextmenu"></ul>
    </div>



<script>
var ele = document.getElementById('container');
if(ele) {
  ele.style.visibility = "visible";
}   
      </script>
<script src="index.js" type="text/javascript"></script>
</body></html>

To create the span element, use the createElement utility function from ej2-base.

Multilevel nesting

The ContextMenu supports multi-level nesting. It can be achieved by mapping the items property inside the parent’s items array. In the sample below, three-level nesting of the ContextMenu is provided.

<!DOCTYPE html><html lang="en"><head>
    <title>Essential JS 2</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="description" content="Essential JS 2">
    <meta name="author" content="Syncfusion">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-buttons/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-lists/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-inputs/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-popups/styles/bootstrap5.3.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-navigations/styles/bootstrap5.3.css" rel="stylesheet">

    <!--style reference from app-->
    <link href="styles.css" rel="stylesheet">

    <!--system js reference and configuration-->
    
    
<script src="https://cdn.syncfusion.com/ej2/34.2.2/dist/ej2.min.js" type="text/javascript"></script>
</head>

<body>
    
    <div id="container">
        <!--target element-->
        <div id="target">Right click / Touch hold to open the ContextMenu</div>
        <!--element which is going to render-->
        <ul id="contextmenu"></ul>
    </div>



<script>
var ele = document.getElementById('container');
if(ele) {
  ele.style.visibility = "visible";
}   
      </script>
<script src="index.js" type="text/javascript"></script>
</body></html>

To open sub menu items only on click, set the showItemOnClick property to true.

See Also