Friday Jun 20, 2014

Building Infinite Scrolling in Oracle Commerce

I have to start by saying that the approach I've taken to implement infinite scrolling may not be considered best practice.  I simply found an approach that worked for my purposes and I thought I would share…

The application I'm working with is an internal Oracle application built on Oracle Commerce (version 10.1.2 / 3.1.2 at the time this was written).  It's not a commerce application, but it does use the ATG 'platform' (modules DSS and below), as well as Endeca.  I have a repository that I index in Endeca, and I leverage Endeca Experience Manager to render some of the key pages of the application.  So, as it relates to infinite scrolling, I was starting with an experience manager driven page which contained a ResultsList cartridge, not unlike what you may see in the Commerce Reference Store (CRS).

There is a generic approach to designing infinite scrolling.  At a high level, you remove any kind of paging logic, you use javascript to notice when the user scrolls to the bottom of the initial results, and when that happens, you make some kind of call to get more data, and you append that data to your results.  The affect is that it seems like as you scroll, the results just keep going.

As I got into it, I found that there's a bit more to consider…  How to make the scrolling seem smooth instead of feeling jerky.  How to work through all the javascript event logic so that there are no unnecessary calls being made.  How to keep track of what was handled by the paging logic (the last record received, how many to get next, etc).  I was happy to find that most of these were actually fairly easy to figure out.

The original ResultsList cartridge (mostly borrowed from CRS) had two JSP's; ResultsList.jsp, and paging.jsp.  Just about all the work was done in ResultsList.jsp and paging.jsp was called to provide the page links at the top of the results (so you could click page 1, 2, 3, 4, etc).

For infinite scrolling, I had to rearrange things.  First, I pulled out the results formatting logic from the ResultsList.jsp and put that in a new JSP called ResultsFormat.jsp.  ResultsFormat.jsp simply takes an array of records and formats them - into a table in my case.  What was left in ResultsList was the call to ResultsFormat as well as the new javascript logic that deals with handling scrolling.

The next JSP I created is called recordRequest.jsp and it was called (by ResultsList.jsp) whenever the user scrolled down and it was time to get more data.  Instead of cramming a bunch of Endeca java code into that JSP, I created a droplet (EndecaInfiniteScrollDroplet) which contained all the Endeca Presentation API work.  The droplet would query Endeca and return the results in an array.  The recordRequest JSP really did nothing but invoke that droplet and pass the results array to the RecordFormat.jsp.  

This is a good time to point out that using the ATG - Endeca integration and Experience Manager, when the page loads for the first time, you get a data element called contentItem.  The contentItem contains a number of things, one of which is the initial result set.  So, in my application, I configured the ResultsList cartridge to return 100 records at a time, so that initial page would have the first 100 records (available to me in the contentItem).  

I didn't want to change how that worked, I wanted to leave that part alone and only figure out how to get the subsequent records I need when the user scrolled down…  So, this left me in the situation where I'm getting Endeca records from two different places; the initial set from the contentItem, and the rest from calls using my droplet (called each time the user scrolled to the bottom of the page).  This is why I decided to create a single place to format the records - for reusability and consistency.  All I really had to do was to make sure that my droplet returned an array of records that was the same as what was available in contentItem.

So, there are a few more moving parts, but it's really not too bad.  To summarize, here's a list of the pieces:
  • ResultsList.jsp - the main JSP, contains the javascript to handle scrolling
  • ResultsFormat.jsp - takes an array of records and formats them appropriately
  • recordRequest.jsp - was called upon scroll, and it invoked a droplet to get more records
  • EndecaInfiniteScrollDroplet - encapsulates all the Endeca API code to get more records

Rather than try to paste sample code snippets into this post, I thought it would be easier if I just provided all the relevant code in case you want to browse through it (keep in mind, this is not at all supported - just sample code).  If you do try to implement this and have questions, please let me know and I'll do what I can to help.


Welcome to the Oracle Commerce Product Strategy Community. We are dedicated to driving Best Business Practices across Oracle ATG products, Oracle ATG and Endeca Solutions and overall eCommerce Strategy. We welcome all collaborative discussions on blog posts. If you have a question for one of our experts, feel free to ask it here:
ATG Business Forum


« June 2014