Overlays are used for displaying messages over the top of the grid. There are two built-in overlays: loading and no-rows.
This page documents the legacy approach to handling overlays. For the latest documentation, see Overlays Overview.
Loading overlay Copy Link
Show or hide the loading overlay by setting the loading property to true or false.
Show or hide the loading UI. true: the loading overlay is shown, or skeleton rows if loadingRows is enabled (Client-Side Row Model only). false: the loading UI is hidden. undefined: the grid will automatically show the loading overlay until rowData and columnDefs are provided. (Client Side Row Model only) |
The loading overlay takes precedence over the no-rows overlay and is not dependent of the state of rowData.
import { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import "./styles.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ModuleRegistry,
enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([ClientSideRowModelModule]);
interface IAthlete {
athlete: string;
country: string;
}
@Component({
selector: "my-app",
standalone: true,
imports: [AgGridAngular],
template: `<div class="example-wrapper">
<div>
<label class="checkbox">
<input
type="checkbox"
checked=""
(change)="setLoading($event.currentTarget.checked)"
/>
loading
</label>
<button (click)="onBtnClearRowData()">Clear rowData</button>
<button (click)="onBtnSetRowData()">Set rowData</button>
</div>
<ag-grid-angular
style="width: 100%; height: 100%;"
[loading]="true"
[columnDefs]="columnDefs"
[rowData]="rowData"
(gridReady)="onGridReady($event)"
/>
</div> `,
})
export class AppComponent {
private gridApi!: GridApi<IAthlete>;
columnDefs: ColDef[] = [{ field: "athlete" }, { field: "country" }];
rowData!: IAthlete[];
setLoading(value: boolean) {
this.gridApi.setGridOption("loading", value);
}
onBtnClearRowData() {
this.gridApi.setGridOption("rowData", []);
}
onBtnSetRowData() {
this.gridApi.setGridOption("rowData", [
{ athlete: "Michael Phelps", country: "US" },
]);
}
onGridReady(params: GridReadyEvent<IAthlete>) {
this.gridApi = params.api;
}
}
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
#myGrid {
flex: 1 1 0px;
}
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { enableProdMode } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
if (new URLSearchParams(window.location.search).get('prod') !== 'false') {
enableProdMode();
}
const app = bootstrapApplication(AppComponent, {
providers: [provideHttpClient()],
});
No rows overlay Copy Link
When rowData is set to an empty array [], the grid automatically displays the no-rows overlay. The no-rows overlay can also be programmatically shown / hidden via the grid API.
It is recommended to use the Active Overlay to manually display an overlay.
Show the no-rows overlay. If loading is true, this will not do anything.setGridOption('activeOverlay', 'agNoRowsOverlay') . |
Hide the no-rows overlay if it is showing. setGridOption('activeOverlay', undefined) . |
The automatic displaying of the no-rows overlay can be suppressed by setting suppressNoRowsOverlay to true.
import { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import "./styles.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ModuleRegistry,
enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([ClientSideRowModelModule]);
interface IAthlete {
athlete: string;
country: string;
}
@Component({
selector: "my-app",
standalone: true,
imports: [AgGridAngular],
template: `<div class="example-wrapper">
<div>
<button (click)="onBtnClearRowData()">Clear rowData</button>
<button (click)="onBtnSetRowData()">Set rowData</button>
</div>
<ag-grid-angular
style="width: 100%; height: 100%;"
[rowData]="rowData"
[columnDefs]="columnDefs"
(gridReady)="onGridReady($event)"
/>
</div> `,
})
export class AppComponent {
private gridApi!: GridApi<IAthlete>;
rowData: IAthlete[] | null = [];
columnDefs: ColDef[] = [{ field: "athlete" }, { field: "country" }];
onBtnClearRowData() {
this.gridApi.setGridOption("rowData", []);
}
onBtnSetRowData() {
this.gridApi.setGridOption("rowData", [
{ athlete: "Michael Phelps", country: "US" },
]);
}
onGridReady(params: GridReadyEvent<IAthlete>) {
this.gridApi = params.api;
}
}
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
#myGrid {
flex: 1 1 0px;
}
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { enableProdMode } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
if (new URLSearchParams(window.location.search).get('prod') !== 'false') {
enableProdMode();
}
const app = bootstrapApplication(AppComponent, {
providers: [provideHttpClient()],
});
Initial loading overlay Copy Link
If loading is not explicitly defined, the grid will automatically show the loading overlay until both rowData and columnDefs are provided with a non-null value for the first time. This behaviour can be suppressed by initialising the grid with an appropriate loading state.
Customisation Copy Link
Overlays can be customised by providing either a HTML string or custom component via grid properties.
Custom Loading Overlay Copy Link
The loading overlay can be customised via the grid properties overlayLoadingTemplate or loadingOverlayComponent and loadingOverlayComponentParams.
Provide a HTML string to override the default loading overlay. Supports non-empty plain text or HTML with a single root element. overlayComponent / overlayComponentSelector |
Provide a custom loading overlay component. overlayComponent / overlayComponentSelector |
Customise the parameters provided to the loading overlay component. overlayComponentParams |
Implement this interface to provide a custom overlay when data is being loaded.
interface ILoadingOverlayAngularComp {
// Mandatory - Params for rendering this component.
agInit(params: ILoadingOverlayParams): void;
// Gets called when the `overlayComponentParams` grid option is updated
refresh?(params: TParams): void;
}This example demonstrates how to provide a custom loading overlay component customised via parameters.
import { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import "./styles.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ModuleRegistry,
TextEditorModule,
TextFilterModule,
enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([
TextEditorModule,
TextFilterModule,
ClientSideRowModelModule,
]);
import { CustomLoadingOverlay } from "./custom-loading-overlay.component";
interface IAthlete {
athlete: string;
country: string;
}
@Component({
selector: "my-app",
standalone: true,
imports: [AgGridAngular, CustomLoadingOverlay],
template: `<div class="example-wrapper">
<div>
<label class="checkbox">
<input
type="checkbox"
checked=""
(change)="setLoading($event.currentTarget.checked)"
/>
loading
</label>
</div>
<ag-grid-angular
style="width: 100%; height: 100%;"
[columnDefs]="columnDefs"
[rowData]="rowData"
[defaultColDef]="defaultColDef"
[loading]="true"
[loadingOverlayComponent]="loadingOverlayComponent"
[loadingOverlayComponentParams]="loadingOverlayComponentParams"
(gridReady)="onGridReady($event)"
/>
</div> `,
})
export class AppComponent {
private gridApi!: GridApi<IAthlete>;
columnDefs: ColDef[] = [
{ field: "athlete", width: 150 },
{ field: "country", width: 120 },
];
rowData: IAthlete[] | null = [
{ athlete: "Michael Phelps", country: "United States" },
{ athlete: "Natalie Coughlin", country: "United States" },
{ athlete: "Aleksey Nemov", country: "Russia" },
{ athlete: "Alicia Coutts", country: "Australia" },
];
defaultColDef: ColDef = {
editable: true,
flex: 1,
minWidth: 100,
filter: true,
};
loadingOverlayComponent: any = CustomLoadingOverlay;
loadingOverlayComponentParams: any = {
loadingMessage: "One moment please...",
};
setLoading(value: boolean) {
this.gridApi.setGridOption("loading", value);
}
onGridReady(params: GridReadyEvent<IAthlete>) {
this.gridApi = params.api;
}
}
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
#myGrid {
flex: 1 1 0px;
}
label.checkbox {
display: inline-block;
user-select: none;
margin: 20px;
}
.fa-hourglass-half {
color: navy;
font-size: 18px;
}
.overlay-loading-center {
background: var(--ag-background-color);
border: solid var(--ag-border-width) var(--ag-border-color);
border-radius: var(--ag-border-radius);
box-shadow: var(--ag-popup-shadow);
padding: var(--ag-spacing);
}
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import type { ILoadingOverlayAngularComp } from 'ag-grid-angular';
import type { ILoadingOverlayParams } from 'ag-grid-community';
type CustomLoadingOverlayParams = ILoadingOverlayParams & { loadingMessage: string };
@Component({
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="overlay-loading-center" role="presentation">
<div
role="presentation"
style="width: 100px; height: 100px; background: url(https://www.ag-grid.com/images/ag-grid-loading-spinner.svg) center / contain no-repeat; margin: 0 auto;"
></div>
<div aria-live="polite" aria-atomic="true">{{ loadingMessage() }}</div>
</div>
`,
})
export class CustomLoadingOverlay implements ILoadingOverlayAngularComp {
loadingMessage = signal('');
agInit(params: CustomLoadingOverlayParams): void {
this.refresh(params);
}
refresh(params: CustomLoadingOverlayParams): void {
this.loadingMessage.set(params.loadingMessage);
}
}
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { enableProdMode } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
if (new URLSearchParams(window.location.search).get('prod') !== 'false') {
enableProdMode();
}
const app = bootstrapApplication(AppComponent, {
providers: [provideHttpClient()],
});
Custom No Rows Overlay Copy Link
The no-rows overlay can be customised via the grid properties overlayNoRowsTemplate or noRowsOverlayComponent and noRowsOverlayComponentParams.
Provide a HTML string to override the default no-rows overlay. Supports non-empty plain text or HTML with a single root element. overlayComponent / overlayComponentSelector |
Provide a custom no-rows overlay component. overlayComponent / overlayComponentSelector |
Customise the parameters provided to the no-rows overlay component. overlayComponentParams |
Implement this interface to provide a custom overlay when no-rows loaded.
interface INoRowsOverlayAngularComp {
// Mandatory - Params for rendering this component.
agInit(params: INoRowsOverlayParams): void;
// Gets called when the `overlayComponentParams` grid option is updated
refresh?(params: TParams): void;
}This example demonstrates how to provide a custom no-rows overlay component customised via parameters.
import { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
import "./styles.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
GridReadyEvent,
ModuleRegistry,
TextEditorModule,
TextFilterModule,
enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([
TextEditorModule,
TextFilterModule,
ClientSideRowModelModule,
]);
import { CustomNoRowsOverlay } from "./custom-no-rows-overlay.component";
interface IAthlete {
athlete: string;
country: string;
}
@Component({
selector: "my-app",
standalone: true,
imports: [AgGridAngular, CustomNoRowsOverlay],
template: `<div class="example-wrapper">
<div>
<button (click)="onBtnClearRowData()">Clear rowData</button>
<button (click)="onBtnSetRowData()">Set rowData</button>
</div>
<ag-grid-angular
style="width: 100%; height: 100%;"
[columnDefs]="columnDefs"
[defaultColDef]="defaultColDef"
[rowData]="rowData"
[noRowsOverlayComponent]="noRowsOverlayComponent"
[noRowsOverlayComponentParams]="noRowsOverlayComponentParams"
(gridReady)="onGridReady($event)"
/>
</div> `,
})
export class AppComponent {
private gridApi!: GridApi<IAthlete>;
columnDefs: ColDef[] = [
{ field: "athlete", width: 150 },
{ field: "country", width: 120 },
];
defaultColDef: ColDef = {
editable: true,
flex: 1,
minWidth: 100,
filter: true,
};
rowData: IAthlete[] | null = [];
noRowsOverlayComponent: any = CustomNoRowsOverlay;
noRowsOverlayComponentParams: any = {
noRowsMessageFunc: () =>
"No rows found at: " + new Date().toLocaleTimeString(),
};
onBtnClearRowData() {
this.gridApi.setGridOption("rowData", []);
}
onBtnSetRowData() {
this.gridApi.setGridOption("rowData", [
{ athlete: "Michael Phelps", country: "US" },
]);
}
onGridReady(params: GridReadyEvent<IAthlete>) {
this.gridApi = params.api;
}
}
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
#myGrid {
flex: 1 1 0px;
}
.fa-frown {
color: navy;
font-size: 18px;
}
.overlay-loading-center {
background: var(--ag-background-color);
border: solid var(--ag-border-width) var(--ag-border-color);
border-radius: var(--ag-border-radius);
box-shadow: var(--ag-popup-shadow);
padding: var(--ag-spacing);
}
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import type { INoRowsOverlayAngularComp } from 'ag-grid-angular';
import type { INoRowsOverlayParams } from 'ag-grid-community';
type CustomNoRowsOverlayParams = INoRowsOverlayParams & { noRowsMessageFunc: () => string };
@Component({
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
template: ` <div class="overlay-loading-center" style="background-color: #b4bebe;" role="presentation">
<i class="far fa-frown" aria-live="polite" aria-atomic="true"> {{ noRowsMessage() }} </i>
</div>`,
})
export class CustomNoRowsOverlay implements INoRowsOverlayAngularComp {
noRowsMessage = signal('');
agInit(params: CustomNoRowsOverlayParams): void {
this.refresh(params);
}
refresh(params: CustomNoRowsOverlayParams): void {
this.noRowsMessage.set(params.noRowsMessageFunc());
}
}
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { enableProdMode } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
if (new URLSearchParams(window.location.search).get('prod') !== 'false') {
enableProdMode();
}
const app = bootstrapApplication(AppComponent, {
providers: [provideHttpClient()],
});