An example of a site we built:
http://www.ezwayprods.com/products/category/default.aspx?cid=3
Things that help:
1. Latest jquery library and knowledge of the framework.
2. Server technology to request new items from. (I used a webservice)
Pagination is most often the solution for having users browse through large amounts of data. It is tedious and not a great user experience. While building a site for a client (See example link above) our original design did not include pagnation because the customer's inventory was not very large. After building the site we decided to include more items from his paper catalog. This ended up with around 1000 products in the 4 categories we originally setup. Since each product came with a picture and 5 columns of data the page was taking too long to load the images and text.
The solution we came up with was a lazy load for the products as the user scrolled down on the page. We bind an event handler to the document scroll event and check to see if the user is at the bottom of the page. If they are then we make a web service call for the next 25 results in the catalog. This keeps occurring until the user has loaded all of the items. The page now loads quickly and only with the items the user wants.
I will only include the JS file for this functionality since the loading of the products list can be done. The product list is fed from a .Net Web Service which populates a Product object using LINQ to SQL, which is stored in our SQL database. The object returned by the webservice is a List<Product>.
JAVASCRIPT:
var pageIndex = 1;
var isLoading = false;
$(document).ready(function() {
$(window).bind("scroll", function() {
if (isScrolledIntoView($("#footer")) && !isLoading)
DynamicLoad();
});
});
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop(),
docViewBottom = docViewTop + $(window).height(),
elemTop = $(elem).offset().top,
elemBottom = elemTop + $(elem).height();
//Is more than half of the element visible
return ((elemTop + ((elemBottom - elemTop) / 2)) >= docViewTop &&
((elemTop + ((elemBottom - elemTop) / 2)) <= docViewBottom));
}
function DynamicLoad() {
$.ajax({
url: "/services/EZWayService.asmx/GetNextProducts",
data: "{categoryID : " + querySt("cid") + ", pageIndex : " + pageIndex++ + "}",
beforeSend: function before(e) {
$("#loading-image").show();
isLoading = true;
},
success: function process(result) {
if (result.d.length > 0) {
$.each(result.d, function() {
var tableRow = "";
var productName = this.SKU_GROUP_DESCRIPTION == null ? this.SHORT_DESCRIPTION : this.SKU_GROUP_DESCRIPTION;
var category = this.PRODUCT_SUBCATEGORY_1;
var productLine = this.ProductLine == null ? "N/A" : this.ProductLine.product_line_name;
var company = this.MANUFACTURER;
tableRow = "<td class=\"img\"><img alt=\"No Image Supplied.\" src=\"/_assets/images/100x100/" +
this.IMAGENAME + "\" /></td><td>" + productName + "</td><td>" + company + "</td><td>" + productLine +
"</td><td>" + category + "</td><td>" + (this.SKU_DESCRIPTION_1 == null ? "N/A" : this.SKU_DESCRIPTION_1) + "</td><td>" +
this.SHORT_DESCRIPTION + "<br/><a href=\"/products/category/products.aspx?pid=" + this.ID
+ "\">Learn More</a></td>";
$(".searchResults").append("<tr onclick=\"window.location='/products/category/products.aspx?pid=" + this.ID + "';\">" + tableRow + "</tr>");
});
$("#loading-image").hide();
isLoading = false;
}
else {
//force a true here so there is no more loading when we are done
isLoading = true;
$("#loading-image").hide();
}
}
});
}
END CODE
As you can see above we start by binding to the document scroll event when the page is completely loaded. We have a global flag that lets us know if the page is currently loading new products or not and a page index variable. I am not going to get into details of the isScrolledIntoView method but it basically lets you know if an element (I used our footer DIV) is more than half in view on the page or not. We attach our handler to the scroll event so that everytime the user scrolls we check if they are at the bottom of the page or are already loading a new list of elements. (Sometimes they may continuously scroll even if they are at the bottom and we don't want to flood the screen with multiple requests.)
If the user is at the bottom of the page and we are not loading new products we call the DynamicLoad method. In DynamicLoad we make an AJAX request to the server for our new products. We show a loading graphic before this starts and then hide that graphic when the request is completed. Secondly, before the request starts we update the isLoading flag to true to block subsequent requests from happening. When the request comes back we make sure we have some new items, if not we keep the isLoading flag to true forever because we are at the end of the list. Each request we pass the page index we want and the category of products we want as well.
If we get a new list of products we iterate over each one appending them to our already existing table on the page. As you can see because we are using JSON as our data serialization technique we can easily reference our products as native javascript objects and access the properties for each one.
That's it! Let me know if you have any suggestions for me or if you have any problems implementing the code. Not shown here is all our custom error handling code and .Netwebservice but we recommend using both. Next week I will explain the dynamic search capabilities we built with keyword highlighting on the same site. http://www.ezwayprods.com/products/default.aspx
Thanks!