Editing tasks in React Gantt component

12 Jan 202424 minutes to read

The editing feature can be enabled in the Gantt component by enabling the editSettings.allowEditing and editSettings.allowTaskbarEditing properties.

The following editing options are available to update the tasks in the Gantt chart:

  • Cell
  • Dialog
  • Taskbar
  • Dependency links

To get start quickly with CRUD functionalities, you can check on this video:

Cell editing

By setting the edit mode to auto using the editSettings.mode property, the tasks can be edited by double-clicking the TreeGrid cells.

Note: If the Edit module is not injected, you cannot edit the tasks through TreeGrid cells.

The following code example shows you how to enable the cell editing in Gantt component.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, EditSettingsModel, Selection } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App(){
    const taskFields = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    child: 'subtasks'
  };
  const editOptions = {
    allowEditing: true,
    mode: 'Auto'
  };
        return <GanttComponent dataSource={data} taskFields={taskFields} allowSelection={true}
        editSettings={editOptions} height = '450px'>
            <Inject services={[Edit, Selection]} />
        </GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, EditSettingsModel, Selection } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App(){
    const taskFields: any = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    child: 'subtasks'
  };
  const editOptions: EditSettingsModel = {
    allowEditing: true,
    mode: 'Auto'
  };
        return <GanttComponent dataSource={data} taskFields={taskFields} allowSelection={true}
        editSettings={editOptions} height = '450px'>
            <Inject services={[Edit, Selection]} />
        </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/28.1.33/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

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

</html>

Note: When the edit mode is set to Auto, double-clicking on the TreeGrid side changes the cells to editable mode. Double-clicking on the chart side opens the edit dialog for editing the task details.

Dialog editing

Modify the task details through the edit dialog by setting the edit mode.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit} from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App(){
    const taskFields = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    child: 'subtasks'
  };
  const editOptions = {
    allowEditing: true,
    mode: 'Dialog'
  };
        return <GanttComponent dataSource={data} taskFields={taskFields}
        editSettings={editOptions} height = '450px'>
            <Inject services={[Edit]} />
        </GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, EditSettingsModel } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App(){
    const taskFields: any = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    child: 'subtasks'
  };
  const editOptions: EditSettingsModel = {
    allowEditing: true,
    mode: 'Dialog'
  };
        return <GanttComponent dataSource={data} taskFields={taskFields}
        editSettings={editOptions} height = '450px'>
            <Inject services={[Edit]} />
        </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/28.1.33/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

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

</html>

Note: In dialog editing mode, the edit dialog appears when the TreeGrid or Gantt chart sides are double-clicked.

Sections or tabs in dialog

In the Gantt dialog, you can define the required tabs or editing sections using the addDialogFields and editDialogFields properties. Every tab is defined using the type property.

