Sunday, June 24, 2012

Continuous Scrolling UI pattern in SharePoint 2010 using REST interface with JSON and JQuery

In this post we will see how to implement the Continuous Scrolling UI pattern in SharePoint 2010 using REST with JSON and JQuery.
You can find more details about the Continuous Scrolling UI pattern here.

What is REST?

REST (Representational State Transfer) interface in SharePoint 2010 provides access to lists as a relational data service.
The core concept of any RESTful interface is the resource, and in SharePoint 2010, lists and items are represented as HTTP resources that can be addressed by remote URLs.
See more information on the SharePoint REST interface here.
In this example we will implement continuous scrolling UI pattern on Announcements list.
So let’s get started.

  1. Upload the jQuery,jQuery Timeago plugin, loading.gif image and the JavaScript Code to  Site Assets document library.

    2.  Add a content editor web part to the page and add a link to the script (ListData.js).


   3.  Here is the JavaScript code for the ListData.js

 <!--Include JQuery download it from here http://docs.jquery.com/Downloading_jQuery-->  
 <script src="../SiteAssets/jquery.min.js"></script>  
 <!--Include JQuery time ago plugin download it from here http://timeago.yarp.com/-->  
 <script src="../SiteAssets/jquery.timeago.js"></script>  
 <style type="text/css">  
   .announcement {  
     background-color: #FFFFEC;  
     padding: 1em;  
     margin: 1em;  
     width: 20em;  
     color:#0072BC;  
     font-size: 1.5em;  
     font-weight: normal;  
     border: 1px solid #EEC;  
     border-width: 1px 1px 1px 1px;  
   }  
   .timeago {  
     color:#BBB;  
     font-size: 12px;  
   }  
 </style>  
 <div id="demo" style="height:500px;overflow:auto;"></div>  
 <div id="divProgress" style="top: -100px;margin-left:120px;">  
   <img src="../SiteAssets/loading.gif" alt="" />  
 </div>  
 <script type="text/javascript">  
   // LIST URL.  
   var listURL = "http://wl2012866/sites/myteam/_vti_bin/ListData.svc/Announcements";  
         // Variable nodata is used as a flag to check the end of Announcements data  
   var nodata = false;  
         // Variable used to specify the number of Initial Announcements and also to fetch the new announcements  
   var pagesize = 5;  
         // Variable used to build the REST URL for subsequent requests..  
   var skipRecords = 0;  
         //Show the loading gif  
   $("#divProgress").show();  
   $(document).ready(function (i) {  
   // Use JQuery getJSON method to call the RESTful interface and get Announcements from the Announcements list,  
   // order results by Id.  
           $.getJSON(listURL + '?$orderby=Id%20desc&$top=' + pagesize, function (data) {  
                         //If Returned JSON object has data then process the result.  
       if (data.d.length > 0) {  
         $.each(data.d, function (i, result) {  
                                 // Append the Title and parsed Modified date to the demo DIV  
           $('#demo').append($('<div class="announcement"> <p>' + result.Title + '</p>' + '<p> <label class="timeago" title="' + parse_WCF_Date(result.Modified).format('yyyy-MM-dd') + '">' + parse_WCF_Date(result.Modified).format('MMM d, yyyy') + '</label> </p> </div>').show('drop'));  
         });  
                                 // Update skipRecords variable for next request.   
         skipRecords = pagesize;  
       } else {  
                         // Append informative message if no announcements returned by the listdata service.  
         $('#demo').append($('<div class="announcement" > There are no current announcements. </div>').show('drop'));  
       }  
                         // Apply jQuery timeago plugin to the Modified date label  
       $("label.timeago").timeago();  
     });  
         //Hide the loading gif  
     $("#divProgress").hide();  
     //Attach function to the scroll event of the demo div  
     $("#demo").scroll(function () {  
       //If user has scrolled to the bottom then load new Announcements..  
       if ($(this)[0].scrollHeight - $(this).scrollTop() == $(this).outerHeight()) {  
         //Show the loading gif during ajax request  
                           $("#divProgress").ajaxStart(function () {  
           $(this).show();  
         });  
                                 //Hide the loading gif  
         $("#divProgress").ajaxStop(function () {  
           $(this).hide();  
         });  
                                 // If there are more announcements call GetMoreAnnouncements function.  
         if (nodata == false) {  
           GetMoreAnnouncements();  
         }  
       }  
     });  
   })  
 // Function to fetch more announcements when the users scrolled the DIV to the bottom.  
   function GetMoreAnnouncements() {  
     var url = listURL + "?$orderby=Id%20desc&$top=5&$skip=" + skipRecords;  
     $.getJSON(url, function (data) {  
       if (data.d.length > 0) {  
         $.each(data.d, function (i, result) {  
           $('#demo').append($('<div class="announcement"> <p>' + result.Title + '</p>' + '<p> <label class="timeago" title="' + parse_WCF_Date(result.Modified).format('yyyy-MM-dd') + '">' + parse_WCF_Date(result.Modified).format('MMM d, yyyy') + '</label> </p> </div>').show('drop'));  
         });  
                                 // Update skipRecords variable for next request.  
         skipRecords = skipRecords + pagesize;  
       } else {  
         $('#demo').append($('<div class="announcement" >There are no more announcements. </div>').show('drop'));  
                                 // No more announcements so set the variable to prevent more requests.  
         nodata = true;  
       }  
       $("label.timeago").timeago();  
     });  
   }  
 // The date format from LISTDATA service is "Date(integer)" where integer is the number of seconds since Jan 1. 1970.  
  // Convert the SharePoint date into a JavaScript date.  
   function parse_WCF_Date(SPDate) {  
     var gmt_date = new Date(parseInt(SPDate.substring(6, 19)));  
     // Adjust GMT offset as per your need.  
     gmt_date.setHours(gmt_date.getHours())  
     return gmt_date;  
   }  
 </script>  

I have added 50 Announcements to the Announcements list using the PowerShell script described here.
Initially only 5 announcements are displayed in the CE web part as shown in below screenshot.


When the user scrolls to the bottom of the DIV, a request to fetch another 5 announcements is sent and a Loading image is shown. Refer below screenshot.





When there are no announcements to display, the further requests to get more announcements are not being sent and the user is informed with a message.




Happy Scripting. :)

5 comments:

  1. A nice descriptive post to help developer community grow.
    Thanks Hemant.

    ReplyDelete
  2. Hemath it is quite good and very use full :). can we the same for MOSS 2007..??

    ReplyDelete

Thanks for your Comment.

There was an error in this gadget