Your search did not match any results.
Tree View

ContextMenu Integration

To display a DevExtreme ContextMenu when users right-click TreeView nodes, specify the nodes as the menu's target elements. To do this, set the menu's target option to a CSS selector. Since all TreeView nodes use the dx-treeview-item class, you can use this class' selector, as shown in this demo.

You can control each command's enabled state depending on the node where users invoked the context menu. Implement the TreeView's onItemContextMenu function; in it, set the disabled option to true for required commands.

Copy to CodeSandBox
Apply
Reset
import React from 'react'; import TreeView from 'devextreme-react/tree-view'; import ContextMenu from 'devextreme-react/context-menu'; import List from 'devextreme-react/list'; import service from './data.js'; class App extends React.Component { constructor(props) { super(props); this.contextMenuRef = React.createRef(); this.treeViewRef = React.createRef(); this.state = { products: service.getProducts(), menuItems: service.getMenuItems(), logItems: [], selectedTreeItem: undefined }; this.treeViewItemContextMenu = this.treeViewItemContextMenu.bind(this); this.contextMenuItemClick = this.contextMenuItemClick.bind(this); } render() { return ( <div className="form"> <TreeView id="treeview" ref={this.treeViewRef} items={this.state.products} width={300} height={450} onItemContextMenu={this.treeViewItemContextMenu} /> <div className="log-container"> <div><i className="icon dx-icon-clock"></i>&nbsp;Operations log:</div> <List id="log" width={400} height={300} showScrollbar="always" items={this.state.logItems} /> </div> <ContextMenu ref={this.contextMenuRef} dataSource={this.state.menuItems} target="#treeview .dx-treeview-item" onItemClick={this.contextMenuItemClick} /> </div> ); } get treeView() { return this.treeViewRef.current.instance; } get contextMenu() { return this.contextMenuRef.current.instance; } treeViewItemContextMenu(e) { this.setState({ selectedTreeItem: e.itemData, }); const isProduct = e.itemData.price !== undefined; this.contextMenu.option('items[0].visible', !isProduct); this.contextMenu.option('items[1].visible', !isProduct); this.contextMenu.option('items[2].visible', isProduct); this.contextMenu.option('items[3].visible', isProduct); this.contextMenu.option('items[0].disabled', e.node.expanded); this.contextMenu.option('items[1].disabled', !e.node.expanded); } contextMenuItemClick(e) { let logEntry = ''; switch(e.itemData.id) { case 'expand': { logEntry = `The '${this.state.selectedTreeItem.text}' group was expanded`; this.treeView.expandItem(this.state.selectedTreeItem.id); break; } case 'collapse': { logEntry = `The '${this.state.selectedTreeItem.text}' group was collapsed`; this.treeView.collapseItem(this.state.selectedTreeItem.id); break; } case 'details': { logEntry = `Details about '${this.state.selectedTreeItem.text}' were displayed`; break; } case 'copy': { logEntry = `Information about '${this.state.selectedTreeItem.text}' was copied`; break; } } const logItems = this.state.logItems.concat([logEntry]); this.setState({ logItems: logItems }); } } export default App;
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.js'; ReactDOM.render( <App />, document.getElementById('app') );
<!DOCTYPE html> <html> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.1.7/css/dx.common.css" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.1.7/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="styles.css" /> <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import('./index.js'); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"></div> </div> </body> </html>
.form { display: flex; } .form>div, #treeview { display: inline-block; vertical-align: top; } .log-container { padding: 20px; margin-left: 20px; font-size: 115%; font-weight: bold; background-color: rgba(191, 191, 191, 0.15); height: 100%; } .log-container .dx-icon-clock { position: relative; top: 1px; } #log { margin-top: 10px; } #log .dx-empty-message { padding-left: 0px; } .dx-list-item-content { padding-left: 0; }
const menuItems = [ { id: 'expand', text: 'Expand category' }, { id: 'collapse', text: 'Collapse category' }, { id: 'details', text: 'Show product details' }, { id: 'copy', text: 'Copy product info' } ]; const products = [{ id: '1', text: 'Stores', expanded: true, items: [{ id: '1_1', text: 'Super Mart of the West', expanded: true, items: [{ id: '1_1_1', text: 'Video Players', items: [{ id: '1_1_1_1', text: 'HD Video Player', price: 220, image: '../../../../images/products/1.png' }, { id: '1_1_1_2', text: 'SuperHD Video Player', image: '../../../../images/products/2.png', price: 270 }] }, { id: '1_1_2', text: 'Televisions', expanded: true, items: [{ id: '1_1_2_1', text: 'SuperLCD 42', image: '../../../../images/products/7.png', price: 1200 }, { id: '1_1_2_2', text: 'SuperLED 42', image: '../../../../images/products/5.png', price: 1450 }, { id: '1_1_2_3', text: 'SuperLED 50', image: '../../../../images/products/4.png', price: 1600 }, { id: '1_1_2_4', text: 'SuperLCD 55', image: '../../../../images/products/6.png', price: 1350 }, { id: '1_1_2_5', text: 'SuperLCD 70', image: '../../../../images/products/9.png', price: 4000 }] }, { id: '1_1_3', text: 'Monitors', expanded: true, items: [{ id: '1_1_3_1', text: '19"', expanded: true, items: [{ id: '1_1_3_1_1', text: 'DesktopLCD 19', image: '../../../../images/products/10.png', price: 160 }] }, { id: '1_1_3_2', text: '21"', items: [{ id: '1_1_3_2_1', text: 'DesktopLCD 21', image: '../../../../images/products/12.png', price: 170 }, { id: '1_1_3_2_2', text: 'DesktopLED 21', image: '../../../../images/products/13.png', price: 175 }] }] }, { id: '1_1_4', text: 'Projectors', items: [{ id: '1_1_4_1', text: 'Projector Plus', image: '../../../../images/products/14.png', price: 550 }, { id: '1_1_4_2', text: 'Projector PlusHD', image: '../../../../images/products/15.png', price: 750 }] }] }, { id: '1_2', text: 'Braeburn', items: [{ id: '1_2_1', text: 'Video Players', items: [{ id: '1_2_1_1', text: 'HD Video Player', image: '../../../../images/products/1.png', price: 240 }, { id: '1_2_1_2', text: 'SuperHD Video Player', image: '../../../../images/products/2.png', price: 300 }] }, { id: '1_2_2', text: 'Televisions', items: [{ id: '1_2_2_1', text: 'SuperPlasma 50', image: '../../../../images/products/3.png', price: 1800 }, { id: '1_2_2_2', text: 'SuperPlasma 65', image: '../../../../images/products/8.png', price: 3500 }] }, { id: '1_2_3', text: 'Monitors', items: [{ id: '1_2_3_1', text: '19"', items: [{ id: '1_2_3_1_1', text: 'DesktopLCD 19', image: '../../../../images/products/10.png', price: 170 }] }, { id: '1_2_3_2', text: '21"', items: [{ id: '1_2_3_2_1', text: 'DesktopLCD 21', image: '../../../../images/products/12.png', price: 180 }, { id: '1_2_3_2_2', text: 'DesktopLED 21', image: '../../../../images/products/13.png', price: 190 }] }] }] }, { id: '1_3', text: 'E-Mart', items: [{ id: '1_3_1', text: 'Video Players', items: [{ id: '1_3_1_1', text: 'HD Video Player', image: '../../../../images/products/1.png', price: 220 }, { id: '1_3_1_2', text: 'SuperHD Video Player', image: '../../../../images/products/2.png', price: 275 }] }, { id: '1_3_3', text: 'Monitors', items: [{ id: '1_3_3_1', text: '19"', items: [{ id: '1_3_3_1_1', text: 'DesktopLCD 19', image: '../../../../images/products/10.png', price: 165 }] }, { id: '1_3_3_2', text: '21"', items: [{ id: '1_3_3_2_1', text: 'DesktopLCD 21', image: '../../../../images/products/12.png', price: 175 }] }] }] }, { id: '1_4', text: 'Walters', items: [{ id: '1_4_1', text: 'Video Players', items: [{ id: '1_4_1_1', text: 'HD Video Player', image: '../../../../images/products/1.png', price: 210 }, { id: '1_4_1_2', text: 'SuperHD Video Player', image: '../../../../images/products/2.png', price: 250 }] }, { id: '1_4_2', text: 'Televisions', items: [{ id: '1_4_2_1', text: 'SuperLCD 42', image: '../../../../images/products/7.png', price: 1100 }, { id: '1_4_2_2', text: 'SuperLED 42', image: '../../../../images/products/5.png', price: 1400 }, { id: '1_4_2_3', text: 'SuperLED 50', image: '../../../../images/products/4.png', price: 1500 }, { id: '1_4_2_4', text: 'SuperLCD 55', image: '../../../../images/products/6.png', price: 1300 }, { id: '1_4_2_5', text: 'SuperLCD 70', image: '../../../../images/products/9.png', price: 4000 }, { id: '1_4_2_6', text: 'SuperPlasma 50', image: '../../../../images/products/3.png', price: 1700 }] }, { id: '1_4_3', text: 'Monitors', items: [{ id: '1_4_3_1', text: '19"', items: [{ id: '1_4_3_1_1', text: 'DesktopLCD 19', image: '../../../../images/products/10.png', price: 160 }] }, { id: '1_4_3_2', text: '21"', items: [{ id: '1_4_3_2_1', text: 'DesktopLCD 21', image: '../../../../images/products/12.png', price: 170 }, { id: '1_4_3_2_2', text: 'DesktopLED 21', image: '../../../../images/products/13.png', price: 180 }] }] }, { id: '1_4_4', text: 'Projectors', items: [{ id: '1_4_4_1', text: 'Projector Plus', image: '../../../../images/products/14.png', price: 550 }, { id: '1_4_4_2', text: 'Projector PlusHD', image: '../../../../images/products/15.png', price: 750 }] }] }] }]; export default { getProducts() { return products; }, getMenuItems() { return menuItems; } };
System.config({ transpiler: 'plugin-babel', meta: { }, paths: { 'npm:': 'https://unpkg.com/' }, defaultExtension: 'js', map: { 'react': 'npm:react@16/umd/react.development.js', 'react-dom': 'npm:react-dom@16/umd/react-dom.development.js', 'prop-types': 'npm:prop-types/prop-types.js', 'devextreme': 'npm:devextreme@20.1', 'devextreme-react': 'npm:devextreme-react@20.1', 'jszip': 'npm:jszip@3.1.3/dist/jszip.min.js', 'quill': 'npm:quill@1.3.7/dist/quill.js', 'devexpress-diagram': 'npm:devexpress-diagram@1.0.14', 'devexpress-gantt': 'npm:devexpress-gantt@1.0.7', // SystemJS plugins 'plugin-babel': 'npm:systemjs-plugin-babel@0/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel@0/systemjs-babel-browser.js' }, packages: { 'devextreme': { defaultExtension: 'js' }, 'devextreme-react': { main: 'index.js' }, 'devextreme/events/utils': { main: 'index' }, 'devextreme/events': { main: 'index' }, }, babelOptions: { sourceMaps: false, stage0: true, react: true } });