let ProjectResources = [
    { resourceId: 1, resourceName: 'Martin Tamer' },
    { resourceId: 2, resourceName: 'Rose Fuller' },
    { resourceId: 3, resourceName: 'Margaret Buchanan' },
    { resourceId: 4, resourceName: 'Fuller King' },
    { resourceId: 5, resourceName: 'Davolio Fuller' },
    { resourceId: 6, resourceName: 'Van Jack' },
    { resourceId: 7, resourceName: 'Fuller Buchanan' },
    { resourceId: 8, resourceName: 'Jack Davolio' },
    { resourceId: 9, resourceName: 'Tamer Vinet' },
    { resourceId: 10, resourceName: 'Vinet Fuller' },
    { resourceId: 11, resourceName: 'Bergs Anton' },
    { resourceId: 12, resourceName: 'Construction Supervisor' }
  ];
  
  let data = [
    {
        TaskID: 1,
        TaskName: 'Project Initiation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 0, Progress: 50, isParent: false, info: 'Measure the total property area alloted for construction' },
            {
                TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50, resources: [2, 3, 5], isParent: false, info: 'Obtain an engineered soil test of lot where construction is planned.' +
                    'From an engineer or company specializing in soil testing'
            },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, Predecessor: "2FS", Progress: 50, isParent: false },
        ]
    },
    {
        TaskID: 5,
        TaskName: 'Project Estimation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            {
                TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4],
                isParent: false, info: 'Develop floor plans and obtain a materials list for estimations'
            },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4, 8], isParent: false, info: '' },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 0, Predecessor: "6SS", Progress: 50, resources: [12, 5], isParent: false, info: '' }
        ]
    },
  ];
  
  import * as React from 'react';
  import * as ReactDOM from 'react-dom';
  import { GanttComponent, Inject,Toolbar, ToolbarItem, Edit,AddDialogFieldsDirective, EditSettingsModel, EditDialogFieldsDirective, EditDialogFieldDirective, AddDialogFieldDirective } from '@syncfusion/ej2-react-gantt';
  
  function App(){
      const taskFields = {
          id: 'TaskID',
          name: 'TaskName',
          startDate: 'StartDate',
          endDate: 'EndDate',
          duration: 'Duration',
          progress: 'Progress',
          dependency: 'Predecessor',
          child: 'subtasks',
          notes: 'info',
          resourceInfo: 'resources'
    };
     const resourceFields = {
          id: 'resourceId',
          name: 'resourceName',
      };
    const toolbarOptions = ['Add'];
    const editOptions = {
          allowEditing: true,
          allowAdding:true,
          mode: 'Dialog'
    };
          return <GanttComponent dataSource={data} toolbar={toolbarOptions} taskFields={taskFields} editSettings={editOptions} height='450px' resourceFields={resourceFields}
          resources={ProjectResources}>
          <AddDialogFieldsDirective>
              <AddDialogFieldDirective type='General' headerText='General'></AddDialogFieldDirective>
              <AddDialogFieldDirective type='Dependency'></AddDialogFieldDirective>
          </AddDialogFieldsDirective>
             <EditDialogFieldsDirective>
                <EditDialogFieldDirective type='General' headerText='General'></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Dependency'></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Resources'></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Notes'></EditDialogFieldDirective>
              </EditDialogFieldsDirective>
              <Inject services={[Edit, Toolbar]} />
          </GanttComponent>
  };
  ReactDOM.render(<App />, document.getElementById('root'));
