Search results

Change sub menu position

The submenu position can be changed by using the beforeOpen event. Assign the top and left position where you want to open the submenu to the beforeOpen event arguments args.top and args.left respectively.

In the below sample, the sub menu opens above the parent menu item.

Source
Preview
index.tsx
index.html
index.jsx
import { closest, enableRipple} from '@syncfusion/ej2-base';
import { BeforeOpenCloseMenuEventArgs, MenuComponent, MenuItemModel } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
import * as ReactDom from 'react-dom';
enableRipple(true);

class App extends React.Component<{}, {}> {
    // Menu items definition
    public menuItems: MenuItemModel[] = [
        {
            items: [
                { text: 'Open' },
                { text: 'Save' },
                { text: 'Exit' }
            ],
            text: 'File'
        },
        {
            items: [
                { text: 'Cut' },
                { text: 'Copy' },
                { text: 'Paste' }
            ],
            text: 'Edit'
        },
        {
            items: [
                { text: 'Toolbar' },
                { text: 'Sidebar' }
            ],
            text: 'View'
        },
        {
            items: [
                { text: 'Spelling & Grammar' },
                { text: 'Customize' },
                { text: 'Options' }
            ],
            text: 'Tools'
        },
        { text: 'Go' },
        { text: 'Help' }
    ];

    public onBeforeOpen(args: BeforeOpenCloseMenuEventArgs) {
        // Getting parent menu item element offset
        const relativeOffset = closest(args.event.target as Element, '.e-menu-item').getBoundingClientRect();
        // Getting sub menu wrapper element using closest method
        const subMenuEle = closest(args.element, '.e-menu-wrapper') as HTMLElement;
        subMenuEle.style.display = 'block';
        args.top = (relativeOffset.top - subMenuEle.getBoundingClientRect().height) + pageYOffset;
        args.left = relativeOffset.left + pageXOffset;
        subMenuEle.style.display = '';
    }

    public render() {
        return (
            <MenuComponent items={this.menuItems} beforeOpen={this.onBeforeOpen}/>
        );
    }
}

ReactDom.render(<App />,document.getElementById('element'));
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React ContextMenu</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="index.css" rel="stylesheet" />
    <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='element'>
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>
import { closest, enableRipple } from '@syncfusion/ej2-base';
import { MenuComponent } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
import * as ReactDom from 'react-dom';
enableRipple(true);
class App extends React.Component {
    constructor() {
        super(...arguments);
        // Menu items definition
        this.menuItems = [
            {
                items: [
                    { text: 'Open' },
                    { text: 'Save' },
                    { text: 'Exit' }
                ],
                text: 'File'
            },
            {
                items: [
                    { text: 'Cut' },
                    { text: 'Copy' },
                    { text: 'Paste' }
                ],
                text: 'Edit'
            },
            {
                items: [
                    { text: 'Toolbar' },
                    { text: 'Sidebar' }
                ],
                text: 'View'
            },
            {
                items: [
                    { text: 'Spelling & Grammar' },
                    { text: 'Customize' },
                    { text: 'Options' }
                ],
                text: 'Tools'
            },
            { text: 'Go' },
            { text: 'Help' }
        ];
    }
    onBeforeOpen(args) {
        // Getting parent menu item element offset
        const relativeOffset = closest(args.event.target, '.e-menu-item').getBoundingClientRect();
        // Getting sub menu wrapper element using closest method
        const subMenuEle = closest(args.element, '.e-menu-wrapper');
        subMenuEle.style.display = 'block';
        args.top = (relativeOffset.top - subMenuEle.getBoundingClientRect().height) + pageYOffset;
        args.left = relativeOffset.left + pageXOffset;
        subMenuEle.style.display = '';
    }
    render() {
        return (<MenuComponent items={this.menuItems} beforeOpen={this.onBeforeOpen}/>);
    }
}
ReactDom.render(<App />, document.getElementById('element'));

For custom positioning, set both top and left position in the beforeOpen event.