Tuesday, July 7, 2015

Implementing pagination on search results

I have been searching an easy way to implement pagination which requires no jQuery/JavaScript or java class implementation. And to my surprise, I found one element - Search.jsp which was present with product installation itself!! It's located at OpenMarket/Xcelerate/Search/Search.jsp which gave me basic idea on how pagination can be implemented with ease within WCS or FatWire.

Requirements:
1. Your search should be implemented via some search engine like lucene or endeca as they have ability to get results by setting starting index and max results. I have used by default lucene search which is installed out-of-the-box with JSK.
2. Knowledge on implementing forms within WCS. Check details here.
3. Knowledge on implementing lucene search. Check details here.

Procedure:
1. Basic idea is to generate page url with some params which lets your application know what results to show (in other words its just passing different params to your page asset templates). Generate URL same as which you generated for search button - Use <render:gettemplateurl> - Either you get vanity url if configured else you will get url by your assembler or generic long url

2. Append all the input params as query strings - Just append all the input params which were passed to search the current page. You might want to consider using packedargs if many parameters are required to be passed. Use tag: <render:unpackarg> and <render:packargs>

3. Update lucene search logic to search assets by setting start and end index - Simply add the following lines:

int startIndex = (null == pageNum || pageNum.length() == 0 ) ? 0 : (Integer.parseInt( pageNum )-1) * 10;
int endIndex = (null == pageNum || pageNum.length() == 0 ) ? 10 : (Integer.parseInt( pageNum ) * 10);
finalQuery.setStartIndex( startIndex );
finalQuery.setMaxResults( 10 );

where, pageNum = page number like 1,2... if null then just pass 0 as starting index and 10 as endIndex. I have considered that I would be showing 10 results per page. By adding this condition, lucene fetches only those results which are asked for.

4. Atlast, a simple logic to generate pagination

if(numOfArticles>10){%>   
    <ul id="pagination" style="padding-right: 50%;padding-left: 50%;display:inline;">   
    <% int pageCount = 0;   
     for(int p=0; p<numOfArticles; ) {   
        pageCount++;   
        String url = ics.GetVar("actURL")+"?keyword="+keyvalue+"&n="+pageCount;    
       if(Utilities.goodString(pageNum) && Integer.valueOf(pageNum) == pageCount ||       !Utilities.goodString(pageNum) && pageCount==1){   
        %><li style="margin: 0 10px;display:inline;"><a style="font-size: large;"><%= pageCount       %></a></li><%   
        } else {   
           %><li style="margin: 0 10px;display:inline;"><a style="font-size: larger;text-      decoration:underline;" href="<%= url %>"><%= pageCount %></a></li><%   
        }   
        p = p + 10;%>   
     <%} %>   
     </ul>   
<%} 

where, numOfArticles = total number of assets found on search
actURL = search results page url
pageNum = pageNumber like 1,2... which will be passed to URL for all the pagination links
rest of code is simply beautification.

If you have followed instructions mentioned in the posts for Satellite form and lucene, then building pagination should not be tough. 
I have developed and shared one sample JSP element which works with latest 11g JSK + Vanity URL configured + patch2 applied. Make changes in template according to your installation and configuration.

Add the param - "n" to cache-criteria to your previous SearchLayout.jsp and the replace code with the new pagination based search results - SearchLayoutPagination.jsp. Your page should look like following:




Note: There are differences in rendering forms for latest 11g and old versions, do check out how to work with them before trying this example.  

Disclaimer: Any sample code on this blog is not officially recommended, use at your own risk.

1 comment:

  1. Hello Dev ...
    Can you share a pagination example code using WCS tags and not controller and lucene search.
    because I just want pagination for data coming through list:loop.
    I want to use ajax for this , if you could help it will be a favor.

    Reply at

    govind.tripathi2106@gmail.com

    thanks

    ReplyDelete

A simple code compare functionality

One of the most important aspect of any development cycle is deployment and while deployment, it is very important to note the changes don...