let ProjectResources: Object[] = [
    { resourceId: 1, resourceName: 'Martin Tamer' },
    { resourceId: 2, resourceName: 'Rose Fuller' },
    { resourceId: 3, resourceName: 'Margaret Buchanan' },
    { resourceId: 4, resourceName: 'Fuller King' },
    { resourceId: 5, resourceName: 'Davolio Fuller' },
    { resourceId: 6, resourceName: 'Van Jack' },
    { resourceId: 7, resourceName: 'Fuller Buchanan' },
    { resourceId: 8, resourceName: 'Jack Davolio' },
    { resourceId: 9, resourceName: 'Tamer Vinet' },
    { resourceId: 10, resourceName: 'Vinet Fuller' },
    { resourceId: 11, resourceName: 'Bergs Anton' },
    { resourceId: 12, resourceName: 'Construction Supervisor' }
  ];
  
  let data: Object[] = [
    {
        TaskID: 1,
        TaskName: 'Project Initiation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 0, Progress: 50, isParent: false, info: 'Measure the total property area alloted for construction' },
            {
                TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50, resources: [2, 3, 5], isParent: false, info: 'Obtain an engineered soil test of lot where construction is planned.' +
                    'From an engineer or company specializing in soil testing'
            },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, Predecessor: "2FS", Progress: 50, isParent: false },
        ]
    },
    {
        TaskID: 5,
        TaskName: 'Project Estimation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            {
                TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4],
                isParent: false, info: 'Develop floor plans and obtain a materials list for estimations'
            },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4, 8], isParent: false, info: '' },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 0, Predecessor: "6SS", Progress: 50, resources: [12, 5], isParent: false, info: '' }
        ]
    },
  ];
  
  import * as React from 'react';
  import * as ReactDOM from 'react-dom';
  import { GanttComponent, Inject,Toolbar, ToolbarItem, Edit,AddDialogFieldsDirective, EditSettingsModel, EditDialogFieldsDirective, EditDialogFieldDirective, AddDialogFieldDirective } from '@syncfusion/ej2-react-gantt';
  
  function App(){
      const taskFields: any = {
          id: 'TaskID',
          name: 'TaskName',
          startDate: 'StartDate',
          endDate: 'EndDate',
          duration: 'Duration',
          progress: 'Progress',
          dependency: 'Predecessor',
          child: 'subtasks',
          notes: 'info',
          resourceInfo: 'resources'
    };
     const resourceFields: any = {
          id: 'resourceId',
          name: 'resourceName',
      };
    const toolbarOptions: ToolbarItem[] = ['Add'];
    const editOptions: EditSettingsModel = {
          allowEditing: true,
          allowAdding:true,
          mode: 'Dialog'
    };
          return <GanttComponent dataSource={data} toolbar={toolbarOptions} taskFields={taskFields} editSettings={editOptions} height='450px' resourceFields={resourceFields}
          resources={ProjectResources}>
          <AddDialogFieldsDirective>
              <AddDialogFieldDirective type='General' headerText='General'></AddDialogFieldDirective>
              <AddDialogFieldDirective type='Dependency'></AddDialogFieldDirective>
          </AddDialogFieldsDirective>
             <EditDialogFieldsDirective>
                <EditDialogFieldDirective type='General' headerText='General'></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Dependency'></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Resources'></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Notes'></EditDialogFieldDirective>
              </EditDialogFieldsDirective>
              <Inject services={[Edit, 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/28.1.33/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

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

</html>

Limiting data fields in general tab

In the Gantt dialog, you can make only specific data source fields visible for editing by using the addDialogFields and editDialogFields properties. The data fields are defined with type and [fields] (https://ej2.syncfusion.com/react/documentation/api/gantt/addDialogFieldSettings/#fields) properties.

Note: You can also define the custom fields in the add/edit dialog General tab using the fields property.

let ProjectResources = [
    { resourceId: 1, resourceName: 'Martin Tamer' },
    { resourceId: 2, resourceName: 'Rose Fuller' },
    { resourceId: 3, resourceName: 'Margaret Buchanan' },
    { resourceId: 4, resourceName: 'Fuller King' },
    { resourceId: 5, resourceName: 'Davolio Fuller' },
    { resourceId: 6, resourceName: 'Van Jack' },
    { resourceId: 7, resourceName: 'Fuller Buchanan' },
    { resourceId: 8, resourceName: 'Jack Davolio' },
    { resourceId: 9, resourceName: 'Tamer Vinet' },
    { resourceId: 10, resourceName: 'Vinet Fuller' },
    { resourceId: 11, resourceName: 'Bergs Anton' },
    { resourceId: 12, resourceName: 'Construction Supervisor' }
  ];
  
  let data = [
    {
        TaskID: 1,
        TaskName: 'Project Initiation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 0, Progress: 50, isParent: false, info: 'Measure the total property area alloted for construction' },
            {
                TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50, resources: [2, 3, 5], isParent: false, info: 'Obtain an engineered soil test of lot where construction is planned.' +
                    'From an engineer or company specializing in soil testing'
            },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, Predecessor: "2FS", Progress: 50, isParent: false },
        ]
    },
    {
        TaskID: 5,
        TaskName: 'Project Estimation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            {
                TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4],
                isParent: false, info: 'Develop floor plans and obtain a materials list for estimations'
            },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4, 8], isParent: false, info: '' },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 0, Predecessor: "6SS", Progress: 50, resources: [12, 5], isParent: false, info: '' }
        ]
    },
  ];
  
  import * as React from 'react';
  import * as ReactDOM from 'react-dom';
  import { GanttComponent, Inject,Toolbar, ToolbarItem, Edit, ColumnsDirective, ColumnDirective, AddDialogFieldsDirective, EditSettingsModel, EditDialogFieldsDirective, EditDialogFieldDirective, AddDialogFieldDirective } from '@syncfusion/ej2-react-gantt';
  
  function App(){
      const taskFields = {
          id: 'TaskID',
          name: 'TaskName',
          startDate: 'StartDate',
          endDate: 'EndDate',
          duration: 'Duration',
          progress: 'Progress',
          dependency: 'Predecessor',
          child: 'subtasks',
          notes: 'info',
          resourceInfo: 'resources'
    };
    const toolbarOptions = ['Add'];
      const editOptions = {
          allowEditing: true,
          allowAdding:true,
          mode: 'Dialog'
    };
      const resourceFields = {
          id: 'resourceId',
          name: 'resourceName',
      };
          return <GanttComponent dataSource={data} toolbar={toolbarOptions} taskFields={taskFields} editSettings={editOptions} height='450px'
          resourceFields={resourceFields} resources={ProjectResources}>
           <ColumnsDirective>
                  <ColumnDirective field='TaskID' width='100' ></ColumnDirective>
                  <ColumnDirective field='TaskName' headerText='Job Name' width='250'></ColumnDirective>
                  <ColumnDirective field='resources'></ColumnDirective>
                  <ColumnDirective field='StartDate'></ColumnDirective>
                  <ColumnDirective field='Duration'></ColumnDirective>
                  <ColumnDirective field='Progress'></ColumnDirective>
                  <ColumnDirective field='Predecessor'></ColumnDirective>
                  <ColumnDirective field='isParent' headerText='Custom Column'></ColumnDirective>
              </ColumnsDirective>
          <AddDialogFieldsDirective>
              <AddDialogFieldDirective type='General' headerText='General' fields= {['TaskID', 'TaskName', 'isParent']}></AddDialogFieldDirective>
              <AddDialogFieldDirective type='Dependency'></AddDialogFieldDirective>
              <AddDialogFieldDirective type='Resources'></AddDialogFieldDirective>
          </AddDialogFieldsDirective>
             <EditDialogFieldsDirective>
                <EditDialogFieldDirective type='General' headerText='General' fields= {['TaskID', 'TaskName', 'isParent']}></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Dependency'></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Resources'></EditDialogFieldDirective>
            </EditDialogFieldsDirective>
              <Inject services={[Edit, Toolbar]} />
          </GanttComponent>
  };
  ReactDOM.render(<App />, document.getElementById('root'));
