Javascript Tutorial - Continuous Pagination

Skill

Javascript Tutorial - Continuous Pagination

Posted in:

Woah there, what's this! A Javascript tutorial!? Yes, I know its been a while since a Javascript tutorial graced the pages of Switch On The Code - but what can I say? I kind of got bored with writing them. And so, after a few month hiatus (and a couple fresh ideas for tutorials), they are back.

So what is on the plate for today? Well, we are going to take a look at how to implement continuous pagination in javascript. What is continuous pagination, you ask? That's a very good question, and it's actually a little bit difficult to describe. Say you have a list with a large number of entries - much more than you would want to load and display at once. The general tactic would be to paginate them - display 10-20 at once, and then have the user click 'next' to see the next 20, and so on and so forth.

But if for the most part, the user is just quickly scanning through these entries, this can get annoying. The user has to click and wait for the next batch of entries to load every time that they are done with the current set. Continuous pagination gets rid of this problem. As the user approaches the end of the entries currently displayed, the next entries are requested asynchronously and appended to the end of the list displayed to the user. This way, the user never has to do anything directly to get the next entries - they are just always there waiting in the list when they are needed!

A great example of this behavior is on the site DZone (which, besides showing off the behavior I'm talking about, is a great developer resource - if you haven't been there, you should check it out).

But of course, we aren't here just to talk about someone else's implementation - we are here to write out own! Below, there is a small example that we are going to create today. As you scroll down to the bottom, it will go off, load more elements, and append them to the bottom.

Initial Entry 1
Initial Entry 2
Initial Entry 3
Initial Entry 4
Initial Entry 5
Initial Entry 6
Initial Entry 7
Initial Entry 8
Initial Entry 10
Initial Entry 11
Initial Entry 12
Initial Entry 13
Initial Entry 14
Initial Entry 15
Initial Entry 16
Initial Entry 17
Initial Entry 18

Ok, now that you're done having fun scrolling, we can drop right into the code. First, the basic html structure:

<div style="position:relative;height:400px;width:500px;border:1px solid black;">
  <div style="overflow:auto;height:100%;width:100%;"
      onscroll="OnDivScroll();" id="scrollContainer">
    <!-- Entries go here -->
  </div>
  <div id="loadingDiv" tyle="position:absolute;bottom:2px;right:20px;
      padding:5px;display:none;background-color:Black;color:White;">

    Loading...
  </div>
</div>

Really not much there - and the element we care about at the moment is the inner div, the 'scrollContainer'. It is a normal div, except that we have attached the method OnDivScroll to the event onscroll. As you might expect, the onscroll event is fired whenever the div is scrolled. So let's take a look at this OnDivScroll method:

function OnDivScroll()
{  
  var el = document.getElementById('scrollContainer');
  if(el.scrollTop < el.scrollHeight - 800)
    return;
 
 
  var loading = document.getElementById('loadingDiv');
  if(loading.style.display == '')
    return; //already loading
   
  loading.style.display = '';
 
  LoadMoreElements();
}

So first, we go and grab the scrollContainer element. Then we check the current scroll position against the total scrollable height of the element. The only oddity is that the property scrollTop gives the current scroll position in terms of the top of the element - which means that scrollTop can never be bigger than scrollHeight minus the actual height of the element. In this case, we are checking to see when scrollTop is within 800 pixels of scrollHeight. If it is, we are close enough to the bottom that we want to load more elements. This value of 800 is completely dependent on what you think feels right for your application - in this case, I just got the number by multiplying the actual height of the element by 2.

Once we know that we should load more elements, we grab ahold of the little loading div element. Then we check if it is currently being displayed or not. If it is being displayed, then we must have already dispatched a request for more elements in a previous OnDivScroll call. Otherwise, we display the loading div, and we call the function LoadMoreElements.

function LoadMoreElements()
{
  //Do a server callback to load
  //more elements
 
  setTimeout(LoadCallback, 350);
}

