Template customization in React Context menu component
7 Oct 202519 minutes to read
The ContextMenu component supports extensive template customization, allowing you to embed complex UI elements and interactive components within menu items. This flexibility enables creating rich, context-aware menus that go beyond simple text-based navigation.
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.
import { enableRipple } from '@syncfusion/ej2-base'; import { ContextMenuComponent } from '@syncfusion/ej2-react-navigations'; import * as React from 'react'; import * as ReactDom from 'react-dom'; enableRipple(true); function App() { let menuItems = [ { iconCss: 'e-cm-icons e-cut', text: 'Cut', }, { iconCss: 'e-icons e-copy', text: 'Copy' }, { iconCss: 'e-cm-icons e-paste', text: 'Paste' }, { separator: true }, { iconCss: 'e-icons e-link', text: 'Link' }, { iconCss: 'e-icons e-table', items: [ { id: 'table' } ], text: 'Table' } ]; function createHeader() { const header = document.createElement('h4'); header.textContent = 'Insert Table'; return header; } function createTable() { const table = document.createElement('table'); for (let i = 0; i < 5; i++) { const row = document.createElement('tr'); table.appendChild(row); for (let j = 0; j < 6; j++) { const col = document.createElement('td'); row.appendChild(col); col.setAttribute('class', 'data'); } } return table; } function itemBeforeEvent(args) { if (args.item.id === 'table') { args.element.classList.add('bg-transparent'); args.element.appendChild(createHeader()); args.element.appendChild(createTable()); } } return (<div className="container"> <div id='target'>Right click / Touch hold to open the ContextMenu</div> <ContextMenuComponent id='contextmenu' target='#target' items={menuItems} beforeItemRender={itemBeforeEvent}/> </div>); } export default App; ReactDom.render(<App />, document.getElementById('element'));import { enableRipple } from '@syncfusion/ej2-base'; import { ContextMenuComponent, MenuEventArgs, MenuItemModel } from '@syncfusion/ej2-react-navigations'; import * as React from 'react'; import * as ReactDom from 'react-dom'; enableRipple(true); function App() { let menuItems: MenuItemModel[] = [ { iconCss: 'e-cm-icons e-cut', text: 'Cut', }, { iconCss: 'e-icons e-copy', text: 'Copy' }, { iconCss: 'e-cm-icons e-paste', text: 'Paste' }, { separator: true }, { iconCss: 'e-icons e-link', text: 'Link' }, { iconCss: 'e-icons e-table', items: [ { id: 'table' } ], text: 'Table' } ]; function createHeader() { const header = document.createElement('h4'); header.textContent = 'Insert Table'; return header; } function createTable() { const table = document.createElement('table'); for (let i: number = 0; i < 5; i++) { const row = document.createElement('tr'); table.appendChild(row); for (let j: number = 0; j < 6; j++) { const col = document.createElement('td'); row.appendChild(col); col.setAttribute('class', 'data'); } } return table; } function itemBeforeEvent(args: MenuEventArgs) { if (args.item.id === 'table') { args.element.classList.add('bg-transparent'); args.element.appendChild(createHeader()); args.element.appendChild(createTable()); } } return ( <div className="container"> <div id='target'>Right click / Touch hold to open the ContextMenu</div> <ContextMenuComponent id='contextmenu' target='#target' items={menuItems} beforeItemRender={itemBeforeEvent}/> </div> ); } export default App; ReactDom.render(<App />,document.getElementById('element'));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.
import { closest, createElement, enableRipple } from '@syncfusion/ej2-base'; import { createCheckBox } from '@syncfusion/ej2-buttons'; import { ContextMenuComponent } from '@syncfusion/ej2-react-navigations'; import * as React from 'react'; import * as ReactDom from 'react-dom'; enableRipple(true); function App() { let menuItems = [ { text: 'Option 1' }, { text: 'Option 2' }, { text: 'Option 3' } ]; function itemBeforeEvent(args) { const check = createCheckBox(createElement, false, { checked: (args.item.text === 'Option 1' || args.item.text === 'Option 2') ? true : false, label: args.item.text }); args.element.innerHTML = ''; args.element.appendChild(check); } function beforeClose(args) { if (closest(args.event.target, '.e-menu-item')) { args.cancel = true; const selectedElem = args.element.querySelectorAll('.e-selected'); for (const elem of selectedElem) { const ele = elem; ele.classList.remove('e-selected'); } const checkbox = closest(args.event.target, '.e-checkbox-wrapper'); if (checkbox) { const frame = checkbox.querySelector('.e-frame'); if (checkbox && frame.classList.contains('e-check')) { frame.classList.remove('e-check'); } else if (checkbox) { frame.classList.add('e-check'); } } } } return (<div className="container"> <div id='target'>Right click / Touch hold to open the ContextMenu</div> <ContextMenuComponent id='contextmenu' target='#target' items={menuItems} beforeItemRender={itemBeforeEvent} beforeClose={beforeClose}/> </div>); } export default App; ReactDom.render(<App />, document.getElementById('element'));import { closest, createElement, enableRipple} from '@syncfusion/ej2-base'; import { createCheckBox } from '@syncfusion/ej2-buttons'; import { BeforeOpenCloseMenuEventArgs, ContextMenuComponent, MenuEventArgs, MenuItemModel } from '@syncfusion/ej2-react-navigations'; import * as React from 'react'; import * as ReactDom from 'react-dom'; enableRipple(true); function App() { let menuItems: MenuItemModel[] = [ { text: 'Option 1' }, { text: 'Option 2' }, { text: 'Option 3' } ]; function itemBeforeEvent(args: MenuEventArgs) { const check = createCheckBox(createElement, false, { checked: (args.item.text === 'Option 1' || args.item.text === 'Option 2') ? true : false, label: args.item.text }); args.element.innerHTML = ''; args.element.appendChild(check); } function beforeClose(args: BeforeOpenCloseMenuEventArgs) { if (closest((args.event.target as HTMLElement), '.e-menu-item')) { args.cancel = true; const selectedElem = args.element.querySelectorAll('.e-selected'); for (const elem of selectedElem as any) { const ele = elem as HTMLElement; ele.classList.remove('e-selected'); } const checkbox = closest(args.event.target as Element, '.e-checkbox-wrapper') as HTMLElement; if (checkbox) { const frame = checkbox.querySelector('.e-frame'); if (checkbox && frame.classList.contains('e-check')) { frame.classList.remove('e-check'); } else if (checkbox) { frame.classList.add('e-check'); } } } } return ( <div className="container"> <div id='target'>Right click / Touch hold to open the ContextMenu</div> <ContextMenuComponent id='contextmenu' target='#target' items={menuItems} beforeItemRender={itemBeforeEvent} beforeClose={beforeClose} /> </div> ); } export default App; ReactDom.render(<App />,document.getElementById('element'));