Scrolling in React TreeGrid

8 Oct 202517 minutes to read

The scrollbar is displayed in the TreeGrid when content exceeds the element width or height. The vertical and horizontal scrollbars appear based on the following criteria:

  • The vertical scrollbar appears when the total height of rows in the TreeGrid exceeds its element height.

  • The horizontal scrollbar appears when the sum of column widths exceeds the TreeGrid element width.

  • The height and width properties set the TreeGrid height and width, respectively.

The default value for height and width is auto.

Set width and height

To specify the scroller width and height in pixels, assign a numeric pixel value.

import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';

import { sampleData } from './datasource';
function App() {
    return <TreeGridComponent dataSource={sampleData} treeColumnIndex={1} childMapping='subtasks' height='315' width='400'>
        <ColumnsDirective>
            <ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
            <ColumnDirective field='taskName' headerText='Task Name' width='180'/>
            <ColumnDirective field='startDate' headerText='Start Date' width='120' format='yMd' textAlign='Right' type='date'/>
            <ColumnDirective field='duration' headerText='Duration' width='110' textAlign='Right'/>
        </ColumnsDirective>
    </TreeGridComponent>;
}
;
export default App;
import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';

import { sampleData } from './datasource';

function App() {
    return <TreeGridComponent dataSource={sampleData} treeColumnIndex={1} childMapping='subtasks'
        height='315' width='400'>
        <ColumnsDirective>
            <ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
            <ColumnDirective field='taskName' headerText='Task Name' width='180'/>
            <ColumnDirective field='startDate' headerText='Start Date' width='120' format='yMd' textAlign='Right' type='date' />
            <ColumnDirective field='duration' headerText='Duration' width='110' textAlign='Right' />
        </ColumnsDirective>
    </TreeGridComponent>
};
export default App;

Responsive with parent container

Specify width and height as 100% to make the TreeGrid fill its parent container. When height is set to 100%, the parent element must have an explicit height.

import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';
import { sampleData } from './datasource';
function App() {
    return <TreeGridComponent dataSource={sampleData} treeColumnIndex={1} childMapping='subtasks' height='100%' width='100%'>
        <ColumnsDirective>
            <ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
            <ColumnDirective field='taskName' headerText='Task Name' width='180'/>
            <ColumnDirective field='startDate' headerText='Start Date' width='120' format='yMd' textAlign='Right' type='date'/>
            <ColumnDirective field='duration' headerText='Duration' width='110' textAlign='Right'/>
        </ColumnsDirective>
    </TreeGridComponent>;
}
;
export default App;
import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';
import { sampleData } from './datasource';

function App() {
    return <TreeGridComponent dataSource={sampleData} treeColumnIndex={1} childMapping='subtasks'
    height='100%' width='100%'>
        <ColumnsDirective>
            <ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
            <ColumnDirective field='taskName' headerText='Task Name' width='180'/>
            <ColumnDirective field='startDate' headerText='Start Date' width='120' format='yMd' textAlign='Right' type='date' />
            <ColumnDirective field='duration' headerText='Duration' width='110' textAlign='Right' />
        </ColumnsDirective>
    </TreeGridComponent>
};
export default App;

The Syncfusion React TreeGrid can keep column headers fixed (sticky) while scrolling through large datasets. Sticky headers remain visible to preserve column context during vertical scrolling, which is especially helpful with wide or lengthy hierarchical data.

Enabling sticky headers ensures that the header row remains anchored to the top of the TreeGrid container or its parent scrolling element, regardless of scroll position.

To enable sticky headers in the TreeGrid, set the enableStickyHeader property to true. This keeps column headers anchored to the top of the TreeGrid container or its parent scrolling container during vertical scroll.

The following sample demonstrates enabling or disabling the sticky header in the TreeGrid using a Switch and its change event:

import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import { SwitchComponent } from '@syncfusion/ej2-react-buttons';
import * as React from 'react';
import { sampleData } from './datasource';

function App() {
  let treeGrid;

  const onChange = (args) => {
    treeGrid.enableStickyHeader = args.checked;
  }

  return (
    <div>
      <div style=>
        <label style=>Enable/Disable Sticky Header </label>
        <SwitchComponent checked={true} change={onChange}></SwitchComponent>
      </div>
      <div style=>
        <TreeGridComponent ref={g => treeGrid = g} dataSource={sampleData} enableStickyHeader={true} treeColumnIndex={1} childMapping='SubTasks'>
          <ColumnsDirective>
            <ColumnDirective field='TaskID' headerText='Task ID' width='90' textAlign='Right' />
            <ColumnDirective field='TaskName' headerText='Task Name' width='180' />
            <ColumnDirective field='StartDate' headerText='Start Date' width='120' format='yMd' textAlign='Right' type='date' />
            <ColumnDirective field='Duration' headerText='Duration' width='110' textAlign='Right' />
          </ColumnsDirective>
        </TreeGridComponent>
      </div>
    </div>
  );
};
export default App;
import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import { ChangeEventArgs, SwitchComponent } from '@syncfusion/ej2-react-buttons';
import * as React from 'react';
import { sampleData } from './datasource';

