Syncfusion AI Assistant

How can I help you?

Filtering in React Gantt Chart Component

7 Apr 202624 minutes to read

Filtering allows you to view specific or related records based on defined criteria. The Gantt Chart component supports options like filter menu, Excel-like filtering, and toolbar search to narrow down visible data.

To enable filtering, set allowFiltering to true in the Gantt configuration. You can define filter options using filterSettings and configure toolbar search using searchSettings property.

To activate filtering functionality, inject the Filter service in the providers of the component.

  • The filtering UI is rendered based on the column type, allowing data to be filtered using appropriate operators.
  • The filter menu is enabled by default. To disable the filtering option for a specific column, set the allowFiltering property of the column to false.

Apply initial filter on load

To apply filtering during the initial render of the Syncfusion® React Gantt Chart component, define the filter conditions using a predicate object within the filterSettings.columns property.

The following sample demonstrates how to apply an initial filter where TaskName starts with Identify and TaskID equals 2, using a Predicate condition set to and.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
  GanttComponent,
  Inject,
  Filter,
  ColumnsDirective,
  ColumnDirective
} 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 splitterSettings = {
    columnIndex: 3
  };

  const filterSettings = {
    columns: [
      { field: 'TaskName', matchCase: false, operator: 'startswith', predicate: 'and', value: 'Identify' },
      { field: 'TaskID', matchCase: false, operator: 'equal', predicate: 'and', value: 2 }
    ]
  };

  return (
    <GanttComponent
      height="370px"
      allowFiltering={true}
      dataSource={data}
      taskFields={taskFields}
      splitterSettings={splitterSettings}
      filterSettings={filterSettings}
    >
      <ColumnsDirective>
        <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="100" />
        <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
        <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
        <ColumnDirective field="Duration" headerText="Duration" width="150" />
        <ColumnDirective field="Progress" headerText="Progress" width="150" />
      </ColumnsDirective>

      <Inject services={[Filter]} />
    </GanttComponent>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
  GanttComponent,
  Inject,
  Filter,
  ColumnsDirective,
  ColumnDirective
} from '@syncfusion/ej2-react-gantt';
import {
  TaskFieldsModel,
  SplitterSettingsModel,
  FilterSettingsModel,
} from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';

