Tuesday, May 15, 2012

Rotating images using JQuery and Data View Web Part in SharePoint Foundation 2010

This post is about rotating images with fixed captions in SharePoint Foundation 2010. There are a few posts around which talks about gettting it done but doesn't work properly so thought to write a step-by-step blog on it.

Note: You can also rotate images using Content query web part (link), but for that you should have SharePoint Server 2010, as content query web part doesn't come with SharePoint foundation 2010!

Requirements:
- Download jquery-1.7.2.min.js
- Download captify.tiny.js (for fixed caption)
- Create a picture library or use the default one and put some pictures into it.
Keep both JQuery files in the <14 hive>\Templates\Layouts\JQuery (create this folder if doesn't exist)

1. Create a new site page.

2. Now edit page in normal mode in SharePoint designer. Put your cursor before SPAN tag with id 'layoutsData' and insert an Empty Data View.

Switch to 'Split' mode, click 'Click here to select a data source' and select the picture library.
Select 'Title' for image caption and 'URL Path' for link to image. Now insert selected fields as multiple item view. It will insert complete xslt required for rendering the picture library on page.

Switch to 'Code' view. Automatically generated code contains few XSLT tag which are of no use in our case so I have removed these. Select automatically generated <XSL> tag and overwrite it with the <XSL> tag given below.


<!----- XSL Tag: START ------>


<Xsl>

 <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">    
 <xsl:output method="html" indent="no"/>    
 <xsl:decimal-format NaN=""/>    
 <xsl:param name="dvt_apos">'</xsl:param>    
 <xsl:variable name="dvt_1_automode">0</xsl:variable>   
  <xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">        
 <xsl:call-template name="dvt_1"/>    
 </xsl:template>    
 <xsl:template name="dvt_1">        
 <xsl:variable name="dvt_StyleName">Table</xsl:variable>        
 <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>        
 <xsl:variable name="dvt_RowCount" select="count($Rows)" />        
 <xsl:variable name="IsEmpty" select="$dvt_RowCount = 0" />

<!-- Jquery file and plugin reference -->
 <script type="text/javascript" src="_layouts/JQuery/jquery-1.7.2.min.js"></script>
 <script type="text/javascript" src="_layouts/JQuery/captify.tiny.js"></script>

 <script type="text/javascript">

  $(window).load(function() {
   

   // This code provides the fade-in and hide effect on regular interval
   var InfiniteRotator =    
       {
           init: function()
           {            

                 //initial fade-in time (in milliseconds)
               var initialFadeIn = 1000;
                 //interval between items (in milliseconds)
               var itemInterval = 5000;
                 //cross-fade time (in milliseconds)
               var fadeTime = 2500;
                 //count number of items
               var numberOfItems = $('#headers li').length;
                 //set current item
               var currentItem = 0;
               if(numberOfItems &gt; 0) {
                //show first item              
                $('#headers li').hide();
                              
                $('#headers li').eq(currentItem).fadeIn(fadeTime);
               
                //$('#headers li').eq(currentItem).fadeOut(fadeTime);
               
                if(numberOfItems &gt; 1)
                {
                 //loop through the items
                 var infiniteLoop = setInterval(function(){
                     $('#headers li').hide();                  
                       if(currentItem == numberOfItems -1){
                         currentItem = 0;
                     }else{
                         currentItem++;
                     }
                     $('#headers li').eq(currentItem).fadeIn(fadeTime);                  
                    
                 }, itemInterval);
                }
               }
               else {                 
                $('#headers').append('<li><span>No images.</span></li>');
               }
           }
       };
      InfiniteRotator.init();
    
     });
   
 </script>

 <script type="text/javascript">  

  $(function(){$('img.captify').captify({
    speedOver: 'fast', 
    // speed of the mouseout effect 
    speedOut: 'normal', 
    // how long to delay the hiding of the caption after mouseout (ms) 
    hideDelay: 500,  
    // 'fade', 'slide', 'always-on' 
    animation: 'always-on',   
    // text/html to be placed at the beginning of every caption 
    prefix: '',   
    // opacity of the caption on mouse over 
    opacity: '0.7',      
    // the name of the CSS class to apply to the caption box 
    className: 'caption-bottom',  
    // position of the caption (top or bottom) 
    position: 'bottom', 
    // caption span % of the image 
    spanWidth: '100%'
  }); });       
     
     
 </script>

 <style type="text/css">
 /*********** CAPTIFY CAPTION ***************/
 .caption-top, .caption-bottom {
       background: #000000;     
       color: #ffffff;     
       cursor:default;     
       padding:2px;     
       font-size:11px;     
       text-align:center;
       }  
 .caption-top {
       border-width:0px;
 }  
 .caption-bottom {
       border-width:0px;
 }  
 .caption a, .caption a {
       background:#000;     
       border:none;     
       text-decoration:none;    
        padding:2px;
 }  
 .caption a:hover, .caption a:hover {
       background:#202020;
 }

 #headers, #headers li{
      margin:0;    
      padding:0;    
      list-style:none;    
 }
 #headers li img{    
  display:none; /* hide the items at first only */       
 }
 #rotating-item-wrapper {
     position: relative;
 }

 </style>

 <ul id="headers">   
  <xsl:call-template name="dvt_1.body">    
    <xsl:with-param name="Rows" select="$Rows"/>    
  </xsl:call-template>
 </ul>
 
 </xsl:template>    

 <xsl:template name="dvt_1.body">        
   <xsl:param name="Rows"/>        
     <xsl:for-each select="$Rows">            
       <xsl:call-template name="dvt_1.rowview" />        
     </xsl:for-each>   
 </xsl:template>
  
 <xsl:template name="dvt_1.rowview">
   <div id="rotating-item-wrapper{generate-id()}">
     <li>
       <img src="
{@FileRef}" class="captify" alt="{@Title}"/>
     </li>
   </div>