function App() {
  let treeGrid: TreeGridComponent | null;

  const onChange = (args: ChangeEventArgs) => {
    (treeGrid as TreeGridComponent).enableStickyHeader = (args.checked as boolean);
  };

  return (
    <div>
      <div style=>
        <label style=>Enable/Disable Sticky Header </label>
        <SwitchComponent checked={true} change={onChange}></SwitchComponent>
      </div>
      <div style=>
        <TreeGridComponent ref={g => treeGrid = g} dataSource={sampleData} enableStickyHeader={true} treeColumnIndex={1} childMapping='SubTasks'>
          <ColumnsDirective>
            <ColumnDirective field='TaskID' headerText='Task ID' width='90' textAlign='Right' />
            <ColumnDirective field='TaskName' headerText='Task Name' width='180' />
            <ColumnDirective field='StartDate' headerText='Start Date' width='120' format='yMd' textAlign='Right' type='date' />
            <ColumnDirective field='Duration' headerText='Duration' width='110' textAlign='Right' />
          </ColumnsDirective>
        </TreeGridComponent>
      </div>
    </div>
  );
}

export default App;

Scroll to selected row

Scroll the TreeGrid content to the selected row position by using the rowSelected event.

import { NumericTextBoxComponent } from '@syncfusion/ej2-react-inputs';
import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';

import { sampleData } from './datasource';
function App() {
    let treegrid;
    let numeric;
    const onChange = () => {
        if (treegrid && numeric) {
            treegrid.selectRow(parseInt(numeric.getText(), 10));
        }
    };
    const rowSelected = (args) => {
        if (treegrid) {
            const rowHeight = treegrid.getRows()[treegrid.getSelectedRowIndexes()[0]].scrollHeight;
            treegrid.getContent().children[0].scrollTop = rowHeight * treegrid.getSelectedRowIndexes()[0];
        }
    };
    return (<div>
        <NumericTextBoxComponent format={'N'} placeholder={'Enter index to select a row'} width={200} showSpinButton={false} min={0} change={onChange} ref={numeric}/>
            <TreeGridComponent dataSource={sampleData} treeColumnIndex={1} childMapping='subtasks' height='270' width='100%' rowSelected={rowSelected} ref={g => treegrid = g}>
        <ColumnsDirective>
            <ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
            <ColumnDirective field='taskName' headerText='Task Name' width='160'/>
            <ColumnDirective field='startDate' headerText='Start Date' width='90' format='yMd' textAlign='Right' type='date'/>
            <ColumnDirective field='duration' headerText='Duration' width='80' textAlign='Right'/>
        </ColumnsDirective>
    </TreeGridComponent></div>);
}
;
export default App;
import { RowSelectEventArgs } from '@syncfusion/ej2-grids';
import { NumericTextBox, NumericTextBoxComponent } from '@syncfusion/ej2-react-inputs';
import { ColumnDirective, ColumnsDirective, TreeGridComponent } from '@syncfusion/ej2-react-treegrid';
import { TreeGrid } from '@syncfusion/ej2-react-treegrid';
import * as React from 'react';

import { sampleData } from './datasource';

function App() {
    let treegrid: TreeGridComponent | null;
    let numeric: NumericTextBox | null;

    const onChange = () => {
        if (treegrid && numeric) {
            treegrid.selectRow(parseInt(numeric.getText(), 10));
        }
    }

    const rowSelected = (args: RowSelectEventArgs) => {
        if (treegrid) {
            const rowHeight: number = treegrid.getRows()[treegrid.getSelectedRowIndexes()[0]].scrollHeight;
            treegrid.getContent().children[0].scrollTop = rowHeight * treegrid.getSelectedRowIndexes()[0];
        }
    }

    return (<div>
        <NumericTextBoxComponent format={'N'} placeholder={'Enter index to select a row'} width={200}
            showSpinButton={false} min={0} change={onChange} ref={numeric}/>
            <TreeGridComponent dataSource={sampleData} treeColumnIndex={1} childMapping='subtasks'
            height='270' width='100%' rowSelected={rowSelected} ref={g => treegrid = g}>
        <ColumnsDirective>
            <ColumnDirective field='taskID' headerText='Task ID' width='90' textAlign='Right'/>
            <ColumnDirective field='taskName' headerText='Task Name' width='160'/>
            <ColumnDirective field='startDate' headerText='Start Date' width='90' format='yMd' textAlign='Right' type='date' />
            <ColumnDirective field='duration' headerText='Duration' width='80' textAlign='Right' />
        </ColumnsDirective>
    </TreeGridComponent></div>)
};
export default App;