let ProjectResources: Object[] = [
    { resourceId: 1, resourceName: 'Martin Tamer' },
    { resourceId: 2, resourceName: 'Rose Fuller' },
    { resourceId: 3, resourceName: 'Margaret Buchanan' },
    { resourceId: 4, resourceName: 'Fuller King' },
    { resourceId: 5, resourceName: 'Davolio Fuller' },
    { resourceId: 6, resourceName: 'Van Jack' },
    { resourceId: 7, resourceName: 'Fuller Buchanan' },
    { resourceId: 8, resourceName: 'Jack Davolio' },
    { resourceId: 9, resourceName: 'Tamer Vinet' },
    { resourceId: 10, resourceName: 'Vinet Fuller' },
    { resourceId: 11, resourceName: 'Bergs Anton' },
    { resourceId: 12, resourceName: 'Construction Supervisor' }
  ];
  
  let data: Object[] = [
    {
        TaskID: 1,
        TaskName: 'Project Initiation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 0, Progress: 50, isParent: false, info: 'Measure the total property area alloted for construction' },
            {
                TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50, resources: [2, 3, 5], isParent: false, info: 'Obtain an engineered soil test of lot where construction is planned.' +
                    'From an engineer or company specializing in soil testing'
            },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, Predecessor: "2FS", Progress: 50, isParent: false },
        ]
    },
    {
        TaskID: 5,
        TaskName: 'Project Estimation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            {
                TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4],
                isParent: false, info: 'Develop floor plans and obtain a materials list for estimations'
            },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, resources: [4, 8], isParent: false, info: '' },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 0, Predecessor: "6SS", Progress: 50, resources: [12, 5], isParent: false, info: '' }
        ]
    },
  ];
  
  import * as React from 'react';
  import * as ReactDOM from 'react-dom';
  import { GanttComponent, Inject,Toolbar, ToolbarItem, Edit, ColumnsDirective, ColumnDirective, AddDialogFieldsDirective, EditSettingsModel, EditDialogFieldsDirective, EditDialogFieldDirective, AddDialogFieldDirective } from '@syncfusion/ej2-react-gantt';
  
  function App(){
      const taskFields: any = {
          id: 'TaskID',
          name: 'TaskName',
          startDate: 'StartDate',
          endDate: 'EndDate',
          duration: 'Duration',
          progress: 'Progress',
          dependency: 'Predecessor',
          child: 'subtasks',
          notes: 'info',
          resourceInfo: 'resources'
    };
    const toolbarOptions: ToolbarItem[] = ['Add'];
      const editOptions: EditSettingsModel = {
          allowEditing: true,
          allowAdding:true,
          mode: 'Dialog'
    };
      const resourceFields: any = {
          id: 'resourceId',
          name: 'resourceName',
      };
          return <GanttComponent dataSource={data} toolbar={toolbarOptions} taskFields={taskFields} editSettings={editOptions} height='450px'
          resourceFields={resourceFields} resources={ProjectResources}>
           <ColumnsDirective>
                  <ColumnDirective field='TaskID' width='100' ></ColumnDirective>
                  <ColumnDirective field='TaskName' headerText='Job Name' width='250'></ColumnDirective>
                  <ColumnDirective field='resources'></ColumnDirective>
                  <ColumnDirective field='StartDate'></ColumnDirective>
                  <ColumnDirective field='Duration'></ColumnDirective>
                  <ColumnDirective field='Progress'></ColumnDirective>
                  <ColumnDirective field='Predecessor'></ColumnDirective>
                  <ColumnDirective field='isParent' headerText='Custom Column'></ColumnDirective>
              </ColumnsDirective>
          <AddDialogFieldsDirective>
              <AddDialogFieldDirective type='General' headerText='General' fields= {['TaskID', 'TaskName', 'isParent']}></AddDialogFieldDirective>
              <AddDialogFieldDirective type='Dependency'></AddDialogFieldDirective>
              <AddDialogFieldDirective type='Resources'></AddDialogFieldDirective>
          </AddDialogFieldsDirective>
             <EditDialogFieldsDirective>
                <EditDialogFieldDirective type='General' headerText='General' fields= {['TaskID', 'TaskName', 'isParent']}></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Dependency'></EditDialogFieldDirective>
                <EditDialogFieldDirective type='Resources'></EditDialogFieldDirective>
            </EditDialogFieldsDirective>
              <Inject services={[Edit, 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/28.1.33/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

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

</html>

Task dependencies

In the Gantt component, you can update the dependencies between tasks and link the tasks interactively. The task dependencies can be mapped from the data source using the dependency property.

You can update the task dependencies using the following ways:

  • Mouse interactions: Using connector points in the taskbar, you can perform drag and drop action to create task dependency links.
  • Edit dialog: Create or remove the task dependencies using the Dependency tab in the edit dialog.
  • Cell editing: Create or remove the task links using cell editing.

The following code example demonstrates how to enable task dependency editing in the Gantt chart using the editSettings property.

let data = [
    {
        TaskID: 1,
        TaskName: 'Project Initiation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 0, Progress: 50 },
            { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50 },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, Predecessor: "2FS", Progress: 50 },
        ]
    },
    {
        TaskID: 5,
        TaskName: 'Project Estimation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50 },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50 },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 0, Predecessor: "6SS", Progress: 50 }
        ]
    },
  ];
  
  
  import * as React from 'react';
  import * as ReactDOM from 'react-dom';
  import { GanttComponent, Inject, Edit } from '@syncfusion/ej2-react-gantt';
  
  function App(){
      const taskFields = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress',
      dependency: 'Predecessor',
      child: 'subtasks'
     };
    const  editOptions = {
      allowEditing: true,
      allowTaskbarEditing: true
    };
          return <GanttComponent dataSource={data} taskFields={taskFields}
          editSettings={editOptions} height = '450px'>
               <Inject services={[Edit]} />
          </GanttComponent>
  };
  ReactDOM.render(<App />, document.getElementById('root'));
