Search results

Template in JavaScript Context Menu control

31 Mar 2023 / 3 minutes to read

Render UL and LI template

Add the HTML UL tag with id attribute as #contextmenu in your index.html file with required LI tags and also add target element on which the ContextMenu has to be opened.

Source
Preview
app.ts
index.html
styles.css
Copied to clipboard
import { ContextMenu } from '@syncfusion/ej2-navigations';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);
// To Initialize ContextMenu component.
let menuObj: ContextMenu = new ContextMenu({ target: '#target' }, '#contextmenu');
Copied to clipboard
<!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="//cdn.syncfusion.com/ej2/21.1.35/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-navigations/styles/material.css" rel="stylesheet" />

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

    <!--system js reference and configuration-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>LOADING....</div>
    <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" class='list'>
            <li>Cut</li>
            <li>Copy</li>
            <li>Paste</li>
        </ul>
    </div>
</body>

</html>
Copied to clipboard
#loader {
  color: #008cff;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}

#container {
  visibility: hidden;
}

.list {
  display: none;
}

#target {
  border: 1px dashed;
  height: 150px;
  padding: 10px;
  position: relative;
  text-align: justify;
  color: gray;
  user-select: none;
}

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.ts
index.html
styles.css
Copied to clipboard
import { Browser } from '@syncfusion/ej2-base';
import { ContextMenu, MenuEventArgs, BeforeOpenCloseMenuEventArgs } from '@syncfusion/ej2-navigations';
import { MenuItemModel, ContextMenuModel } from '@syncfusion/ej2-navigations';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

// To create header element.
let header: HTMLElement = document.createElement('h4');
header.textContent = 'Insert Table';

// To create table with five rows and six columns.
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-border');
}
}

// Initialize menu items.
let 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'
            }
        ]
    }];

// Initialize ContextMenu options.
let menuOptions: ContextMenuModel = {
    target: '#target',
    items: menuItems,
    beforeItemRender: (args: MenuEventArgs) => {
      // To append table on `li` rendering.
      if (args.item.id === 'table') {
        args.element.classList.add('bg-transparent');
        args.element.appendChild(header);
        args.element.appendChild(table);
      }
    }
};

// Initialize ContextMenu component.
let menuObj: ContextMenu = new ContextMenu(menuOptions, '#contextmenu');
Copied to clipboard
<!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="//cdn.syncfusion.com/ej2/21.1.35/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-lists/styles/material.css" rel="stylesheet" />

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

    <!--system js reference and configuration-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
    .e-contextmenu-wrapper ul .e-menu-item.bg-transparent {
        background-color: transparent;
        line-height: normal;
        height: auto;
      }
      h4 {
        text-align: center;
        margin-top: 5px;
        margin-bottom: 5px;
      }
    </style>
</head>

<body>
    <div id='loader'>LOADING....</div>
    <div id='container'>
        <div id="target">Right click / Touch hold to open the ContextMenu</div> 
        <ul id="contextmenu"></ul>
    </div>
</body>
</html>
Copied to clipboard
#loader {
  color: #008cff;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}

#container {
  visibility: hidden;
}

.list {
  display: none;
}

.e-border {
  border: 1px solid rgba(0, 0, 0, 0.87);
  padding: 8px;
}

#target {
  border: 1px dashed;
  height: 150px;
  padding: 10px;
  position: relative;
  text-align: justify;
  color: gray;
  user-select: none;
}

