HelpBot Assistant

How can I help you?

Scrolling in Angular Grid Component

19 Mar 202623 minutes to read

The scrolling feature in the Angular Grid component enables seamless navigation through content extending beyond the visible grid area. Scrollbars automatically appear when content exceeds the grid dimensions configured via the height and width properties.

Scrollbar behavior:

  • Vertical scrollbar: Appears when total row height exceeds the grid element height.
  • Horizontal scrollbar: Appears when total column width exceeds the grid element width.
  • Default dimensions: Both height and width default to “auto”.

Set width and height

The grid dimension configuration enables precise control over scrollbar display and grid size. Use pixel values with the width and height properties to define exact dimensions.

In the following example, the scrollbar is enabled, and the grid’s height is set to “315” pixels, while the width is set to “400” pixels:

import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { GridModule } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [ GridModule ],
    standalone: true,
    selector: 'app-root',
    template: `<ejs-grid [dataSource]='data' height=315 width=400>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=120></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
                    <e-column field='EmployeeID' headerText='Employee ID' textAlign='Right' width=120></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=150></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' width=150></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=150></e-column>
                </e-columns>
               </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];

    ngOnInit(): void {
        this.data = data;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Responsive with parent container

Responsive grid sizing enables dynamic adjustment to available space. The width and height properties accept “100%” values to fill the parent container.

Parent element configuration is required when setting height to “100%”. The parent container must explicitly define a height value for the grid’s responsive layout to function correctly.

In the following example, the parent container has explicit height and width set, and the grid container’s height and width are both set to “100%”:

import { data } from './datasource';
import { Component, OnInit } from '@angular/core';
import { GridModule } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [ GridModule ],
    standalone: true,
    selector: 'app-root',
    template: `
         <div style="height:380px;width:600px">
           <ejs-grid [dataSource]='data' height='100%' width='100%'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=120></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
                    <e-column field='Frieght' headerText='Frieght' textAlign='Right' width=120></e-column>
                    <e-column field='ShipAddress' headerText='ShipAddress' width=150></e-column>
                </e-columns>
            </ejs-grid>
            </div>`
})
export class AppComponent implements OnInit {

    public data?: object[];

    ngOnInit(): void {
        this.data = data;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Sticky header configuration keeps column headers visible during vertical scrolling. The enableStickyHeader property enables this behavior when set to true.

The following demo enables sticky header behavior during parent container scrolling.

import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { ChangeEventArgs, SwitchModule } from '@syncfusion/ej2-angular-buttons';
import { GridComponent, GridModule } from '@syncfusion/ej2-angular-grids';

@Component({
  imports: [ GridModule,  SwitchModule ],
  standalone: true,
  selector: 'app-root',
  template: `
        <div style="padding:10px 0px 20px 0px">
        <label>Enable/Disable Sticky Header</label>
        <ejs-switch id="switch" (change)="toggleStickyHeader($event)"></ejs-switch>
        </div>
        <div style='height:350px;'>
        <ejs-grid #grid [dataSource]='data'>
            <e-columns>
            <e-column field='OrderID' headerText='Order ID' textAlign='Right' width="120"></e-column>
            <e-column field='CustomerID' headerText='Customer ID' width="150"></e-column>
            <e-column field='Frieght' headerText='Freight' textAlign='Right' width="120"></e-column>
            <e-column field='ShipAddress' headerText='Ship Address' width="150"></e-column>
            </e-columns>
        </ejs-grid>
        </div> `
})
export class AppComponent implements OnInit {
  public data?: object[];
  @ViewChild('grid') public grid?: GridComponent;

  ngOnInit(): void {
    this.data = data;
  }
  toggleStickyHeader(args: ChangeEventArgs): void {
    (this.grid as GridComponent).enableStickyHeader = (args.checked as boolean);
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Scroll to selected row

Auto-scroll functionality automatically displays selected rows in view. The rowSelected event triggers scroll positioning when navigating large datasets.

The following example demonstrates auto-scroll implementation using the rowSelected event:

import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { ChangeEventArgs, DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { EditService, GridComponent, GridModule, PageService, RowSelectEventArgs, ToolbarService } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [GridModule,DropDownListModule ],
    providers: [PageService, ToolbarService, EditService],
    standalone: true,
    selector: 'app-root',
    template: `   
            <div style="display: flex">
                <label style="padding: 5px 5px 0 0" > Select row index :</label>
                <ejs-dropdownlist #dropdown id='value' #sample index='0' 
                width='220' [dataSource]='dropDownData' (change)='valueChange($event)' height='250px'>
                </ejs-dropdownlist>
            </div>
            <div style="padding: 5px 5px 0 0">
                <ejs-grid #grid [dataSource]='data' height='300' width='100%' (rowSelected)='rowSelected($event)'>
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=120></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
                        <e-column field='Frieght' headerText='Employee ID' textAlign='Right' width=120></e-column>
                        <e-column field='ShipAddress' headerText='Ship Address' width=150></e-column>
                    </e-columns>
                </ejs-grid>
            </div>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    @ViewChild('grid')
    public grid?: GridComponent;
    public dropDownData?: Object[] = [
        { text: 'Select count' },
        { text: '10', value: '10' },
        { text: '20', value: '20' },
        { text: '30', value: '30' },
        { text: '80', value: '80' },
        { text: '100', value: '100' },
        { text: '200', value: '200' },
        { text: '232', value: '232' },
        { text: '300', value: '300' },
        { text: '500', value: '500' },
        { text: '800', value: '800' },
        { text: '820', value: '850' },
        { text: '920', value: '920' },
        { text: '2020', value: '2020' },
        { text: '3000', value: '3000' },
        { text: '4000', value: '4000' },
        { text: '4999', value: '4999' }

      ];
    ngOnInit(): void {
        this.data = data;
    }

    valueChange(args: ChangeEventArgs): void  {
        (this.grid as GridComponent).selectionModule.selectRow(parseInt((args.value as string), 10));   
    }
    rowSelected(args: RowSelectEventArgs) {
        const rowHeight: number = (this.grid as any).getRows()[(this.grid as GridComponent).getSelectedRowIndexes()[0]].scrollHeight;
        (this.grid as GridComponent).getContent().children[0].scrollTop = rowHeight * (this.grid as GridComponent).getSelectedRowIndexes()[0];
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Hide the empty placeholder of scrollbar

Scrollbar placeholder hiding enhances interface cleanliness by removing unnecessary scrollbar placeholders. The hideScroll method determines scrollbar visibility based on content overflow.

The following example demonstrates the hideScroll method implementation with the dataBound event:

import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { GridComponent, GridModule } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [GridModule ],
    standalone: true,
    selector: 'app-root',
    template: `<ejs-grid #grid [dataSource]='data' height='315' width='100%' (dataBound)='dataBound()'>
                <e-columns>
                    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=120></e-column>
                    <e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
                    <e-column field='EmployeeID' headerText='Employee ID' textAlign='Right' width=120></e-column>
                    <e-column field='ShipCity' headerText='Ship City' width=150></e-column>
                    <e-column field='ShipCountry' headerText='Ship Country' width=150></e-column>
                    <e-column field='ShipName' headerText='Ship Name' width=150></e-column>
                </e-columns>
               </ejs-grid>`
})
export class AppComponent implements OnInit {