let data: Object[] = [
    {
        TaskID: 1,
        TaskName: 'Project Initiation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 0, Progress: 50 },
            { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50 },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, Predecessor: "2FS", Progress: 50 },
        ]
    },
    {
        TaskID: 5,
        TaskName: 'Project Estimation',
        StartDate: new Date('04/02/2019'),
        EndDate: new Date('04/21/2019'),
        isParent: true,
        subtasks: [
            { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50 },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50 },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 0, Predecessor: "6SS", Progress: 50 }
        ]
    },
  ];
  
  
  import * as React from 'react';
  import * as ReactDOM from 'react-dom';
  import { GanttComponent, Inject, Edit, EditSettingsModel } from '@syncfusion/ej2-react-gantt';
  
  function App(){
      const taskFields: any = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress',
      dependency: 'Predecessor',
      child: 'subtasks'
     };
    const  editOptions: EditSettingsModel = {
      allowEditing: true,
      allowTaskbarEditing: true
    };
          return <GanttComponent dataSource={data} taskFields={taskFields}
          editSettings={editOptions} height = '450px'>
               <Inject services={[Edit]} />
          </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/28.1.33/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

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

</html>

Alt text

Updating with mouse interaction action

Alt text

Updating with cell Edit

Alt text

Updating with Dialog

