Scrolling in Angular Grid component

2 Sep 202524 minutes to read

The scrolling feature in the Angular Grid component enables seamless navigation through content that extends beyond the visible area of the grid. Scrollbars are automatically displayed when the content exceeds the specified width or height of the grid element, making it practical to display large amounts of data within a limited space. Vertical and horizontal scrollbars are displayed under the following conditions:

  • The vertical scrollbar is shown when the total height of rows in the grid exceeds its element height.
  • The horizontal scrollbar appears when the sum of column widths exceeds the grid element width.
  • The height and width properties set the grid’s height and width, respectively.

The default value for both height and width is auto.

Set width and height

The Angular Grid component enables you to precisely define the width and height of the scroller to match your requirements. Use pixel values (as numbers) for the width and height properties for direct control of the grid’s dimensions.

In the following example, the vertical and horizontal scrollbars are enabled. The grid’s height is set to 315 pixels and the width to 400 pixels:

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule } from '@syncfusion/ej2-angular-grids'



import { Component, OnInit } from '@angular/core';
import { data } from './datasource';

@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

The Grid can fill its parent container and respond automatically to changes in available space, making it ideal for adaptive layouts and responsive applications. To achieve this, specify the width and height properties as 100%. Note that when setting the grid’s height to 100%, the parent container must have an explicit height defined.

The example below demonstrates a parent container with explicit dimensions and the grid set to 100% height and width for responsive behavior:

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule } from '@syncfusion/ej2-angular-grids'

import { Component, OnInit } from '@angular/core';
import { data } from './datasource';

@Component({
imports: [
        
        GridModule
    ],


standalone: true,
    selector: 'app-root',
    template: `
         <div style="height:500px;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));

The Angular Grid supports sticky column headers, ensuring that headers remain visible while scrolling through the grid content. Enable this feature by setting the enableStickyHeader property to true.

In the following demonstration, column headers remain fixed while scrolling the Grid’s parent div:

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule } from '@syncfusion/ej2-angular-grids'
import { SwitchModule } from '@syncfusion/ej2-angular-buttons'

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

@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

The Angular Grid can automatically scroll to and bring any selected row into view. This is especially useful when working with large datasets and ensures the selected row remains in focus. Use the rowSelected event to scroll to a selected row.

The following example shows how the rowSelected event can be used to scroll to the chosen row:

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule, PageService, ToolbarService, EditService,RowSelectEventArgs, GridComponent } from '@syncfusion/ej2-angular-grids'
import { DropDownListModule,ChangeEventArgs } from '@syncfusion/ej2-angular-dropdowns'
import { Component, OnInit, ViewChild } from '@angular/core';
import { data } from './datasource';
 
@Component({
    imports: [GridModule,DropDownListModule ],
    providers: [PageService, ToolbarService, EditService],
    standalone: true,
    selector: 'app-root',
    template: `   
            <div style="display: flex">
                <label style="padding: 30px 20px 0 0" > Select row index :</label>
                <ejs-dropdownlist #dropdown id='value' style="padding: 26px 0 0 0" #sample index='0' 
                width='220' [dataSource]='dropDownData' (change)='valueChange($event)' >
                </ejs-dropdownlist>
            </div>
            <div style="padding: 20px 17px 0 0">
                <ejs-grid #grid [dataSource]='data' height='315' 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

The Syncfusion Grid allows you to hide empty scrollbar placeholders for a cleaner appearance. Use the hideScroll method to hide the scrollbar based on content overflow. This helps maintain a tidy interface and avoids showing unnecessary scrollbars.

The following example demonstrates how to use the hideScroll method in the dataBound event:

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GridModule } from '@syncfusion/ej2-angular-grids'



import { Component, OnInit, ViewChild } from '@angular/core';
import { data } from './datasource';
import { GridComponent } 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

The Syncfusion Angular Grid supports rendering horizontal scrollbars at both the top and bottom, improving navigation when working with wide datasets. This enhances accessibility by providing scroll access from either direction.

To render a scrollbar at the top of the Grid:

  1. Add a Scrollbar - Insert a <div id="scroller"> above the Grid in the template to serve as the top scrollbar.
  2. Initialize Scrollbar in created Event - Dynamically move the scroller div above the grid content and set up its properties.
  3. Synchronize Scroll Events - Connect the onscroll events of the top scroller and the Grid content so they scroll together.
  4. Adjust Scrollbar Width and Visibility - Use setScroller() to ensure the scrollbar width matches the Grid and updates on window resize.

The example below shows how to use the created event to insert and synchronize a scrollbar at the top of the Grid content:

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

@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));