It is in this function that you would do an AJAX callback to request more elements from the server. Since this is just a little demo app (and I didn't want to write any server side code), we just simulate this action by using a setTimeout call. Why is this mostly equivalent to doing an actual callback? Well, an actual callback will take time, and occur asynchronously, and that is what the setTimout call here is doing for us.

So, after a bit of time, the server returns with some elements (or, in the case, the setTimeout executes our function):

var NumberOfNewEntrySets = 1;

unction LoadCallback()
{
  var el = document.getElementById('scrollContainer');
  var loading = document.getElementById('loadingDiv');
 
  loading.style.display = 'none';
 
  for(var i=1; i<=6; i++)
    el.innerHTML += "<div class='entry'>New Entry " + i
        + " of Set " + NumberOfNewEntrySets + "</div>";
  NumberOfNewEntrySets++;
}

In this case, again, since there is no actual server results, we are just generating new entries and adding them. Potentially, this callback would have an argument (the server response), and you would parse the response and add all the contained elements. Oh, and don't forget to set the loading div to be invisible again.

And there you go! That is all you need to do continuous pagination. Here is all the code together in a single block for your viewing pleasure:

<html>
  <head>
    <title>Auto Fill Scroll Test</title>
    <style type="text/css">
      .entry
      {
        height:75px;
 
        border-bottom:solid 1px #cccccc;
        border-top:solid 1px #cccccc;
        border-collapse:collapse;
        padding:5px;
      }
    </style>
    <script type="text/javascript" src="javascript.js"></script>
  </head>
  <body>
    <div style="position:relative;height:400px;width:500px;border:1px solid black;">
      <div style="overflow:auto;height:100%;width:100%;"
          onscroll="OnDivScroll();" id="scrollContainer">
        <div class="entry">Initial Entry 1</div>
        <div class="entry">Initial Entry 2</div>
        <div class="entry">Initial Entry 3</div>
        <div class="entry">Initial Entry 4</div>
        <div class="entry">Initial Entry 5</div>
        <div class="entry">Initial Entry 6</div>
        <div class="entry">Initial Entry 7</div>
        <div class="entry">Initial Entry 8</div>
        <div class="entry">Initial Entry 10</div>
        <div class="entry">Initial Entry 11</div>
        <div class="entry">Initial Entry 12</div>
        <div class="entry">Initial Entry 13</div>
        <div class="entry">Initial Entry 14</div>
        <div class="entry">Initial Entry 15</div>
        <div class="entry">Initial Entry 16</div>
        <div class="entry">Initial Entry 17</div>
        <div class="entry">Initial Entry 18</div>
      </div>
      <div id="loadingDiv" tyle="position:absolute;bottom:2px;right:20px;
          padding:5px;display:none;background-color:Black;color:White;">

        Loading...
      </div>
    </div>
  </body>
</html>

var NumberOfNewEntrySets = 1;

function OnDivScroll()
{  
  var el = document.getElementById('scrollContainer');
  if(el.scrollTop < el.scrollHeight - 800)
    return;
 
 
  var loading = document.getElementById('loadingDiv');
  if(loading.style.display == '')
    return; //already loading
   
  loading.style.display = '';
 
  LoadMoreElements();
}

function LoadMoreElements()
{
  //Do a server callback to load
  //more elements
 
  setTimeout(LoadCallback, 350);
}

function LoadCallback()
{
  var el = document.getElementById('scrollContainer');
  var loading = document.getElementById('loadingDiv');
 
  loading.style.display = 'none';
 
  for(var i=1; i<=6; i++)
    el.innerHTML += "<div class='entry'>New Entry " + i
        + " of Set " + NumberOfNewEntrySets + "</div>";
  NumberOfNewEntrySets++;
}

If you would like, you can download a simple html file with this example here. As always, fee free to leave any questions or comments below.

Zonux.c
05/16/2008 - 04:30

Thanks, nice tutorial

reply

Janko
05/17/2008 - 05:56

Excellent tutorial. I planned to write somethig similar because I intend to implement this pattern in current project.

Thanks!

reply

Greg Tidwell
05/19/2008 - 20:38

i've been watching your blog for its morsels of flex knowledge. now, i've got another reason. keep up the javascript posts! thanks

reply

Property Bulgaria
05/23/2008 - 02:05

Very nice post, i found some tips about that here http://ooyes.net/blog/javascript-tutorials:75

reply

Majid
06/11/2008 - 08:40

I am new learning javascripts, I like this article tutorial, I have two questions please :

1)How to have the picture loading instead of the text "Loading..." ?

2)Can someone show me how to use a server (jsp, struts,..) side to poll data from a database and show it in this pagination?

Thanks

reply

Aaron
10/04/2008 - 06:48

I really love the example, ive been trying to find a way to paginate some results on my page with javascript for a while.

Ive been mulling it over for the last few days and cant find a way to make a call back to get more results from php/mysql - can anybody help??

reply

Seo Nedir
10/19/2008 - 13:36

it's very useful.thanks to him made it

reply

HtmlCentre
11/22/2008 - 23:33

it’s very useful.thanks to him made it

reply

Okan
01/08/2009 - 09:45

siten güzel olmuş tebrikler

reply

Oynardin
01/08/2009 - 10:09

güzel sevdim siteyi bok gibi

reply

Jay
04/01/2009 - 01:03

Hi, could this be used with pulling data from mysql?

reply

The Professionalist
05/17/2009 - 02:07

Thanx This is good

reply

Mark Bathen
10/17/2010 - 12:36

I need to learn how to paginate, so that the first entry is first, and last entry is last

reply

Mahesh Jain (Foxinfosoft)
03/16/2011 - 07:57

Thanks good and very useful tutorial for beginners...

reply

poohdedoo
03/17/2011 - 01:27

Hi,
I am new to javascript my question is how do i access the data i retrieve from the back end server and then display when the scroller goes down??
(i dont see the connection between retrieving data from the back end and displaying )
pls help

reply

Anonymous
05/31/2011 - 23:56

we have same problem but. this tutorial has a lot more to do with our concerns.. just review the code..

reply

Anonymous
05/31/2011 - 23:54

thanks.. it will guide me in my pagination with the site i creating by now.. just a little revising it.. it will fit in my need..

reply

Anonymous
06/07/2011 - 14:51

Thanks for this useful post..

reply

Bhaskar
06/26/2011 - 12:46

Nice Post. Very helpful. Thanks.

reply

Anonymous
10/30/2011 - 19:43

How can I use this code but add in different content to each div that appears when you scroll down?

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.