Note: When the edit mode is set to Auto, on performing double-click action on TreeGrid side, the cells will be changed to editable mode and on performing double-click action on chart side, the edit dialog will appear for editing the task details.

Update task values using method

Tasks’ value can be dynamically updated by using the updateRecordById method. You can call this method on any custom action. The following code example shows how to use this method to update a task.

NOTE: Using the updateRecordById method, you cannot update the task ID value.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { GanttComponent, Inject, Edit, Selection } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App(){
    const  taskFields = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    child: 'subtasks'
  };
  const  editOptions = {
      allowEditing: true
  };
  let ganttInstance;
 function clickHandler(){
    let data = {
        TaskID: 3,
        TaskName: 'Updated by index value',
        StartDate: new Date('04/02/2019'),
        Duration: 4,
        Progress: 50
    };
    ganttInstance.updateRecordByID(data);
}
        return (<div>
        <ButtonComponent onClick= { clickHandler}>Update Record</ButtonComponent>
        <GanttComponent dataSource={data}  ref={gantt => ganttInstance = gantt} taskFields={taskFields} allowSelection={true}
        editSettings={editOptions} height = '450px'>
            <Inject services={[Edit, Selection]} />
        </GanttComponent></div>)
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { GanttComponent, Inject, Edit, EditSettingsModel, Selection } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App(){
    const  taskFields: any = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    child: 'subtasks'
  };
  const  editOptions: EditSettingsModel = {
      allowEditing: true
  };
  let ganttInstance:any;
 function clickHandler(){
    let data: any = {
        TaskID: 3,
        TaskName: 'Updated by index value',
        StartDate: new Date('04/02/2019'),
        Duration: 4,
        Progress: 50
    };
    ganttInstance.updateRecordByID(data);
}
        return (<div>
        <ButtonComponent onClick= { clickHandler}>Update Record</ButtonComponent>
        <GanttComponent dataSource={data}  ref={gantt => ganttInstance = gantt} taskFields={taskFields} allowSelection={true}
        editSettings={editOptions} height = '450px'>
            <Inject services={[Edit, Selection]} />
        </GanttComponent></div>)
};
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/28.1.33/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

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