@font-face {
font-family: 'ddb-icons';
src:
url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAKAIAAAwAgT1MvMj0gSRkAAAEoAAAAVmNtYXDnE+dkAAABlAAAADxnbHlmlh33NQAAAdwAAAJMaGVhZBKOK9sAAADQAAAANmhoZWEHeANwAAAArAAAACRobXR4E6AAAAAAAYAAAAAUbG9jYQGOAegAAAHQAAAADG1heHABEwBlAAABCAAAACBuYW1l1LBM9QAABCgAAAI9cG9zdMJntbUAAAZoAAAAUAABAAADUv9qAFoEAAAAAAADygABAAAAAAAAAAAAAAAAAAAABQABAAAAAQAAojXaQl8PPPUACwPoAAAAANfSc4gAAAAA19JziAAA//oDygPsAAAACAACAAAAAAAAAAEAAAAFAFkABAAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQPtAZAABQAAAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA5wDnAwNS/2oAWgPsAJYAAAABAAAAAAAABAAAAAPoAAAD6AAAA+gAAAPoAAAAAAACAAAAAwAAABQAAwABAAAAFAAEACgAAAAEAAQAAQAA5wP//wAA5wD//wAAAAEABAAAAAEAAgADAAQAAAAAAI4AwgEAASYAAwAA//oDNQPsAA4AHQBYAAAlHgEOAScmJy4BNz4BMzIFFgYHBgcGLgE2NzYzMhYBHgEXDgEHDgEHDgIWFxYXFjY3NjQ3PgE3HgEXFhQXHgE3PgE3PgEuAScuAScuASc+ATc+AQcLASYWAVEfFxo6IBkNCQIHCy8bCQG9BwIJDRkgOhoXHwoKGi/+TR1RDyEOIxo+ExckFAQMFikwVhcMBwYlFRYkBwcMF1YwFCALDAQUIxcUPhojDiAOUR4cAQvEwwsB6gtDTycJCBsSKxYhJ0gWKxIaCQknUEILAycCf2TPI0w2HBUmDg0sOzsaKQ4ONzcniyYXNBgYNBcmiyc3OA8GHRQaOzssDQ4mFRw2TiLOZGdBA/5vAZEDQQAEAAAAAAOqA+kABQANABcAHwAAARUzFSERAyERIzUjNSEBIREhESMVITUjMyMVITUjNSMC733+iT8B9D4+/oj+igE4AXc//c4++j8BOT+7AbZ8+gF2/ksBdz4//ksB9AF2fHw+Pj8AAAIAAAAAA7cD6QACACQAAAEhEwMOAQcVITUmJyY1ND8BIRcWFxYVFAcGKwEVITUmJyYnASMCKP8AguQrOy0BGkIRHREkASstEgEEDhQxEQGaJxUcLP7PDAFNAVL+PHBHCBsbBgsUKR8wX3owBg4NFgsQGxsDFx1zAyMAAAACAAAAAAPKA+oAAgATAAABFxEBDgEHHgEXETMRMxEzETM1IQL+zP1abpADA5t0f2F+XP41AfbMAZgBJwmYcHSbA/48A2r8lgNqfgAAAAASAN4AAQAAAAAAAAABAAAAAQAAAAAAAQAJAAEAAQAAAAAAAgAHAAoAAQAAAAAAAwAJABEAAQAAAAAABAAJABoAAQAAAAAABQALACMAAQAAAAAABgAJAC4AAQAAAAAACgAsADcAAQAAAAAACwASAGMAAwABBAkAAAACAHUAAwABBAkAAQASAHcAAwABBAkAAgAOAIkAAwABBAkAAwASAJcAAwABBAkABAASAKkAAwABBAkABQAWALsAAwABBAkABgASANEAAwABBAkACgBYAOMAAwABBAkACwAkATsgZGRiLWljb25zUmVndWxhcmRkYi1pY29uc2RkYi1pY29uc1ZlcnNpb24gMS4wZGRiLWljb25zRm9udCBnZW5lcmF0ZWQgdXNpbmcgU3luY2Z1c2lvbiBNZXRybyBTdHVkaW93d3cuc3luY2Z1c2lvbi5jb20AIABkAGQAYgAtAGkAYwBvAG4AcwBSAGUAZwB1AGwAYQByAGQAZABiAC0AaQBjAG8AbgBzAGQAZABiAC0AaQBjAG8AbgBzAFYAZQByAHMAaQBvAG4AIAAxAC4AMABkAGQAYgAtAGkAYwBvAG4AcwBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIAB1AHMAaQBuAGcAIABTAHkAbgBjAGYAdQBzAGkAbwBuACAATQBlAHQAcgBvACAAUwB0AHUAZABpAG8AdwB3AHcALgBzAHkAbgBjAGYAdQBzAGkAbwBuAC4AYwBvAG0AAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAQIBAwEEAQUBBgADY3V0CHBhc3RlXzAxBGZvbnQOcGFyYS1tYXJrLS0tMDMAAA==) format('truetype');
font-weight: normal;
font-style: normal;
}

