With the advent of mobile devices, an infinite scroll functionality became a very popular feature. This feature is similar in nature to pull-to-refresh though, in this case, as the user scrolls, an application is loading additional content to the bottom of a list. Data is fetched in batches as needed, pulling a fixed number of records at a time.
 
The OnsenUI can do this but for some reason this functionality is not even described in the official documentation. To achieve this OnsenUI provides ons-scroller directive which makes the inner content scrollable.
 
This article will cover everything you need to know about this feature, you will also find a working example.
 
This statement may sound silly, but this is a highly important feature. Without it, as number of list elements rises, our application would gradually become slower and slower. Hybrid mobile applications just can’t handle large number of list items; I managed to witness that while I was working with jQuery Mobile. Nothing changed since that time; even modern mobile frameworks can’t compete with native application scrolling.
 
 

Note: If this tutorial was helpful, need further clarification, something is not working or do you have a request for another Ionic post? Furthermore, if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here, again leave me a comment below. I'm here to help you, I expect the same from you. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com, or follow and mention me on twitter (@gajotres). Thanks and have a nice day!

PS. If you want my help, if possible (even if it takes you some time to do that), create a working example I can play with. Use Plunker for AngularJS based questions or jsFiddle for jQuery/jQuery Mobile based questions.


 

Table of Contents

Intro

 
<ons-scroller 
    infinit-scroll-enable="canWeLoadMoreContent()" 
    can-load="true" 
    on-scrolled="populateList()" 
    threshold="20" 
    style="height:100%">
</ons-scroller>
 
The ons-scroller directive allows you to scroll inner content. Currently, it’s only usable on mobile devices.
 
The expression you pass in for on-scrolled is called when the user scrolls greater than distance set in a threshold attribute.
 
The expression you pass for infinit-scroll-enable requires true/false to determine if infinite scrolling is enabled or disabled.
 

Example

 
This example will use a Faker.js framework. For those of you who never heard of this framework, it’s used for data faking. I reviewed it (plus few more frameworks) in one of my earlier articles; find it here.
 
A short walk through, when this example first initializes it will generate ten list elements; every call to on-infinite function will produce ten additional list items (each time you scroll to the bottom).
 
Demo
 

Embedded working example

 
Ionic Framework Infinite Scroll Example
 
Warning: Native looking scrolling is not supported in desktop browsers so you will need to use your mouse scroll wheel.
 

HTML:

<html>

<head>
  <script src="https://code.angularjs.org/1.3.0/angular.js"></script>
  <script src="http://onsenui.io/OnsenUI/build/js/onsenui.js"></script>
  <script src="http://marak.com/faker.js/js/faker.js"></script>
  <script src="script.js"></script>
  <link rel="stylesheet" href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.2.2/build/css/onsenui.css" />
  <link rel="stylesheet" href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.2.2/build/css/onsen-css-components.css" />
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-controller="ListCtrl">

  <ons-navigator animation="slide" var="app.navi">
    <ons-page>
      <ons-toolbar class="toolbar-black">
        <div class="center">OnsenUI Infinite Scroll Example</div>
      </ons-toolbar>

      <ons-scroller infinit-scroll-enable="canWeLoadMoreContent()" can-load="true" on-scrolled="populateList()" threshold="20" style="height:100%">

          <ons-list-item class="list-item-container" ng-repeat="list in _list">
            <ons-row style="padding: 10px 10px 5px 0;">
              <ons-col width="145px">
                <img ng-src="{{list.image}}" class="thumbnail">
              </ons-col>
              <ons-col>
                <div style="height: 30px;">
                  <h4>{{list.name}}</h4>
                </div>
                <div style="height: 30px; font-size: 13px;">
                  <i class="fa fa-map-marker"></i> {{list.address}}
                </div>
                <div style="height: 30px; font-size: 13px;">
                  <i class="fa fa-phone"></i> {{list.phone}}
                </div>
              </ons-col>
              <ons-col width="40px"></ons-col>
            </ons-row>
          </ons-list-item>

          <ons-list-item ng-show="isLoading">
            <div class="loader-container">
              <ons-icon icon="spinner" size="40px" spin="true"></ons-icon>
            </div>
          </ons-list-item>

      </ons-scroller>

    </ons-page>
  </ons-navigator>


</body>

</html>

JavaScript:

var module = ons.bootstrap('my-app', ['onsen']);

module.controller('ListCtrl', function($scope, $timeout) {
  
  $scope._list = [];  
  $scope.isLoading = false;

  $scope.populateList = function() {
    
    if($scope.isLoading) return;
  
     $timeout(function(){
        for (var i = 0; i <= 9; i++) {
          
          var firstName = faker.name.firstName();
          var lastName = faker.name.lastName();      
          
          $scope._list.push({ name: firstName + " " + lastName, 
                              address: faker.address.streetAddress(),
                              phone: faker.phone.phoneNumber(),
                              image: faker.internet.avatar()
          });
        }    
        console.log($scope._list.length);
         $scope.isLoading = false;
     },1000);
  
     $timeout(function() {
       $scope.isLoading = true;  
     });    
  }

  $scope.canWeLoadMoreContent = function() {
    return ($scope._list.length > 49) ? false : true;
  }  

  $scope.populateList();
  
});

Walkthrough

 
When ListCtrl controller first initializes it will create an empty _list object; we’ll use it to store application list data:
 
$scope._list = [];  
 
JavaScript will immediately populate it using a function call:
 
$scope.populateList(); 
 
Application is calling this function:
 
$scope.populateList = function() {
    
    if($scope.isLoading) return;
  
     $timeout(function(){
        for (var i = 0; i <= 9; i++) {
          
          var firstName = faker.name.firstName();
          var lastName = faker.name.lastName();      
          
          $scope._list.push({ name: firstName + " " + lastName, 
                              address: faker.address.streetAddress(),
                              phone: faker.phone.phoneNumber(),
                              image: faker.internet.avatar()
          });
        }    
        console.log($scope._list.length);
         $scope.isLoading = false;
     },1000);
  
     $timeout(function() {
       $scope.isLoading = true;  
     });    
}
 
Function generates ten list elements per call using Faker.js to autogenerate fake data. $timeout is needed here because without it list directive will not be updated. Look at it as a broadcast that new items are available.
 
This is applications ons-scroller directive:
 
<ons-scroller 
    infinit-scroll-enable="canWeLoadMoreContent()" 
    can-load="true" 
    on-scrolled="populateList()" 
    threshold="20" 
    style="height:100%">
</ons-scroller>
 
Directive is configured to trigger a function populateList() when a distance reach a threshold of 20. This example will show max. 50 elements; it will disable infinite scrolling if number of list elements surpass that number. Disabling/enabling can be achieved using an expression we’re sending through infinit-scroll-enable attribute:
 
$scope.canWeLoadMoreContent = function() {
    return ($scope._list.length > 49) ? false : true;
}  
 

Author’s Notes

 
I need to apologize in advance, but I need to get this off my chest. I’m becoming more and more disappointed with this framework. What used to look as a great documentation now looks less and less promising. For example, I don’t even want to ask what’s the point of ons-scroller directive, other frameworks can do this out od the box. Ons-scroller won’t even work in desktop Chrome environment, ffs, I would like to be able to test this feature without using my smartphone.
 

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.

Blogs worth reading

If you're here looking for information related to the Ionic Framework, you will also like these blogs:






  • Hi, Thanks for article,
    It seems that Infinit-scroll is not working on Onsen 2, am I right?

    • I can tell you right not that this feature is currently in development. It should come out soon.