</html>

Capture the modified records in React Gantt component

In the EJ2 Gantt chart, modified records can be conveniently retrieved after adding, editing, or deleting data by utilizing the [actionComplete] (https://ej2.syncfusion.com/react/documentation/api/gantt/actionCompleteArgs/) event.

The following code example serves as a practical illustration of how to effectively capture the modified records within the Gantt control.

import { GanttComponent, Inject, Edit, Selection, Toolbar } from '@syncfusion/ej2-react-gantt';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { data } from './datasource';
function App() {
    const taskFields = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        child: 'subtasks',
    };
    const editSettings = {
        allowEditing: true,
        allowAdding: true,
        allowDeleting: true,
        allowTaskbarEditing: true,
        showDeleteConfirmDialog: true,
        mode: 'Auto',
    };
    const toolbar = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll', 'Search',
    'PrevTimeSpan', 'NextTimeSpan'];

    function actionComplete(args) {
        if (args.requestType == 'add') {
            console.log("Added new record values available in the 'args' variable as 'newTaskData'", args);
        }
        if (args.requestType == 'save') {
            console.log("Edited record values available in the 'args' variable as 'modifiedTaskData'", args);
        }
        if (args.requestType == 'delete') {
            console.log("Modified Records after Delete action", args);
        }
    }
    return <GanttComponent dataSource = {data} taskFields = {taskFields} allowSelection = {true} editSettings = {editSettings} height = '400px' actionComplete = {actionComplete} toolbar = {toolbar}>
           <Inject services = {[Edit, Selection, Toolbar]}/>
        </GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
import { GanttComponent, Inject, Edit, Selection, Toolbar } from '@syncfusion/ej2-react-gantt';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { data } from './datasource';
function App () {
   const taskFields: any = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    child: 'subtasks',
  };
  const editSettings: any = {
    allowEditing: true,
    allowAdding: true,
    allowDeleting: true,
    allowTaskbarEditing: true,
    showDeleteConfirmDialog: true,
    mode: 'Auto',
  };
  const toolbar: any = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll', 'Search',
    'PrevTimeSpan', 'NextTimeSpan'];

  function actionComplete(args: any) {
    if (args.requestType == 'add') {
        console.log("Added new record values available in the 'args' variable as 'newTaskData'", args);
    }
    if (args.requestType == 'save') {
        console.log("Edited record values available in the 'args' variable as 'modifiedTaskData'", args);
    }
    if (args.requestType == 'delete') {
        console.log("Modified Records after Delete action", args);
    }
  };
  return <GanttComponent dataSource = {data} taskFields = {taskFields} allowSelection = {true}
        editSettings = {editSettings} height = '400px' actionComplete = {actionComplete} toolbar = {toolbar}>
           <Inject services = {[Edit, Selection, 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/28.1.33/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

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

</html>

The following screenshots represent sample add, edit, and delete record actions using the gantt args.

The data of the newly added record can be obtained from actionComplete event by requestType of [args.requestType] (https://ej2.syncfusion.com/react/documentation/api/gantt/iActionBeginEventArgs/#requesttype) to the action add and the following screenshot shows that the added record’s data is available in [args.newTaskData] (../../api/gantt/actionCompleteArgs/#newtaskdata) property.

Add action

The data of the edited record can be obtained from actionComplete event by requestType of [args.requestType] (../../api/gantt/iActionBeginEventArgs/#requesttype) to the action save and the following screenshot shows that the edited record’s data is available in [args.modifiedTaskData] (../../api/gantt/iActionBeginEventArgs/#modifiedtaskdata) property.

Edit action

The data of the deleted record can be obtained from actionComplete event by requestType of [args.requestType] (../../api/gantt/iActionBeginEventArgs/#requesttype) to the action delete and the following screenshot shows that the deleted record’s data is available in [args.modifiedRecords] (../../api/gantt/iActionBeginEventArgs/#modifiedrecords) property.

Delete action