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. :)

Monday, May 7, 2012

Integrating jQuery Timeago plugin in SharePoint 2010


I've been doing lots of reading about all the nifty things that can be done using jQuery on a SharePoint site. jQuery is one of the most popular javascript libraries used by ASP.NET developers.  There are many interesting jQuery plugins. Timeago is one of my favourite plugin which makes it easy to support automatically updating fuzzy timestamps like in Facebook, Twitter etc.
While working on a POC I need to display dates in content query webpart like in facebook / twitter (a min ago, 2 days ago etc).
Mark Rackley has written excellent posts (A Dummies Guide to SharePoint and jQuery–Getting Started) on jQuery and SharePoint.
To integrate Timeago jquery plugin to your Sharepoint 2010 site follow these steps.


1. Upload the jQuery and Timeago plugin to Site Assets document library.
2. Write your script, references the appropriate libraries, save it as a file and upload it to Site Assets document library
 <script src="../SiteAssets/jquery.min.js"></script>  
 <script src="../SiteAssets/jquery.timeago.js"></script>  
 <script type="text/javascript">  
      jQuery(document).ready(function($) {  
           jQuery(".timeago").timeago();  
      });  
 </script>  

3. Put a content editor web part on the page and link to the script (CustomJs.js) in Site Assets document library. This content editor web part is used to link the scrips uploaded in step 1 to the current page.


          4. Put a Content Query Web part on the page and configure it as shown in below screen shots.


    5. Open the ItemStyle.xsl from Style Library. Change the ItemStyle to include the [title] attribute and also change the div class from “description” to “timeago” as shown below. For POC i have used the Description column to display the Modified date. You can create your custom column and use it in CQWP.
 <div class="timeago">  
          <xsl:attribute name="title">  
            <xsl:value-of select="@Description" />  
           </xsl:attribute>  
           <xsl:value-of select="@Description" />  
         </div>  

              

6. Save the XSL and refresh the page.
You will see the date strings are replaced with the time delta.



Happy scripting :)

Note: SPUtility.TimeDeltaAsString Method can be also used to show the time difference between two time value as String.

Thursday, March 22, 2012

jQuery 1.7.2 released



jQuery team has released a new version of jQuery library which is 1.7.2.
Change log of the 1.7.2 release is available on jQuery blog.
http://blog.jquery.com/2012/03/21/jquery-1-7-2-released/

You can get the code from the jQuery CDN now.

http://code.jquery.com/jquery-1.7.2.min.js (minified, production)
http://code.jquery.com/jquery-1.7.2.js (unminified, debug)

Note: If you’re using jQuery Mobile, please use jQuery 1.7.2 only with jQuery Mobile 1.1.
For previous versions of jQuery Mobile, stay with jQuery core 1.7.1 or earlier.

Wednesday, March 7, 2012

The Basics of jQuery


jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. if you haven’t tried it yet, you’re missing out on a real time-saver.
AndrĂ©e Hansson has written a thorough walk through of The Basics of jQuery that will get you going. Definitely one of the better beginner guides I’ve come across so far.
I recommend jQuery Fundamentals by Rebecca Murphey. It’s a comprehensive online book which guides you from JavaScript basics through to writing jQuery plugins. Even expert JavaScript developers will find something they didn’t know.
The book is excellent. It’s well-written, concise, and contains plenty of examples. What’s more, it’s free.
There was an error in this gadget