Templates in React Context menu component
7 Oct 202524 minutes to read
Item template
The itemTemplate property in the ContextMenu component allows you to define custom templates for displaying menu items. This feature enables you to customize the appearance, layout, and content of menu items beyond the default text-based display. Use item templates when you need to include icons, formatted text, additional metadata, or complex HTML structures within menu items.
import { enableRipple, Browser } 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() { const 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>"; let content = Browser.isDevice ? 'Right-click or touch and hold to open the Context Menu and select the answer type' : 'Right click/Touch hold to open the Context Menu and select the answer type'; // ContextMenu items definition const 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" }, ]; const addTemplateClass = (args) => { if (args.element.classList.contains('e-ul')) { args.element.classList.add('e-contextMenu-template'); } }; return ( <div className='control-pane'> <div className='control-section'> <div className='contextmenu-section'> <div id='contextmenu-control'> <div id="contextmenutarget">{content}</div> <ContextMenuComponent className="e-contextMenu-template" target='#contextmenutarget' items={menuItems} itemTemplate={template} beforeOpen={addTemplateClass} /> </div> </div> </div> </div> ); } export default App; ReactDom.render(<App />, document.getElementById('element'));import { enableRipple, Browser } 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() { const template: string = "<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>"; let content: string = Browser.isDevice ? 'Right-click or touch and hold to open the Context Menu and select the answer type' : 'Right click/Touch hold to open the Context Menu and select the answer type'; // ContextMenu items definition const menuItems: any = [ { 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" }, ]; const addTemplateClass = (args: MenuEventArgs) => { if (args.element.classList.contains('e-ul')) { args.element.classList.add('e-contextMenu-template'); } }; return ( <div className='control-pane'> <div className='control-section'> <div className='contextmenu-section'> <div id='contextmenu-control'> <div id="contextmenutarget">{content}</div> <ContextMenuComponent className="e-contextMenu-template" target='#contextmenutarget' items={menuItems} itemTemplate={template} beforeOpen={addTemplateClass} /> </div> </div> </div> </div> ); } export default App; ReactDom.render(<App />, document.getElementById('element'));Customize specific menu items
ContextMenu items can be customized using the beforeItemRender event. This event triggers while rendering each menu item, providing access to the item element and menu item data for customization based on specific requirements. The following example demonstrates how to add keyboard shortcuts to specific menu items by appending span elements during the rendering process.
import { createElement, 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 = [ { text: 'Save as...' }, { text: 'View page source' }, { text: 'Inspect' } ]; function itemBeforeEvent(args) { const shortCutSpan = createElement('span'); const text = args.item.text; const 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'); } return (<div class="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 { createElement, 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[] = [ { text: 'Save as...' }, { text: 'View page source' }, { text: 'Inspect' }]; function itemBeforeEvent(args: MenuEventArgs) { const shortCutSpan = createElement('span'); const text = args.item.text; const 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'); } return ( <div class="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'));To create span element,
createElementutil function used fromej2-base.
Multi-level nesting
The ContextMenu component supports multiple levels of nesting for creating hierarchical menu structures. Achieve this by mapping the items property within parent menuItems. The following example demonstrates a three-level nested ContextMenu structure.
import * as React from 'react'; import * as ReactDom from 'react-dom'; import { ContextMenuComponent } from '@syncfusion/ej2-react-navigations'; import { enableRipple } from '@syncfusion/ej2-base'; enableRipple(true); function App() { let menuItems = [ { text: 'Show All Bookmarks' }, { text: 'Bookmarks Toolbar', items: [ { text: 'Most Visited', items: [ { text: 'Google' }, { text: 'Gmail' } ] }, { text: 'Recently Added' } ] } ]; return (<div class="container"> <div id='target'>Right click / Touch hold to open the ContextMenu</div> <ContextMenuComponent id='contextmenu' target='#target' items={menuItems}> </ContextMenuComponent> </div>); } export default App; ReactDom.render(<App />, document.getElementById('element'));import * as React from 'react'; import * as ReactDom from 'react-dom'; import { ContextMenuComponent, MenuItemModel } from '@syncfusion/ej2-react-navigations'; import { enableRipple } from '@syncfusion/ej2-base'; enableRipple(true); function App() { let menuItems: MenuItemModel[] = [ { text: 'Show All Bookmarks' }, { text: 'Bookmarks Toolbar', items: [ { text: 'Most Visited', items: [ { text: 'Google' }, { text: 'Gmail' } ] }, { text: 'Recently Added' } ] }]; return ( <div class="container"> <div id='target'>Right click / Touch hold to open the ContextMenu</div> <ContextMenuComponent id='contextmenu' target='#target' items={menuItems}> </ContextMenuComponent> </div> ); } export default App; ReactDom.render(<App />,document.getElementById('element'));To open sub menu items only on click, set the
showItemOnClickproperty totrue.