Thursday, July 24, 2014

JQuery Slide Animation using a SharePoint Document Library

I've been exploring the concept of leveraging SharePoint's UI to easily upload and manage libraries of photos along with rendering out the stored images to an animated presentation. I used a DFWP (Data Form Web Part) and stripped out all the html table elements (<table>,<tr>,<td>, etc.) to ensure that an unbroken rendering of the library would be displayed. Next, I used filtering to restrict images based on metadata-embedded expiration dates (This would allow images to be automatically removed at a predetermined date, if needed). A little JQuery here, a little Javascript there, filled in with just a little XSLT, and a controlled slide animation was birthed!

Below is the code (This assumes that a JQuery library of at least 1.7.2 is referenced). This is really easy to work with, partially because the kind of animation at work isn't very complicated, but also because it doesn't require a special JQuery libary, apart from the core library to work. As a quick side note, I did experiment in using the same approach while employing other JQuery libraries for more sophisticated effects. This will work as well, provided that the necessary parsing code (Usually <div> tags with a special class or id) are added to the XSLT around the image declaration. Hope it helps someone!


JAVASCRIPT \ JQUERY (I needed my slide show sized dynamically, per the visitor's screen setup, hence the dimensions calculations (Call this function via the onload handler). The sizing is multiplied by 200, as my images were "200px" wide. At the end, two subsequent functions hand the animation off to each other, back and forth, in an infinite loop. There's probably a more elegant way to do this, but it works and doesn't seem to drain resources to any great length.

function finishStartUp()
{
/*Locate all the slides (IMG) within the DFWP and return as an array*/
var allSlides = $('#slides img').map(function(){
                       return this.src;
                   }).get();
/*Calculate the sizing of the container, based on the array length, that is needed to show all the images in a continuous line without over compensating on either side*/
var thisWide = allSlides.length*200-document.getElementById('slides').offsetWidth;
//Pass the sizing off to the first animation function
beginSlideShow(thisWide);  
}

function beginSlideShow(wide)
{
/*Animate a complete run then, pass off the sizing to the return animation*/
$('#slides').animate({
   marginLeft: -wide+'px',
   },20000,function(){bounceSlideShow(wide)}); 

}
function bounceSlideShow(wide)
{
/*Continue the animation backward, then pass the sizing again back to the first function*/
$('#slides').animate({
   marginLeft: '0px',
   },20000,function(){beginSlideShow(wide)}); 

}



HTML \ XSLT (Good stuff marked in red - I removed my GUIDs, as they wouldn't work anyway if copied from below. The GUIDs are system generated when webparts are supplied via SharePoint's tools, and should be included when you insert a DFWP on your page)

<div id="slideDiv" style="overflow:hidden;">
<div id="slides" style="white-space:nowrap;">
<WebPartPages:DataFormWebPart runat="server" IsIncluded="True" AsyncRefresh="True" FrameType="None" NoDefaultStyle="TRUE" ViewFlag="8" Title="Slideshow" PageType="PAGE_NORMALVIEW" ListName="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" Default="FALSE" DisplayName="Slideshow" __markuptype="vsattributemarkup" __WebPartId="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" id="g_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" __AllowXSLTEditing="true" WebPart="true" Height="" Width="">
<DataSources>
<SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" UseServerDataFormat="true" selectcommand="&lt;View&gt;&lt;Query&gt;&lt;Where&gt;&lt;Or&gt;&lt;IsNull&gt;&lt;FieldRef Name=&quot;expires&quot;/&gt;&lt;/IsNull&gt;&lt;Gt&gt;&lt;FieldRef Name=&quot;expires&quot;/&gt;&lt;Value Type=&quot;DateTime&quot;&gt;&lt;Today/&gt;&lt;/Value&gt;&lt;/Gt&gt;&lt;/Or&gt;&lt;/Where&gt;&lt;/Query&gt;&lt;/View&gt;" id="Slideshow1"><SelectParameters><WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"/></SelectParameters><DeleteParameters><WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"/></DeleteParameters><UpdateParameters><WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"/></UpdateParameters><InsertParameters><WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"/></InsertParameters></SharePoint:SPDataSource>
</DataSources>
<ParameterBindings>
<ParameterBinding Name="ListID" Location="None" DefaultValue="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"/>
<ParameterBinding Name="dvt_apos" Location="Postback;Connection"/>
<ParameterBinding Name="ManualRefresh" Location="WPProperty[ManualRefresh]"/>
<ParameterBinding Name="UserID" Location="CAMLVariable" DefaultValue="CurrentUserName"/>
<ParameterBinding Name="Today" Location="CAMLVariable" DefaultValue="CurrentDate"/>
</ParameterBindings>
<datafields>@FileLeafRef,Name (for use in forms);@Title,Title;@expires,expires;@ID,ID;@ContentType,Content Type;@Created,Created;@Author,Created By;@Modified,Modified;@Editor,Modified By;@_CopySource,Copy Source;@CheckoutUser,Checked Out To;@_CheckinComment,Check In Comment;@CheckedOutTitle,Checked Out To;@CheckedOutUserId,ID of the User who has the item Checked Out;@FileDirRef,Path;@FSObjType,Item Type;@HTML_x0020_File_x0020_Type,HTML File Type;@File_x0020_Type,File Type;@IsCheckedoutToLocal,Is Checked out to local;@_SourceUrl,Source URL;@_HasCopyDestinations,Has Copy Destinations;@ContentTypeId,Content Type ID;@_ModerationStatus,Approval Status;@_UIVersion,UI Version;@Created_x0020_Date,Created;@FileRef,URL Path;@File_x0020_Size,File Size;@ItemChildCount,Item Child Count;@FolderChildCount,Folder Child Count;@_UIVersionString,Version;@ParentVersionString,Source Version (Converted Document);@ParentLeafName,Source Name (Converted Document);@TemplateUrl,Template Link;</datafields>
<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">&apos;</xsl:param>
<xsl:param name="ManualRefresh"></xsl:param>
<xsl:param name="Today">CurrentDate</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:choose>
<xsl:when test="($ManualRefresh = 'True')">
<xsl:call-template name="dvt_1"/>
<img src="/_layouts/images/staticrefresh.gif" id="ManualRefresh" border="0" onclick="javascript: {ddwrt:GenFireServerEvent('__cancel')}" alt="Click here to refresh the dataview."/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="dvt_1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="dvt_1">
<xsl:variable name="dvt_StyleName">RepForm3</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" />
<xsl:variable name="dvt_IsEmpty" select="$dvt_RowCount = 0"/>

<xsl:choose>
<xsl:when test="$dvt_IsEmpty">
<xsl:call-template name="dvt_1.empty"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose></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">
<xsl:param name="urlSlide" select="@FileLeafRef" />
<img src="http://website.com/Slideshow/{$urlSlide}" style="height:150px;" />
<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
<span ddwrt:amkeyfield="ID" ddwrt:amkeyvalue="ddwrt:EscapeDelims(string(@ID))" ddwrt:ammode="view"></span>
</xsl:if>
</xsl:template>
<xsl:template name="dvt_1.empty">
<xsl:variable name="dvt_ViewEmptyText">There are no items to show in this view.</xsl:variable>
<table border="0" width="100%">
<tr>
<td class="ms-vb">
<xsl:value-of select="$dvt_ViewEmptyText"/>
</td>
</tr>
</table>
</xsl:template></xsl:stylesheet> </XSL>
</WebPartPages:DataFormWebPart>

</div>


</div>

No comments:

Post a Comment