    public data?: object[];
    @ViewChild('grid')
    public grid?: GridComponent;

    ngOnInit(): void {
        this.data = data.slice(0, 2);
    }
    dataBound(): void {
        (this.grid as any).hideScroll();
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Render scrollbar in both top and bottom

Dual scrollbar rendering at top and bottom positions enhances horizontal navigation for large datasets. This configuration enables convenient scrolling from either position.

Implementation steps:

Step Action Details
1 Add HTML Element Insert <div id="scroller"> above the grid to create a top scrollbar.
2 Initialize in created event Position the scroller div above grid content dynamically.
3 Synchronize Scroll Events Link onscroll events between the scroller and grid content.
4 Adjust Width and Visibility Use the setScroller() method to match scrollbar width and respond to resize.

The following example demonstrates to use the created event to insert a scrollbar at the top of the grid content:

import { data } from './datasource';
import { Component, OnInit, ViewChild } from '@angular/core';
import { GridComponent, GridModule } from '@syncfusion/ej2-angular-grids';

@Component({
    imports: [GridModule],
    standalone: true,
    selector: 'app-root',
    template: `<div id="scroller" style="width: 100%; overflow-x: auto;"></div>
                <ejs-grid #grid [dataSource]='data' height='315' width='500' (created)='created()'>
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=90></e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width=100></e-column>
                        <e-column field='EmployeeID' headerText='Employee ID' textAlign='Right' width=80></e-column>
                        <e-column field='OrderDate' headerText='Order Date' width=100 format='yMd' textAlign='Right'></e-column>
                        <e-column field='Freight' headerText='Freight' width=80></e-column>
                        <e-column field='ShipName' headerText='Ship Name' width=130></e-column>
                        <e-column field='ShipAddress' headerText='Ship Address' width=140></e-column>
                        <e-column field='ShipCity' headerText='Ship City' width=100></e-column>
                        <e-column field='ShipCountry' headerText='Ship Country' width=100></e-column>
                        <e-column field='ShipRegion' headerText='Ship Region' width=80></e-column>
                        <e-column field='ShipPostalCode' headerText='Ship Postal Code' width=110></e-column>
                    </e-columns>
                </ejs-grid>`
})
export class AppComponent implements OnInit {
    @ViewChild('grid') public grid?: GridComponent;
    public data?: object[];

    public ngOnInit(): void {
        this.data = data;
    }

    public created(): void {
        const scroller = document.getElementById('scroller') as HTMLDivElement;
        const content = (this.grid as GridComponent).getContent().firstElementChild as HTMLDivElement;
        const contentTable = (this.grid as GridComponent).getContentTable() as HTMLTableElement;
        (this.grid as GridComponent).element.insertBefore(scroller, content.parentElement);

        scroller.onscroll = (): void => { 
            content.scrollLeft = scroller.scrollLeft; 
        };
        
        content.onscroll = (): void => { 
            scroller.scrollLeft = content.scrollLeft; 
        };

        const setScroller = () : void => {
          scroller.innerHTML = `<div style="width: ${contentTable.offsetWidth}px; height: 18px;"></div>`;
          scroller.style.height = content.scrollWidth <= content.clientWidth ? '0px' : '18px';
        };

        setScroller();
        window.onresize = setScroller;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));