.e-cm-icons {
 font-family: 'ddb-icons' !important;
speak: none;
font-size: 55px;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.e-cut::before {
  content: '\e700';
}

.e-copy::before {
  content: '\e70a';
}

.e-paste::before {
  content: '\e701';
}

.e-link::before {
  content: '\e290';
}

.e-table::before {
  content: '\e705';
}

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.ts
index.html
styles.css
Copied to clipboard
import { closest, enableRipple} from '@syncfusion/ej2-base';
import { ContextMenu, MenuEventArgs, BeforeOpenCloseMenuEventArgs } from '@syncfusion/ej2-navigations';
import { ContextMenuModel, MenuItemModel } from '@syncfusion/ej2-navigations';
import { CheckBox } from '@syncfusion/ej2-buttons';

enableRipple(true);

// Initialize menu items.
let menuItems: MenuItemModel[] = [
    { text: 'Option 1' },
    { text: 'Option 2' },
    { text: 'Option 3' }
];

let i = 1;
// Initialize ContextMenu options.
let menuOptions: ContextMenuModel = {
    target: '#target',
    items: menuItems,
    beforeItemRender: (args: MenuEventArgs) => {
        // To render CheckBox component on each li.
        let checkbox: CheckBox = new CheckBox({ label: 'Option'+  i, checked: i%2 === 0 ? true : false });
        args.element.innerHTML = '';
        checkbox.appendTo('#checkbox'+i);
        let checkboxObj = document.getElementsByClassName('e-checkbox-wrapper');
        args.element.appendChild(checkboxObj[0]);
        i++;
    },
    beforeClose: (args: BeforeOpenCloseMenuEventArgs) => {
        if ((args.event.target as HTMLElement).closest('.e-menu-item')) {
            // To prevent ContextMenu close on item click.
            args.cancel = true;
        }
    },
    select: (args: MenuEventArgs) => {
        let selectedElem: NodeList = args.element.parentElement.querySelectorAll('.e-selected');
        for (let i:number=0; i < selectedElem.length; i++) {
           let ele: Element = selectedElem[i] as Element;
           ele.classList.remove('e-selected');
        }
        let checkbox: HTMLElement = args.element.childNodes[0] as HTMLElement;
        let frame: Element = checkbox.querySelector('.e-frame');
        if (checkbox && frame.classList.contains('e-check')) {
            frame.classList.remove('e-check');
        } else if (checkbox) {
            frame.classList.add('e-check');
        }
    }
};

let menuObj: ContextMenu = new ContextMenu(menuOptions, '#contextmenu');
Copied to clipboard
<!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="//cdn.syncfusion.com/ej2/21.1.35/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.1.35/ej2-lists/styles/material.css" rel="stylesheet" />

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

    <!--system js reference and configuration-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>LOADING....</div>
    <div id='container'>
        <div id="target">Right click / Touch hold to open the ContextMenu</div> 
        <ul id="contextmenu"></ul>
        <input type="checkbox" id="checkbox1" style="display:none"/>
        <input type="checkbox" id="checkbox2" style="display:none"/>
        <input type="checkbox" id="checkbox3" style="display:none"/>
    </div>
</body>
</html>
Copied to clipboard
#loader {
  color: #008cff;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}

#container {
  visibility: hidden;
}

.list {
  display: none;
}

#target {
  border: 1px dashed;
  height: 150px;
  padding: 10px;
  position: relative;
  text-align: justify;
  color: gray;
  user-select: none;
}