You Are Here:

Community: Wiki

This page was last modified on 24 September 2009, at 15:47.

How to implement Live Scrolling in a Web Runtime widget

From Forum Nokia Wiki

Reviewer Approved   

This article explains how to implement the Live Scrolling Design Pattern in a Web Runtime widget.

The Live Scrolling Design Pattern is explained in detail in this Forum Nokia Wiki Article: Mobile Design Pattern: Live Scrolling

Contents

Description

The Live Scrolling pattern will be implemented following these steps:

  • an HTML element is defined to contain all the loaded data
  • the first set of data is loaded, and shown inside the specified HTML element


Image:Wrt_livescrolling_0.png

  • as soon as the user scrolls to the bottom of the page, the next set of data starts loading


Image:Wrt_livescrolling_1.png

  • when the new data is available, it is appended to the existing one


Image:Wrt_livescrolling_2.png

How to load remote data

The widget needs to load data from a remote server. This will be done by the following loadXML() file, structured as follows:

  • creates an XMLHttpRequest object
  • start the asynchronous HTTP request to retrieve the remote data
  • if request goes well (readyState = 4 and HTTP status = 200) then the response XML is passed to the func() handler passed as argument, otherwise the handler is called with false as argument
function loadXML(xmlFile, func)
{
try
{
var request = new XMLHttpRequest();
request.open("GET", xmlFile, true );
request.send(null);
 
request.onreadystatechange = function(){
if(this.readyState == 4)
{
if(this.status == 200)
{
func(request.responseXML);
}
else
{
func(false);
}
}
}
}
catch( e )
{
func(false);
}
}

Loading and displaying chunks of data

First, it's necessary to have an HTML node where the data items will be appended. The following items_container DIV will be used:

<body onload="init()">
 
<div id="items_container">
 
</div>
 
</body>

Now, to load and display sets of data, two functions are defined:

  • loadDataset(dataIndex): will load a specific set of data, by using the loadXML() function already defined
  • loadDatasetHandler(): function that will handle and display the loaded data
function loadDataset(dataIndex)
{
loadXML("http://www.jappit.com/m/test/livescrolling/page.php?page=" + dataIndex, loadDatasetHandler);
}
 
function loadDatasetHandler(xml)
{
if(xml)
{
var items = xml.getElementsByTagName('item');
 
for(var i = 0; i < items.length; i++)
{
var itemElement = document.createElement('div');
 
itemElement.className = 'item';
 
itemElement.innerHTML = items[i].firstChild.nodeValue;
 
itemsContainer.appendChild(itemElement);
}
}
else
{
alert("Error while loading page");
}
}

The itemsContainer variable is a global variable holding a reference to the HTML container node already defined, and is initialized in the widget's init() method, called by the onload event.

/* DOM element containing the data items */
var itemsContainer = null;
 
/* widget onload handler */
function init()
{
itemsContainer = document.getElementById('items_container');
}

Notifying the user with a loading indicator

It's always good practice, when some remote data is loading, to give visual information to the user with some sort of indicator. This will be done by the following showLoader() and hideLoader() methods:

var loader = null;
 
function showLoader()
{
if(loader == null)
{
loader = document.createElement('div');
 
loader.id = 'loading_indicator';
 
var loaderImage = document.createElement('img');
 
loaderImage.src = 'images/ajax-loader.gif';
 
loader.appendChild(loaderImage);
 
loader.appendChild(document.createTextNode('Loading...'));
 
itemsContainer.appendChild(loader);
}
}
function hideLoader()
{
if(loader != null)
{
itemsContainer.removeChild(loader);
 
loader = null;
}
}

So, the load-related methods can be modified, in order to correctly show and hide the loading indicator.

function loadDataset(dataIndex)
{
showLoader();
 
[...]
}
function loadDatasetHandler(xml)
{
hideLoader();
 
[...]
}

Handling the scroll events

Fundamental part, in live scrolling, is to check when the user reaches the end of page, in order to start the loading of the next set of data. The onscroll window event will be used for this purpose.

function init()
{
[...]
 
window.addEventListener("scroll", scrollHandler, false);
}
 
function scrollHandler()
{
if(itemsContainer.offsetHeight + itemsContainer.offsetTop - document.body.scrollTop < screen.availHeight)
{
dataIndex++;
 
loadDataset(dataIndex);
}
}

What the scrollHandler() function does is to check the vertical offsets of the DOM container, comparing with the widget's total height and current vertical scroll offset. If the bottom part of the DOM element is shown, then the next set of data is loaded.

The dataIndex global variable holds the index value of the last loaded data set, in order to correctly load the next data set when required.

/* index of the last loaded data set */
var dataIndex = 0;

Loading the first set of data

Now, all is ready to load the first set of data. In order to do this, it is enough to call the loadDataset() method, with the starting dataset index (zero). The loadDataset() call is added to the init() method, after the already added code:

function init()
{
[...]
 
loadPage(0);
}

Downloads

The widget presented in this article is available for download here: Media:LiveScrollingWidget.zip

Related Wiki Articles

No related wiki articles found

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZidentifierQSxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2findeE78E2ephpE2fThemesE3aHomeE5fScreenX qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfntypeZCommunityContentQ qdcZtypeQUqfntypeZE52esourceQ qdcZtypeQUqfntypeZWebpageQ qdcZtypeQUqfntypeZWikiContentQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qfnZtypeQUqfntypeZCommunityContentQ qfnZtypeQUqfntypeZE52esourceQ qfnZtypeQUqfntypeZWebpageQ qfnZtypeQUqfntypeZWikiContentQ qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfntypeZCommunityContentQ qrdfZtypeQUqfntypeZE52esourceQ qrdfZtypeQUqfntypeZWebpageQ qrdfZtypeQUqfntypeZWikiContentQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ
User Rating: qfnZuserE5FratingQNx4E2E0000X