function App() {

  const taskFields: TaskFieldsModel = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    parentID: 'ParentID'
  };

  const splitterSettings: SplitterSettingsModel = {
    columnIndex: 3
  };

  const filterSettings: FilterSettingsModel = {
    columns: [
      { field: 'TaskName', matchCase: false, operator: 'startswith', predicate: 'and', value: 'Identify' },
      { field: 'TaskID', matchCase: false, operator: 'equal', predicate: 'and', value: 2 }
    ]
  };

  return (
    <GanttComponent
      height="370px"
      allowFiltering={true}
      dataSource={data}
      taskFields={taskFields}
      splitterSettings={splitterSettings}
      filterSettings={filterSettings}
    >
      <ColumnsDirective>
        <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="100" />
        <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
        <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
        <ColumnDirective field="Duration" headerText="Duration" width="150" />
        <ColumnDirective field="Progress" headerText="Progress" width="150" />
      </ColumnsDirective>

      <Inject services={[Filter]} />
    </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.2.3/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>

Supported filter operators

Filter operators can be set using the filterSettings.columns.operator property to define the comparison logic for each column.

The available operators and their supported data types are:

Operator Description Supported Types
startswith Matches values beginning with the specified value. String
endswith Matches values ending with the specified value. String
contains Matches values that include the specified value. String
equal Matches values exactly equal to the specified value. String, Number, Boolean, Date
notequal Matches values not equal to the specified value. String, Number, Boolean, Date
greaterthan Matches values greater than the specified value. Number, Date
greaterthanorequal Matches values greater than or equal to the value. Number, Date
lessthan Matches values less than the specified value. Number, Date
lessthanorequal Matches values less than or equal to the value. Number, Date

By default, the filterSettings.columns.operator value is equal

Hierarchy-based filtering modes

The React Gantt Chart component supports multiple filtering modes, which can be configured using the filterSettings.hierarchyMode property. The available modes are:

  • Parent: This is the default mode. Filtered records are displayed along with their parent records. If no parent exists, only the filtered records are shown.

  • Child: Displays filtered records along with their child records. If no child exists, only the filtered records are shown.

  • Both: Displays filtered records along with both parent and child records. If neither exists, only the filtered records are shown.

  • None: Displays only the filtered records without any parent or child context.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, Toolbar, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
import { data } from './datasource';

function App() {

    let ganttInstance = null;

    const taskFields = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    };

    const splitterSettings = {
        columnIndex: 3
    };

    const toolbar = ['Search'];

    const dropData = [
        { id: 'Parent', mode: 'Parent' },
        { id: 'Child', mode: 'Child' },
        { id: 'Both', mode: 'Both' },
        { id: 'None', mode: 'None' }
    ];

    const fields = { text: 'mode', value: 'id' };

    function onChange(e) {
        const mode = e.value;
        ganttInstance.filterSettings.hierarchyMode = mode;
        ganttInstance.searchSettings.hierarchyMode = mode;
        ganttInstance.clearFiltering();
    }

    return (
        <div>
            <div style=>
                <label style=>Hierarchy Mode:</label>
                <DropDownListComponent change={onChange} dataSource={dropData} fields={fields} value="Parent" width="200px" />
            </div>

            <GanttComponent
                ref={(g) => (ganttInstance = g)}
                height="370px"
                allowFiltering={true}
                dataSource={data}
                taskFields={taskFields}
                toolbar={toolbar}
                splitterSettings={splitterSettings}
            >
                <ColumnsDirective>
                    <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="100" />
                    <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
                    <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
                    <ColumnDirective field="Duration" headerText="Duration" width="150" />
                    <ColumnDirective field="Progress" headerText="Progress" width="150" />
                </ColumnsDirective>

                <Inject services={[Filter, Toolbar]} />
            </GanttComponent>
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, Toolbar, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { TaskFieldsModel, SplitterSettingsModel, ColumnModel } from '@syncfusion/ej2-react-gantt';
import { DropDownListComponent, ChangeEventArgs } from '@syncfusion/ej2-react-dropdowns';
import { data } from './datasource';

function App() {

  let ganttInstance: GanttComponent = null;

  const taskFields: TaskFieldsModel = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    duration: 'Duration',
    progress: 'Progress',
    parentID: 'ParentID'
  };

  const splitterSettings: SplitterSettingsModel = {
    columnIndex: 3
  };

  const toolbar: any = ['Search'];

  const dropData: object[] = [
    { id: 'Parent', mode: 'Parent' },
    { id: 'Child', mode: 'Child' },
    { id: 'Both', mode: 'Both' },
    { id: 'None', mode: 'None' }
  ];

  const fields: object = { text: 'mode', value: 'id' };

  function onChange(e: ChangeEventArgs): void {
    const mode: any = e.value;
    ganttInstance.filterSettings.hierarchyMode = mode;
    ganttInstance.searchSettings.hierarchyMode = mode;
    ganttInstance.clearFiltering();
  }

  return (
    <div>
      <div style=>
        <label style=>Hierarchy Mode:</label>
        <DropDownListComponent change={onChange} dataSource={dropData} fields={fields} value="Parent" width="200px"/>
      </div>

      <GanttComponent
        ref={(g) => (ganttInstance = g)}
        height="370px"
        allowFiltering={true}
        dataSource={data}
        taskFields={taskFields}
        toolbar={toolbar}
        splitterSettings={splitterSettings}
      >
        <ColumnsDirective>
          <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="100" />
          <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
          <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
          <ColumnDirective field="Duration" headerText="Duration" width="150" />
          <ColumnDirective field="Progress" headerText="Progress" width="150" />
        </ColumnsDirective>

        <Inject services={[Filter, Toolbar]} />
      </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/33.2.3/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>

Enable diacritic-sensitive filtering

By default, the Syncfusion® React Gantt Chart component ignores diacritic characters during filtering. To enable filtering with diacritic sensitivity, set the filterSettings.ignoreAccent property to true.

The following sample demonstrates this behavior: when filtering the TaskName column, entries containing diacritic characters (e.g., “Próject”, “Projéct”) will be matched if you enter the base text Project.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, ColumnsDirective, ColumnDirective } 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 splitterSettings = {
        columnIndex: 3
    };

    const filterSettings = {
        ignoreAccent: true
    };

    return (
        <GanttComponent
            height="370px"
            allowFiltering={true}
            dataSource={data}
            taskFields={taskFields}
            splitterSettings={splitterSettings}
            filterSettings={filterSettings}
        >
            <ColumnsDirective>
                <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="120" />
                <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
                <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
                <ColumnDirective field="Duration" headerText="Duration" width="150" />
                <ColumnDirective field="Progress" headerText="Progress" width="150" />
            </ColumnsDirective>

            <Inject services={[Filter]} />
        </GanttComponent>
    );
}

ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { TaskFieldsModel, SplitterSettingsModel, FilterSettingsModel } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';

function App() {

    const taskFields: TaskFieldsModel = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    };

    const splitterSettings: SplitterSettingsModel = {
        columnIndex: 3
    };

    const filterSettings: FilterSettingsModel = {
        ignoreAccent: true
    };

    return (
        <GanttComponent
            height="370px"
            allowFiltering={true}
            dataSource={data}
            taskFields={taskFields}
            splitterSettings={splitterSettings}
            filterSettings={filterSettings}
        >
            <ColumnsDirective>
                <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="120" />
                <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
                <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
                <ColumnDirective field="Duration" headerText="Duration" width="150" />
                <ColumnDirective field="Progress" headerText="Progress" width="150" />
            </ColumnsDirective>

            <Inject services={[Filter]} />
        </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.2.3/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>

Programmatic filtering using method

You can apply dynamic filtering in the Syncfusion® React Gantt by using the filterByColumn method. This enables programmatic filtering without relying on UI interactions.

The following sample demonstrates how to filter the TaskName and TaskID columns using single and multiple values. The filtering is triggered through an external button click by calling the filterByColumn method.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';

function App() {
    let gantt = null;

    const taskFields = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    };

    const splitterSettings = {
        columnIndex: 3
    };

    function onSingleValueFilter() {
        gantt.clearFiltering();
        gantt.filterByColumn('TaskName', 'startswith', 'Iden', 'and');
    }

    function onMultipleValueFilter() {
        gantt.clearFiltering();
        gantt.filterByColumn('TaskID', 'equal', [2, 3, 4], 'or');
    }

    return (
        <div>
            <button className="filter-btn" onClick={onSingleValueFilter}>Filter with single value</button>
            <button onClick={onMultipleValueFilter}>Filter with multiple values</button>
            <br /><br /><br />

            <GanttComponent
                ref={(g) => (gantt = g)}
                height="430px"
                allowFiltering={true}
                dataSource={data}
                taskFields={taskFields}
                splitterSettings={splitterSettings}
            >
                <ColumnsDirective>
                    <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="120" />
                    <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
                    <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
                    <ColumnDirective field="Duration" headerText="Duration" width="150" />
                    <ColumnDirective field="Progress" headerText="Progress" width="150" />
                </ColumnsDirective>

                <Inject services={[Filter]} />
            </GanttComponent>
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { TaskFieldsModel, SplitterSettingsModel } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';

function App() {
    let gantt: any = null;

    const taskFields: TaskFieldsModel = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    };

    const splitterSettings: SplitterSettingsModel = {
        columnIndex: 3
    };

    function onSingleValueFilter(): void {
        gantt.clearFiltering();
        gantt.filterByColumn('TaskName', 'startswith', 'Iden', 'and');
    }

    function onMultipleValueFilter(): void {
        gantt.clearFiltering();
        gantt.filterByColumn('TaskID', 'equal', [2, 3, 4], 'or');
    }

    return (
        <div>
            <button className="filter-btn" onClick={onSingleValueFilter}>Filter with single value</button>
            <button onClick={onMultipleValueFilter}>Filter with multiple values</button>
            <br /><br /><br />

            <GanttComponent
                ref={(g) => (gantt = g)}
                height="430px"
                allowFiltering={true}
                dataSource={data}
                taskFields={taskFields}
                splitterSettings={splitterSettings}
            >
                <ColumnsDirective>
                    <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="120" />
                    <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
                    <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
                    <ColumnDirective field="Duration" headerText="Duration" width="150" />
                    <ColumnDirective field="Progress" headerText="Progress" width="150" />
                </ColumnsDirective>

                <Inject services={[Filter]} />
            </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/33.2.3/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>

Clear all applied filters

You can clear all the filtering conditions applied in the Gantt Chart component by using the clearFiltering method.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';

function App() {
    let gantt = null;

    const taskFields = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    };

    const splitterSettings = {
        columnIndex: 3
    };

    const filterSettings = {
        columns: [
            { field: 'TaskName', matchCase: false, operator: 'startswith', predicate: 'and', value: 'Identify' },
            { field: 'Progress', matchCase: false, operator: 'equal', predicate: 'and', value: 50 }
        ]
    };

    function clearFilter() {
        gantt.clearFiltering();
    }

    return (
        <div>
            <button onClick={clearFilter}>Clear Filter</button>
            <br /><br /><br />
            <GanttComponent
                ref={(g) => (gantt = g)}
                height="370px"
                allowFiltering={true}
                dataSource={data}
                taskFields={taskFields}
                splitterSettings={splitterSettings}
                filterSettings={filterSettings}
            >
                <ColumnsDirective>
                    <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="100" />
                    <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
                    <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
                    <ColumnDirective field="Duration" headerText="Duration" width="150" />
                    <ColumnDirective field="Progress" headerText="Progress" width="150" />
                </ColumnsDirective>
                <Inject services={[Filter]} />
            </GanttComponent>
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { TaskFieldsModel, SplitterSettingsModel, FilterSettingsModel } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';

function App() {
    let gantt: any = null;

    const taskFields: TaskFieldsModel = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    };

    const splitterSettings: SplitterSettingsModel = {
        columnIndex: 3
    };

    const filterSettings: FilterSettingsModel = {
        columns: [
            { field: 'TaskName', matchCase: false, operator: 'startswith', predicate: 'and', value: 'Identify' },
            { field: 'Progress', matchCase: false, operator: 'equal', predicate: 'and', value: 50 }
        ]
    };

    function clearFilter(): void {
        gantt.clearFiltering();
    }

    return (
        <div>
            <button onClick={clearFilter}>Clear Filter</button>
            <br /><br /><br />
            <GanttComponent
                ref={(g) => (gantt = g)}
                height="370px"
                allowFiltering={true}
                dataSource={data}
                taskFields={taskFields}
                splitterSettings={splitterSettings}
                filterSettings={filterSettings}
            >
                <ColumnsDirective>
                    <ColumnDirective field="TaskID" headerText="Task ID" textAlign="Left" width="100" />
                    <ColumnDirective field="TaskName" headerText="Task Name" width="250" />
                    <ColumnDirective field="StartDate" headerText="Start Date" width="150" />
                    <ColumnDirective field="Duration" headerText="Duration" width="150" />
                    <ColumnDirective field="Progress" headerText="Progress" width="150" />
                </ColumnsDirective>
                <Inject services={[Filter]} />
            </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/33.2.3/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>

Set different filter types per column

You can enable different filter types for individual columns in the Gantt Chart component by setting the column.filter.type property.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter } from '@syncfusion/ej2-react-gantt';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
import { data } from './datasource';

function App() {
  let gantt = null;
  let fieldDropDown = null;
  let typeDropDown = null;

  const taskFields = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    progress: 'Progress',
    parentID: 'ParentID'
  };

  const columns = [
    { field: 'TaskID', headerText: 'Task ID', width: 120 },
    { field: 'TaskName', headerText: 'Task Name', width: 250 },
    { field: 'StartDate', headerText: 'Start Date', width: 150 },
    { field: 'Progress', headerText: 'Progress', width: 150 }
  ];

  const fieldData = columns.map(col => col.field);
  const typeData = ['Menu', 'Excel'];

  function onFieldChange() {
    if (!fieldDropDown || !typeDropDown) return;
    typeDropDown.enabled = true;
    const selectedField = fieldDropDown.value;
    const column = columns.find(col => col.field === selectedField);
    const nextType = column && column.filter && column.filter.type ? column.filter.type : null;
    typeDropDown.value = nextType;
    typeDropDown.dataBind();
  }

  function onTypeChange(args) {
    if (!gantt || !fieldDropDown) return;

    const selectedField = fieldDropDown.value;
    const selectedType = args.value;

    const column = columns.find(col => col.field === selectedField);
    if (column) {
      column.filter = { ...(column.filter || {}), type: selectedType };
      if (typeDropDown) {
        typeDropDown.value = selectedType;
        typeDropDown.dataBind();
      }
      gantt.refresh();
    }
  }

  return (
    <div>
      <div style=>
        <div style=>
          <label style=>Select Column:</label>
          <DropDownListComponent
            ref={(ddl) => fieldDropDown = ddl}
            dataSource={fieldData}
            change={onFieldChange}
            placeholder="Select column"
          />
        </div>

        <div style=>
          <label style=>Select Filter Type:</label>
          <DropDownListComponent
            ref={(ddl) => typeDropDown = ddl}
            enabled={false}
            dataSource={typeData}
            change={onTypeChange}
            placeholder="Select filter type"
          />
        </div>
      </div>

      <GanttComponent
        ref={(g) => gantt = g}
        height="430px"
        dataSource={data}
        allowFiltering={true}
        taskFields={taskFields}
        splitterSettings=
        columns={columns}
      >
        <Inject services={[Filter]} />
      </GanttComponent>
    </div>
  );

}
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter, TaskFieldsModel, Columns } from '@syncfusion/ej2-react-gantt';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
import { data } from './datasource';

function App() {
  let gantt: GanttComponent | null = null;
  let fieldDropDown: DropDownListComponent | null = null;
  let typeDropDown: DropDownListComponent | null = null;

  const taskFields: TaskFieldsModel = {
    id: 'TaskID',
    name: 'TaskName',
    startDate: 'StartDate',
    progress: 'Progress',
    parentID: 'ParentID'
  };

  const columns: Columns[] = [
    { field: 'TaskID', headerText: 'Task ID', width: 120 },
    { field: 'TaskName', headerText: 'Task Name', width: 250 },
    { field: 'StartDate', headerText: 'Start Date', width: 150 },
    { field: 'Progress', headerText: 'Progress', width: 150 }
  ];

  const fieldData = columns.map(col => col.field);
  const typeData = ['Menu', 'Excel'];

  function onFieldChange() {
    if (!fieldDropDown || !typeDropDown) return;
    typeDropDown.enabled = true;
    const selectedField = fieldDropDown.value as string;
    const column = columns.find(col => col.field === selectedField);
    const nextType = column && column.filter && column.filter.type ? column.filter.type : null;
    (typeDropDown as any).value = nextType;
    typeDropDown.dataBind();
  }

  function onTypeChange(args: { value: any; }) {
    if (!gantt || !fieldDropDown) return;

    const selectedField = fieldDropDown.value as string;
    const selectedType = args.value;

    const column = columns.find(col => col.field === selectedField);
    if (column) {
      column.filter = { ...(column.filter || {}), type: selectedType };
      if (typeDropDown) {
        (typeDropDown as any).value = selectedType;
        typeDropDown.dataBind();
      }
      gantt.refresh();
    }
  }

  return (
    <div>
      <div style=>
        <div style=>
          <label style=>Select Column:</label>
          <DropDownListComponent
            ref={(ddl: DropDownListComponent) => fieldDropDown = ddl}
            dataSource={fieldData}
            change={onFieldChange}
            placeholder="Select column"
          />
        </div>

        <div style=>
          <label style=>Select Filter Type:</label>
          <DropDownListComponent
            ref={(ddl: DropDownListComponent) => typeDropDown = ddl}
            enabled={false}
            dataSource={typeData}
            change={onTypeChange}
            placeholder="Select filter type"
          />
        </div>
      </div>

      <GanttComponent
        ref={(g: any) => gantt = g}
        height="430px"
        dataSource={data}
        allowFiltering={true}
        taskFields={taskFields}
        splitterSettings=
        columns={columns}
      >
        <Inject services={[Filter]} />
      </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/33.2.3/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>

Customize filtering behavior using events

You can customize the filtering behavior in the Syncfusion® React Gantt using the actionBegin and actionComplete events. These events allow you to inject custom logic at different stages of the filtering workflow.

The following sample demonstrates how to handle different filtering stages using args.requestType:

  • For filterBeforeOpen, customize filter operators based on args.columnType (number or string).
  • For filtering, cancel the action if args.currentFilteringColumn is StartDate.
  • For filterAfterOpen, apply background styling to the filter dialog content and footer.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';

function App() {

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

  const splitterSettings = {
    columnIndex: 2
  };

  const filterSettings = {
    type: 'Menu'
  };

  const columns = [
    { field: 'TaskID', headerText: 'Task ID', width: '120' },
    { field: 'TaskName', headerText: 'Task Name', width: '250' },
    { field: 'StartDate', headerText: 'Start Date', width: '150' },
    { field: 'Progress', headerText: 'Progress', width: '150' },
    { field: 'Approved', headerText: 'Approved', width: '100', type: 'boolean' }
  ];

  const updateMessage = (text) => {
    const msgElement = document.getElementById('message');
    if (msgElement) msgElement.textContent = text;
  };

  function actionBegin(args) {
    let msg = '';

    if (args.requestType === "filterBeforeOpen") {
      if (args.columnType === 'number') {
        args.filterModel.customFilterOperators.numberOperator = [
          { value: 'equal', text: 'Equal' },
          { value: 'notequal', text: 'Not Equal' }
        ];
        msg = 'Custom number filter operators applied.';
      }
      else if (args.columnType === 'string') {
        args.filterModel.customFilterOperators.stringOperator = [
          { value: 'contains', text: 'Contains' },
          { value: 'startswith', text: 'Starts With' }
        ];
        msg = 'Custom string filter operators applied.';
      }
    }

    if (args.requestType === 'filtering' &&
      args.currentFilteringColumn === 'StartDate') {

      args.cancel = true;
      msg = 'Filtering is not allowed for StartDate column';

    } else {
      msg = args.requestType + ' action is triggered in actionBegin';
    }

    updateMessage(msg);
  }

  function actionComplete(args) {
    let msg = '';

    if (args.requestType === "filterAfterOpen") {
      msg = 'Applied custom CSS for filter dialog';

      const content = args.filterModel.dlgDiv.querySelector('.e-dlg-content');
      const footer = args.filterModel.dlgDiv.querySelector('.e-footer-content');

      if (content) content.style.background = '#eeeaea';
      if (footer) footer.style.background = '#30b0ce';
    }

    if (args.requestType === 'filtering') {
      msg = args.requestType + ' action is triggered in actionComplete';
    }

    updateMessage(msg);
  }

  return (
    <div>
      <p style= id="message"></p>
      <GanttComponent
        height="370px"
        allowFiltering={true}
        dataSource={data}
        taskFields={taskSettings}
        columns={columns}
        splitterSettings={splitterSettings}
        filterSettings={filterSettings}
        actionBegin={actionBegin}
        actionComplete={actionComplete}
      >
        <Inject services={[Filter]} />
      </GanttComponent>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Filter } from '@syncfusion/ej2-react-gantt';
import { TaskFieldsModel, SplitterSettingsModel, FilterSettingsModel, ColumnModel } from '@syncfusion/ej2-react-gantt';
import { FilterEventArgs } from '@syncfusion/ej2-react-grids';
import { data } from './datasource';

function App() {

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

  const splitterSettings: SplitterSettingsModel = {
    columnIndex: 2
  };

  const filterSettings: FilterSettingsModel = {
    type: 'Menu'
  };

  const columns: ColumnModel[] = [
    { field: 'TaskID', headerText: 'Task ID', width: '120' },
    { field: 'TaskName', headerText: 'Task Name', width: '250' },
    { field: 'StartDate', headerText: 'Start Date', width: '150' },
    { field: 'Progress', headerText: 'Progress', width: '150' },
    { field: 'Approved', headerText: 'Approved', width: '100', type: 'boolean' }
  ];

  const updateMessage = (text: string): void => {
    const msgElement = document.getElementById('message');
    if (msgElement) msgElement.textContent = text;
  };

  function actionBegin(args: FilterEventArgs): void {
    let msg = '';

    if (args.requestType === "filterBeforeOpen") {
      if ((args as any).columnType === 'number') {
        (args as any).filterModel.customFilterOperators.numberOperator = [
          { value: 'equal', text: 'Equal' },
          { value: 'notequal', text: 'Not Equal' }
        ];
        msg = 'Custom number filter operators applied.';
      }
      else if ((args as any).columnType === 'string') {
        (args as any).filterModel.customFilterOperators.stringOperator = [
          { value: 'contains', text: 'Contains' },
          { value: 'startswith', text: 'Starts With' }
        ];
        msg = 'Custom string filter operators applied.';
      }
    }

    if (args.requestType === 'filtering' &&
      (args as any).currentFilteringColumn === 'StartDate') {

      args.cancel = true;
      msg = 'Filtering is not allowed for StartDate column';

    } else {
      msg = args.requestType + ' action is triggered in actionBegin';
    }

    updateMessage(msg);
  }

  function actionComplete(args: FilterEventArgs): void {
    let msg = '';

    if (args.requestType === "filterAfterOpen") {
      msg = 'Applied custom CSS for filter dialog';

      const content = (args as any).filterModel.dlgDiv.querySelector('.e-dlg-content');
      const footer = (args as any).filterModel.dlgDiv.querySelector('.e-footer-content');

      if (content) content.style.background = '#eeeaea';
      if (footer) footer.style.background = '#30b0ce';
    }

    if (args.requestType === 'filtering') {
      msg = args.requestType + ' action is triggered in actionComplete';
    }

    updateMessage(msg);
  }

  return (
    <div>
      <p style= id="message"></p>

      <GanttComponent
        height="370px"
        allowFiltering={true}
        dataSource={data}
        taskFields={taskSettings}
        columns={columns}
        splitterSettings={splitterSettings}
        filterSettings={filterSettings}
        actionBegin={actionBegin}
        actionComplete={actionComplete}
      >
        <Inject services={[Filter]} />
      </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/33.2.3/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>