</xsl:template>

</xsl:stylesheet>

</Xsl>


<!----- XSL Tag : END ------>

Note : For your information, I have highlighted the text which is inserted after cleaning the xslt code.


Done! Just save the page and navigate to it. You should be able to see images fadding in with a regular interval having fixed caption.

Additional Notes : You can also filter the images/items by providing required filter criteria in this tag:

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[<filter_criteria>]"/>

Please let me know if you have any query.

References:
  • link to rotate images infinitely.
  • link to captify images.
Result:


9 comments:

  1. Thanks very much for the step by step. Works great. One question. How do I alter the height of the photos?

    ReplyDelete
  2. Nice to hear, it was helpful!!

    You can specify height and width in the image tag given at the end.

    img src="{@FileRef}" class="captify" alt="{@Title}" height="40" width="40"

    ReplyDelete
  3. Hi Youdhbir. Thanks for the blog above. For a newbie this is a great help. One question. Is there a way to make the images hyperlinks?

    Thanks

    Norrie

    ReplyDelete
    Replies
    1. Thanks Norrie !
      You can hyperlink image by including the last img tag in the anchor tag as follows:

      <li>
      <a href="link path"
      <img src="{@FileRef}" class="captify" alt="{@Title}"/>
      </a>
      </li>

      Note : Please replace '<' and '>' with '<' and '>' respectively.

      Delete
    2. Hi Youdhbir,

      Thanks a lot for your reply. Unfortunately, I'm still a bit confused. Is "link path" referencing a column in the Picture Library? Also, not sure about what you mean in your Note:. It looks like you're replacing '<' with the same '<'. What is the difference?

      Norrie

      Delete
    3. Hi Norrie,

      "link path" can be any link of your choice or any column name.
      And please don't consider Note. This is the result of my unawareness :)

      -Youdhbir

      Delete
    4. Thanks so much for your help Youdhbir. Works like a charm.

      Norrie

      Delete
  4. It works great for me, in FireFox. For some reason my IE is caching #headers li img{display:none;} so it never displays the images. If i set this off it works.. kind of. It displays the captions sometimes and sometimes not. Any ideas what I could do to force IE to recognise the change?

    ReplyDelete
  5. This is fantastic. I've been working on this for a couple of days on and off, was almost there, but your solution saved me a lot of frustration! Thanks for the post.

    Dean Lawson

    ReplyDelete