Syncfusion AI Assistant

How can I help you?

Context Menu in React Gantt Chart Component

24 Mar 202614 minutes to read

The context menu in the Syncfusion React Gantt Chart component provides right-click access to task and column operations, improving efficiency with contextual task actions. Menu items adapt based on the clicked element, such as task rows, column headers, or chart areas.

Enabling context menu

To enable the context menu, set the enableContextMenu property to true and import ContextMenu service from @syncfusion/ej2-react-gantt in the providers of the component.

The following items are available in the default context menu:

  • AutoFit: Adjusts the current column width to fit its content.
  • AutoFitAll: Adjusts all column widths to fit their content.
  • SortAscending: Sorts the current column in ascending order.
  • SortDescending: Sorts the current column in descending order.
  • TaskInformation: Opens the editing dialog for the selected task.
  • Add: Inserts a new task with sub-options: Above, Below, Child, Milestone.
  • Indent: Moves the selected task one level inward.
  • Outdent: Moves the selected task one level outward.
  • DeleteTask: Deletes the selected task.
  • Save: Commits changes to the edited task.
  • Cancel: Discards changes to the edited task.
  • SplitTask: Divides the selected task at the specified date.
  • MergeTask: Combines split task segments with sub-options: Left, Right.
  • Convert: Converts tasks with sub-options: To Milestone and To Task.
  • DeleteDependency: Deletes the selected task dependency.

The following example demonstrates context menu implementation with default items, where menu options adapt based on the clicked element and editSettings configuration.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { GanttComponent, Inject, Selection, ContextMenu, Edit, Sort, Resize } from "@syncfusion/ej2-react-gantt";

import { data } from "./datasource";

function App() {

    const taskSettings = {
        id: "TaskID",
        name: "TaskName",
        startDate: "StartDate",
        duration: "Duration",
        progress: "Progress",
        dependency: "Predecessor",
        parentID: "ParentID"
    };

    const editSettings = {
        allowAdding: true,
        allowEditing: true,
        allowDeleting: true
    };

    return (
        <GanttComponent
            height="430px"
            dataSource={data}
            taskFields={taskSettings}
            enableContextMenu={true}
            allowSorting={true}
            allowResizing={true}
            editSettings={editSettings}
        >
            <Inject services={[Selection, ContextMenu, Edit, Sort, Resize]} />
        </GanttComponent>
    );
}

ReactDOM.render(<App />, document.getElementById("root"));
import * as React from "react";
import * as ReactDOM from "react-dom";
import { GanttComponent, Inject, Selection, ContextMenu, Edit, Sort, Resize, TaskFieldsModel, EditSettingsModel } from "@syncfusion/ej2-react-gantt";

import { data } from "./datasource";

function App() {

    const taskSettings: TaskFieldsModel = {
        id: "TaskID",
        name: "TaskName",
        startDate: "StartDate",
        duration: "Duration",
        progress: "Progress",
        dependency: "Predecessor",
        parentID: "ParentID"
    };

    const editSettings: EditSettingsModel = {
        allowAdding: true,
        allowEditing: true,
        allowDeleting: true
    };

    return (
        <GanttComponent
            height="430px"
            dataSource={data}
            taskFields={taskSettings}
            enableContextMenu={true}
            allowSorting={true}
            allowResizing={true}
            editSettings={editSettings}
        >
            <Inject services={[Selection, ContextMenu, Edit, Sort, Resize]} />
        </GanttComponent>
    );
}

ReactDOM.render(<App />, document.getElementById("root"));
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Gantt</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="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
     <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
        <div id='root'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>

If a required feature is not enabled, the related context menu item will be disabled or hidden to prevent unsupported actions.

Custom context menu items

Extend the context menu functionality by adding custom items using the contextMenuItems property. Custom items are defined as a collection of contextMenuItemModel objects with properties for id (unique identifier), text (display label), target (CSS selector for appearance context), and iconCss (icon styling class).

The target property determines where custom menu items appear: .e-content for task-related operations, like add, delete, save, and cancel, .e-gridheader for column-related operations.

The contextMenuOpen event enables dynamic modification, such as hiding items based on row selection. The contextMenuClick event handles custom item actions, providing details like the selected item’s id, text, and row data.

The following sample shows context menu items for parent rows to expand or collapse child rows in the content area and a context menu item to hide columns in the header area.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, ContextMenu, Selection, Sort, Resize, Toolbar } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
    const taskFields = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    };
    const editOptions = {
        allowAdding: true,
        allowEditing: true,
        allowDeleting: true
    };
    const toolbarOptions = ['Add'];
    return <GanttComponent dataSource={data} taskFields={taskFields} allowSelection={true} editSettings={editOptions} enableContextMenu={true} toolbar={toolbarOptions} height='450px'>
        <Inject services={[Edit, ContextMenu, Selection, Sort, Resize, Toolbar]} />
    </GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, ContextMenu, Selection, Sort, Resize, Toolbar } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
    const taskFields = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    };
    const editOptions = {
        allowAdding: true,
        allowEditing: true,
        allowDeleting: true
    };
    const toolbarOptions = ['Add'];
    return <GanttComponent dataSource={data} taskFields={taskFields} allowSelection={true} editSettings={editOptions} enableContextMenu={true} toolbar={toolbarOptions} height='450px'>
        <Inject services={[Edit, ContextMenu, Selection, Sort, Resize, Toolbar]} />
    </GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Gantt</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="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
    <div id='root'>
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>

This implementation shows custom context menu integration with event handling. The contextMenuClick event receives parameters including the selected item’s id, text, and the current row data, enabling specific actions based on the context.

Touch interaction

On touch devices, context menu functionality is accessible through long press gestures. Long press on task rows, headers, or chart areas opens the context menu, while tapping menu items executes associated actions. Items with sub-menus (e.g., Add, Convert) expand additional options when tapped, and tapping outside the menu closes it without performing actions.

This touch interaction ensures consistent experience across different device types and input methods while maintaining full functionality through intuitive gesture-based navigation.

For a comprehensive demonstration of context menu functionality, including default items, custom items, and sub-menus, explore the interactive sample.