Ajax Paging Through Records On Scroll
I've always thought one of the cooler features on dzone was how they paged through the entries as you scroll down the list. This seems a ton more user friendly then the traditional 'next/previous' links.
I decided to see how easy it would be to recreate this functionality using ColdFusion 8 and as usual the answer was 'pretty easy'. There is a bit of JavaScript, but it's nothing too difficult to wrap your head around.
Check the demo here first. I intentionally sleep the thread for 1 second so you can see the loading icon - so don't think that it's just slow :).
On to the code bits. The first thing I have going here in this example is a super simple cfajaxproxy:
This lets me call the function to get the display data with JavaScript - which is important in this example rather then using binding or ColdFusion.navigate(). See, I'd rather that the user really not know what was going on - and using those other methods would swap out the contents of the container and give a loading icon while we made the Async call. Normally that's ok, I just wanted this to be seemless because later we'll append the page of data to our innerHTML rather then fully replacing it.
Next I create the JS variable representing the Ajax proxy and declare a few other variables that will be used later on:
var startRow = 1;
var loading = "";
The main JS functions that handle the data retrieval are here:
if(!loading){
loading = true;
testProxy.setCallbackHandler(populateData);
var loadIcon = document.getElementById('loadingIcon');
loadIcon.style.visibility = 'visible';
var data = testProxy.getRecords(startRow);
}
}
So when this function is called (we'll look at that later) it checks the global 'loading' variable to make sure it's not already getting some data. Next I set a callback handler for the proxy to the 'populateData' function. This ensures that I'll be able to hide the loading gif when the data retrieval is finished. Here's the callback function:
var container = document.getElementById('display');
var loadIcon = document.getElementById('loadingIcon');
container.innerHTML = container.innerHTML + d;
loadIcon.style.visibility = 'hidden';
loading = false;
}
The callback takes one argument, the result of the CFC invocation. This function takes that data and appends it so the innerHTML of the display container. Finally I reset the loading flag to false signifying that the request is complete. Here's the display container:
<div id="loadingIcon" style="visibility: hidden;"><img src='/CFIDE/scripts/ajax/resources/cf/images/loading.gif'/></div>
So just a fixed height div with an that fires another JS function onscroll. That function looks like this:
var container = document.getElementById('display');
if(!loading){
if(container.scrollTop+container.clientHeight == container.scrollHeight){
startRow = parseInt(startRow) + 10;
getData();
}
}
}
Again I check that there is not a current request running by checking the 'loading' variable. The next line was a bit tricky:
So this checks the scrollTop variable against the scrollHeight to determine if the current scroll is at the bottom of the div (ready to get more records in other words). However since the div's height will grow everytime we append more data I had to ensure that the variable div height was accounted for. Adding the clientHeight to the scrollTop handled that nicely.
If the conditional passes then we increment the global startRow variable and call the getData() function.
Oh also - A quick load event in the body makes sure we intially load the first 'page' of data.
Full code for this demo is attached.



Although I was looking for a jquery equivalent of this but this will do :)
thanks again
Thanks for the great post. but can you or someone else out there please show how to do this with PHP. i don't know any cold fusion and even though this is a great feature i am unable to use it :(
I need to create the same in asp.net. i m using the UI suite called "componentArt" which has its own grid and callback trigger.
I m specially interested to know what happens on the server and how does the data get appended to exitsting records. Normally, asp.net grids render the whole tables with <table>...</table> instead of rows.
I appriciated your help in advance. Thanks