Paging Through Records OnScroll Using Unobtrusive Spry
Posted By : todd sharp Posted At : October 24, 2007 4:02 PM Posted In: Ajax
5
A while back I posted a demo on how to paginate through a recordset onscroll in a div. Since I've been on the path to enlightenment regarding unobtrusive JavaScript I decided to revisit this demo and rebuild it in an unobtrusive manner. The end result is quite a bit "lighter" since I upgraded to Spry 1.6 which ships with minified/packed versions of its lib.
Here is the extent of the display page:
<head>
<script type="text/javascript" src="SpryData.js"></script>
<script type="text/javascript" src="ajaxPaging.js"></script>
</head>
<body>
<div id="display" style="height: 100px; width: 300px; overflow-y: scroll;"></div>
<div id="loadingIcon" style="visibility: hidden;"><img src='/CFIDE/scripts/ajax/resources/cf/images/loading.gif'/></div>
</body>
</html>
Pretty darn beautiful to come in at a whole 10 lines of code. The magic all happens in the ajaxPagins.js file (a whopping 31 lines of code):
var loading = "";
scrollAction = function(){
var container = Spry.$('display');
if(!loading){
if(container.scrollTop+container.clientHeight == container.scrollHeight){
startRow = parseInt(startRow) + 10;
getData();
}
}
}
getData = function(){
if(!loading){
loading = true;
Spry.$('loadingIcon').style.visibility = "visible";
Spry.Utils.loadURL("GET", "test.cfc?method=getRecords&_cf_nodebug=true&returnFormat=plain&startRow="+startRow, true, populateData);
}
}
populateData = function(request){
var container = Spry.$('display');
Spry.$('loadingIcon').style.visibility = "hidden";
container.innerHTML = container.innerHTML + request.xhRequest.responseText;
loading = false;
}
//use a load listener to ensure the DOM is ready
Spry.Utils.addLoadListener(function(){
//attach a scroll listener to the div
Spry.Utils.addEventListener("display", "scroll", scrollAction, false);
//get the first batch of data
getData(1);
});
I'll not go through this line by line (if you have questions please post them in the comments). Basically the end result looks identical to the original. The real purpose was to show a real world example of using Spry unobtrusively.



To make this truly "unobtrusive", the DIV container would show the first page of results with a some kind control for paging through the results. You'd then hide the navigation control if JS is enabled.
That would give you a true unobtrusive & progressive enhancement. Your page would work regardless of whether or not your user has JS enabled, but it provides a better user experience if JS is enabled.
Man...now that you put it that way, full "unobtrusiveness" might be difficult to achieve with an Ajax/JS heavy site/page.
While it takes a little getting used to, it's still pretty achievable and doesn't add a lot of extra work. The biggest adjustment is just in your planning stages.
Like I said, all you really need to do to make your example truly unobtrusive is load the first page of results automatically and then provide some method for navigating pages.
You already have code written to retrieve a page of results (your doing it your AJAX call) so it's just a matter of adding that to your plain CF code.
I will say being completely unobtrusive isn't always necessary. If you're dealing with a controlled user group then it may not be necesary at all. However, if you're trying to reach the general population, then providing code that works in all situations is your best solution--that's where being truly unobtrusive can be really affective.
Also to clarify on my previous comment, there's two thoughts that are closely related "Unobtrusive JavaScript" and "Progressive Enhancment."
Some will argue that "unobtrusive JavaScript" just means you're separating the JS from the presentation--which your example does do.
My personal feeling is to be truly "unobtrusive" your page should work with or without Javascript. This is a form of "progressive enhancement". The difference is you can acheive progressive enhancement without having unobtrusive JS (since you could be intermingling the presentation and JS--such as adding event handlers to all your HTML markup.)
So in my mind being Unobtrusive encompases the whole progress enhancement idea.
Hope this isn't too confusing...
I guess my (skewed/biased/ignorant) thinking is that one of the biggest benefits of attaching event handlers via a framework instead of inline HTML is that the framework has taken the time to recognize how different browsers interpret the event and therefore makes it seemless to me (I don't have to change how IE/FF/Safari interprets a window load event, I just know it works). So I'm straying a bit from the unobtrusive conversation, but I guess moving more towards a selfish usability/programability benefit of attaching an event handler in this manner.
Personally I think the audience that I mainly deal with is more of a technical audience (as in the typical user of CFSnippets.org) so I'm not _too_ concerned with making accomodations for the non-JS user in some/most of my development. It certainly is something we should all be cognizant of - I do agree with that.
Even if it's something as simple as a <noscript>Turn on JavaScript you noob</noscript> (ok I may be over-simplifying...)