Tutorial hero
Lesson icon

How to Create an Infinite Scrolling List in Sencha Touch

Originally published October 07, 2014 Time 5 mins

Facebook, Twitter, Instagram and thousands more use infinite scrolling in their mobile applications. If you scroll to the bottom of your news feed in Facebook, or your Twitter feed you will soon be greeted with more and more content.

The problem with mobile is that we have a lot less power to work with than a desktop computer or laptop. The more elements that are in the Document Object Model (DOM) and the more requests we need to make to the server to load content, the slower the application will become.

This is the problem that infinite scrolling addresses (and it’s certainly not exclusive to mobile, it’s commonly used across a lot of websites as well). Rather than loading in all, or a lot of, our content we load in small chunks at a time. As the user approaches the bottom of the list, we load in more content. Ideally the content will load before the user gets there so the user won’t experience any delay. Often though there may be a small delay as the new content is fetched.

Take a look at the video below by Sencha’s Jacky Nguyen where he talks about some of the more technical aspects of this problem in depth. Fortunately for us, they have done a lot of the work and it’s reasonably straight forward to add infinite scrolling to our own Sencha Touch apps.

1. Add the List Paging Plugin

If you browse to the /touch/src/plugin directory in your Sencha Touch project you will find there are a few plugins there already by default. This includes ListPaging.js which we will need for our infinite scrolling set up, and PullRefresh.js which we will also add. Pull Refresh allows users to scroll up past the start of the list to refresh the data. This is another common pattern found in popular mobile applications today.

  • Add the following code to your lists configuration
config: {
    plugins: [
        {
            xclass: 'Ext.plugin.ListPaging',
            autoPaging: true,
            loadMoreText: 'Loading...',
            noMoreRecordsText: 'No more records'
        },
        {
            xclass: 'Ext.plugin.PullRefresh',
            pullText: 'Pull down to refresh'
        }
    ],
    //..snip
}

2. Define your Page Size

The page size determines how many records will be loaded in at a time and is defined on the store.

  • Add the following code to the store for your list
config: {
  //..snip
  pageSize: 15;
}

3. Define the Total Property

We need to send back a “total” value to our application from our API that will indicate the total number of records we have. This let’s the application know if it has reached the end of the list or not.

  • We will make changes to include this in our API shortly but for now add an additional line to the reader in your proxy to define the total property that will be returned:
reader: {
	type: 'json',
	rootProperty: 'items',
	totalProperty: 'total'
}

4. Implement ‘Start’ and ‘Limit’ in your API

Now that we’ve included the plugin in our project, we need to start making use of the extra parameters that are sent with “read” requests:

Query String Parameters

You will notice that a “page”, “start” and “limit” variable is being sent.

Rather than returning all of our records from the database, we now only want to send back the records for the current page. To do this we’ll use LIMIT and OFFSET in MySQL, defined by the start and limit variables, to return the subset we require.

  • Restructure your database query to utilise the start and limit variables
$start = $mysqli->real_escape_string($_GET['start']);
$limit = $mysqli->real_escape_string($_GET['limit']);

$query = "SELECT * FROM table LIMIT ".$limit." OFFSET ".$start;

5. Return a Total Property

As I mentioned previously, you will have to return a “total” along with the JSON response.

  • Run another query to grab the total number of records
$query = "SELECT * FROM table";
$dbresult = $mysqli->query($query);
$total = $dbresult->num_rows;
  • Return the total along with the rest of the data
$result = "{'success':true, 'items':" . json_encode($items) . ", 'total':".$total."}";

Conclusion

If you run your application now you should see the amount of records defined in your page size load initially, and more as you scroll to the bottom of the list.

This paging plugin only works with a remote proxy, it will not work with local storage. I’m yet to find a good solution for paging results from local storage so if you’ve come across one or developed one yourself please leave it in the comments below!

Learn to build modern Angular apps with my course