Advanced User Interface Controls and Components

Infinite Scroll in AngularJS Grid

Created: 19 October 2015

There are several ways to load data into the AngularJS Grid directive: by loading the whole data at one time, using pagination or with infinite scrolling where data is loaded on demand. In following sections of this article, you will learn how to create infinite scroll in Grid directive.

Grid directive is part of IntegralUI Studio for Web
a suite of UI Components for development of web apps

In above demo, whenever scroll position is close to the end, additional data will be loaded into the Grid. Loading process is accompanied by a circular animation.

Related: Loading Animation in AngularJS Grid

Handling Scroll Events

Initially, when page is loaded for the first time, only small number of rows is loaded into the grid. When we scroll the current view close to the end of maximum scroll position, a loading animation will appear notifying that additional data is loading.

In order to check the current scroll position, we will handle the scrollPosChanged event:


.module("appModule", ["integralui"])

.controller("appCtrl", ["$scope", "IntegralUITreeGridService", "$timeout", function($scope, $gridService, $timeout){

var maxScrollPos = { x: 0, y: 0 }

var topRow = null;

var supressCallback = false;


$scope.onScrollPosChanged = function(e){

if (!supressCallback && e.scrollPos.y > 0 && e.scrollPos.y >= (maxScrollPos.y * 0.80)){

// Retrieve the top visible row in current view

topRow = $gridService.topRow($scope.gridName);


// Load additional data into the Grid





<!DOCTYPE html>



<link rel="stylesheet" href="css/integralui.css" />

<link rel="stylesheet" href="css/integralui.treegrid.css" />

<link rel="stylesheet" href="css/themes/theme-flat-blue.css" />

<script type="text/javascript" src="external/angular.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.lists.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.treegrid.min.js"></script>



<div ng-app="appModule" ng-controller="appCtrl">

<iui-treegrid name="{{gridName}}" columns="columns" rows="rows" control-style="controlStyle" show-footer="false" load-complete="onLoadComplete()" allow-focus="false" scrollpos-changed="onScrollPosChanged(e)"></iui-treegrid>




In this function, we also preserve the top row that is currently visible in the grid, so that we know to correctly set the scroll position after data is fully loaded. This is required, because whenever a new data is loaded, the maximum scroll position also changes.

Load Data on Demand

During loading process, we will add additional small data set to the grid. When new rows are added to the grid, it may trigger the update of grid layout with every single row. To wvoid this and increase overall performance, we will enclose this operation within the suspendLayout and resumeLayout methods, so that grid layout is updated only once.

As above code shows, editorType value is set to 'checkbox', and editorSettings value is set to an object that holds different checkbox properties. Depending on these settings, checkbox can appear and behave in different way. Here is a list of all acceptable fields:

var rowCount = 0;


// Create row cells

var createCells = function(i){

var cells = [];


for (var j = 1; j <= $scope.columns.length; j++)

cells.push({ text: "Item" + i + j });


return cells;



// Create a simple row

var createRow = function(i){

var row = {

id: i,

text: "Item" + i,

cells: createCells(i)





return row;



// Create a function that will load additional data

var load = function(){

// Starts a loading animation

$gridService.beginLoad($scope.gridName, null, { type: 'circular', opacity: 0.4 });

// Supress callbacks from scrollPosChanged event handler

supressCallback = true;


var loadTimer = $timeout(function(){

// Suspend the grid layout to increase performance



// Load additional data into the grid

var maxCount = rowCount+25;

for (var i = rowCount+1; i <= maxCount; i++)



// Resume the layout and update the grid




}, 1000);


Showing of loading animation is optional, but it is always best to have some kind of notification to the end user that data loading is processing. To start a loading animation, we are using the beginLoad method. In our case, we have chosen the circular animation.

In our demo, data is created and loaded from a local data source. Because of this, the loading process is instant. To simulate that there is some time required before data is fully loaded, we have set a minor delay of 1 sec. When data is loaded from a remote data source, this is not required.

Finally, when data is fully loaded and the grid layout is updated, the loadComplete event is fired. We will handle this event to stop loading animation and make sure that the current view of the grid remains the same. For this purpose, we are using the top row (stored previously).

$scope.onLoadComplete = function(){

// Stop the loading animation



// After short delay, make sure the current view of the grid remains the same as prior data load

var scrollTimer = $timeout(function(){

// Use the top row to scroll to it

if (topRow)

$gridService.scrollTo($scope.gridName, topRow);


// Update the maximum scroll position

maxScrollPos = $gridService.getMaxScrollPos($scope.gridName);

supressCallback = false;



}, 50);



Instead of populating the grid with whole data at once, using infinite scroll you can load data on demand into the AngularJS Grid directive. Whenever the scrollbar moves close to the end of the maximum scroll position, a new data is loaded into the grid. This process is accompanied by a loading animation, to notify the user that data loading is in the process.


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.