Beyond the Slideshow web part capabilities in SharePoint 2010

Overview

In one of the previous post we have started the discussion of customizing   Slideshow web part, in particular it was demonstrated  how to provide additional filtering for picture items. This time we’re going to go further and consider different scenarios of using SharePoint SlideShow capabilities. We deliberately do not consider the use of  third party libraries for Slideshow or creating custom web parts, but try to build new experience using existing tools only.

1. Customize the display for Slideshow control: display additional picture properties

Suppose in addition to standard properties, custom properties should be displayed  from Picture Library in Slideshow web part.

PictureLibCustomFields

The following  fields are retrieved  from Picture Library for Slideshow:

So, our goal is to display slideshow using custom layout as shown below

CarsSlideshow

Solution:

Solution consist of the following parts:

  • load custom picture properties, see loadCarPicturesAdditionalInfo method for details
  • Slideshow library (imglib.js) methods overriding for slideshow object initialization, picture  changing and displaying


function SlideshowObjectInitializer() {
ChangePic = (function(ChangePicOrig) {
return function() {
var ssObj = arguments[0]; //SlideShow object
if(typeof ssObj.additionalInfo != "undefined")
ChangePicOrig.apply(this, arguments);
};
})(ChangePic);
ShowPic = (function(ShowPicOrig) {
return function() {
ShowPicOrig.apply(this, arguments); //call original ShowPic
var ssObj = arguments[0]; //SlideShow object
ShowAdditionalPicInfo(ssObj);
};
})(ShowPic);
function ShowAdditionalPicInfo(ssObj)
{
var curPicIdx=ssObj.index; //current picture index
if(ssObj.additionalInfo.length == 0)
return;
var picEntry = ssObj.additionalInfo[curPicIdx];
var ssobj_ext_cell = '<td>';
ssobj_ext_cell += '<div style="font-size:22px;"><span style="font-weight:bold">Car Model:</span>' + picEntry.CarModel + '</div>';
ssobj_ext_cell += '<div style="font-size:22px;"><span style="font-weight:bold">Car Description:</span>' + picEntry.CarDesc + '</div>';
ssobj_ext_cell += '</td>';
var ssobj_row = jQuery(ssObj.cell).closest('tr');
if(ssobj_row.find('td').length > 1) {
ssobj_row.find('td:nth-child(2)').replaceWith(ssobj_ext_cell);
}
else
ssobj_row.append(ssobj_ext_cell);
}
SlideshowObject = (function(SlideshowObjectOrig) {
return function() {
SlideshowObjectOrig.apply(this, arguments);
var ssobj = this;
ExecuteOrDelayUntilScriptLoaded(function(){
loadCarPicturesAdditionalInfo(function(picEntries){
ssobj.additionalInfo = picEntries;
ChangePic(ssobj);
});
},'SP.js');
};
})(SlideshowObject);
}
function loadCarPicturesAdditionalInfo(cbPicsResults) {
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle("Pictures");
var viewXml = '<View></View>';
var query = new SP.CamlQuery();
query.set_viewXml(viewXml);
var items = list.getItems(query);
context.load(items,"Include(CarModel,CarDesc)");
context.add_requestSucceeded(onLoaded);
context.add_requestFailed(onFailure);
context.executeQueryAsync();
function onLoaded() {
var picEntries = [];
var itemsCount = items.get_count();
for (i = 0; i < itemsCount; i++) {
var item = items.itemAt(i);
var picEntry = item.get_fieldValues();
picEntries.push(picEntry);
}
cbPicsResults(picEntries);
}
function onFailure() {
cbPicsResults(null);
}
}

Usage

Save JavaScript code to the file and embed it into the page with Slideshow web part  as demonstrated below


<script src="/_layouts/SE/imglibutils.js" type="text/javascript"></script>
<script type="text/javascript">
ExecuteOrDelayUntilScriptLoaded(SlideshowObjectInitializer, 'imglib.js');
</script>

2. Customize the display for Slideshow control: display original pictures

In Slideshow web part, picture is initialized with field value that contains the Url of  Web image (EncodedAbsWebImgUrl  field). Unfortunately it is not supported to configure in web part what image type (original, web or thumbnail) should be displayed in Slideshow The solution that demonstrated below allows to display original images instead of web images in Slideshow web part.

Solution:

In order to specify original images, method overriding for picture initialization is used:


function SlideshowObjectInitializer() {
ShowPic = (function(ShowPicOrig) {
return function() {
var ssObj = arguments[0]; //SlideShow object
var curPicIdx=ssObj.index; //current picture index
ShowPicOrig.apply(this, arguments); //call original ShowPic
//apply some changes to display original picture in SlideShow control
ssObj.image.src = ssObj.linkArray[curPicIdx]; //display original image instead of web image
//change picture & container size to auto instead of fixed (by default web image size is used)
ssObj.image.setAttribute('height','100%');
ssObj.image.setAttribute('width','100%');
var cell = ssObj.cell;
cell.style.width = 'auto';
cell.style.height = 'auto';
cell.style.display = '';
var pcell = ssObj.cell.parentNode;
pcell.style.width = 'auto';
pcell.style.height = 'auto';
};
})(ShowPic);
}
ExecuteOrDelayUntilScriptLoaded(SlideshowObjectInitializer, 'imglib.js');

Usage

One of the most simple way to apply these changes is to embed specified JavaScript code via Content Editor web part (CEWP), for more details please follow this article.

  • Save JavaScript code to the file, for example in SlideshowObjectInitializer.txt and upload it to SiteAssets Library
  • Add CEWP on page where Slideshow web part is located and in the Content Editor tool pane, under Content Link property, type /SiteAssets/SlideshowObjectInitializer.txt

3. Slideshow List View

Slideshow List View is only available for Pictures Library. It is pretty common scenario when another types of repositories are used for storing images, for example Assets Library. Let’s look at how to create a Slideshow  List View for images stored in Assets Library.

Solution:

Slideshow List View


<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema&quot;
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp&quot;
version="1.0" exclude-result-prefixes="xsl msxsl ddwrt x d asp __designer SharePoint ddwrt2"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime&quot;
xmlns:asp="http://schemas.microsoft.com/ASPNET/20&quot;
xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer&quot;
xmlns:xsl="http://www.w3.org/1999/XSL/Transform&quot;
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:SharePoint="Microsoft.SharePoint.WebControls"
xmlns:ddwrt2="urn:frontpage:internal">
<xsl:import href="/_layouts/xsl/main.xsl"/>
<xsl:output method="html" indent="no"/>
<xsl:template match="View" mode="full" ddwrt:ghost="always">
<tr class="ms-viewheadertr"></tr>
<tr>
<td>
<!– Slideshow control –>
<table border="0" style="table-layout: fixed">
<tbody>
<tr>
<td >
<div id="slidecontrol_cell" style="display: table-cell; vertical-align: middle; text-align: center;">
<span style="vertical-align: middle; height: 100%; display: inline-block"></span>
<a id="slidecontrol_link" target="_blank">
<img id="slidecontrol_curr" style="opacity: 0.9900000000000007; border: 0px; vertical-align: middle;" alt=""/>
</a>
</div>
</td>
</tr>
<tr>
<td style="height: 75px">
<div style="height: 75px; opacity: 0.9900000000000007;" id="slidecontrol_text">
<span id="slidecontrol_title" class="ms-slideshow-title"></span>
<br/>
</div>
</td>
</tr>
<tr>
<td style="text-align: center">
<a id="btn_prev" >
<img border="0" style="position: relative; cursor: hand" onmouseover="HiliteButton()" onmouseout="DemoteButton()" src="/_layouts/images/plprev1.gif" alt="Previous Image"/>
</a>
<a id="btn_pp" >
<img border="0" style="position: relative; cursor: hand" onmouseover="HiliteButton()" onmouseout="DemoteButton()" src="/_layouts/images/plpause1.gif" id="slidecontrol_playpause" alt="Pause"/>
</a>
<a id="btn_next">
<img border="0" style="position: relative; cursor: hand" onmouseover="HiliteButton()" onmouseout="DemoteButton()" src="/_layouts/images/plnext1.gif" alt="Next Image"/>
</a>
</td>
</tr>
</tbody>
</table>
<img id="slidecontrol_next" width="0" height="0" style="visibility: hidden" />
<img id="slidecontrol_prev" width="0" height="0" style="visibility: hidden" />
<img id="slidecontrol_pp" width="0" height="0" style="visibility: hidden" />
</td>
</tr>
<script type="text/javascript">
var slidecontrol_slideshowObject;
ExecuteOrDelayUntilScriptLoaded(function(){
slidecontrol_slideshowObject = createSlideControl('slidecontrol_');
},'SP.js');
</script>
<xsl:apply-templates mode="footer" select="." />
</xsl:template>
<xsl:template name="SlideshowViewOverride" mode="RootTemplate" match="View" ddwrt:dvt_mode="root">
<script type='text/javascript' src="/_layouts/1033/imglib.js"></script>
<script type='text/javascript' src="/_layouts/yaspp/slideshow.js"></script>
<!–script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script–&gt;
<script type="text/javascript">
</script>
<xsl:call-template name="View_Default_RootTemplate"/>
</xsl:template>
</xsl:stylesheet>

Slideshow control initialization and retrieving picture entries from Assets Library


//initialize SlideshowObject control
function createSlideControl(slidecontrolId)
{
loadPicturesInfo(function(picEntries) {
var slidecontrol_slideshowObject = new SlideshowObject(slidecontrolId, picEntries.src, picEntries.fullImageSrc, picEntries.title, picEntries.description, picEntries.height, picEntries.width, 15, 1.0);
ChangePic(slidecontrol_slideshowObject);
InitSlideControlNavButtons(slidecontrol_slideshowObject);
});
}
//
function InitSlideControlNavButtons(slideshowObject) {
var btn_prev = document.getElementById("btn_prev");
AddEvtHandler(btn_prev, "onclick", function() { NextPrevious(slideshowObject, false);});
var btn_pp = document.getElementById("btn_pp");
AddEvtHandler(btn_pp, "onclick", function() { PlayPause(slideshowObject);});
var btn_next = document.getElementById("btn_next");
AddEvtHandler(btn_next, "onclick", function() { NextPrevious(slideshowObject, true);});
}
//retrieve picture entries for SlideObject control
function loadPicturesInfo(cbPicsResults) {
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle(ctx.ListTitle);
var viewXml = '<View></View>';
var query = new SP.CamlQuery();
query.set_viewXml(viewXml);
var items = list.getItems(query);
context.load(items,"Include(Title,EncodedAbsWebImgUrl,EncodedAbsUrl,ImageWidth,ImageHeight)");
context.add_requestSucceeded(onLoaded);
context.add_requestFailed(onFailure);
context.executeQueryAsync();
function onLoaded() {
var widthArray = [];
var heightArray = [];
var pictureArray = [];
var linkArray = [];
var titleArray = [];
var descriptionArray = [];
var itemsCount = items.get_count();
for (i = 0; i < itemsCount; i++) {
var item = items.itemAt(i);
var picEntry = item.get_fieldValues();
titleArray.push(picEntry.Title);
pictureArray.push(picEntry.EncodedAbsWebImgUrl);
linkArray.push(picEntry.EncodedAbsUrl);
descriptionArray.push('');
widthArray.push(picEntry.ImageWidth);
heightArray.push(picEntry.ImageHeight);
}
picEntries = {title:titleArray,description:descriptionArray,fullImageSrc: linkArray,src:pictureArray, width:widthArray,height:heightArray};
cbPicsResults(picEntries);
}
function onFailure() {
cbPicsResults(null);
}
}

view raw

slideshow.js

hosted with ❤ by GitHub

4. Aggregate picture items and render as Slideshow

The last example demonstrates how to display slideshow for pictures aggregated  from site collection.  For aggregating pictures from site collection, Content Query web part is utilized.

Solution

OuterTemplate.SlideShowBody template is intended for rendering Slideshow control in CQWP


<xsl:template name="OuterTemplate.SlideShowBody">
<xsl:param name="Rows" />
<xsl:param name="FirstRow" />
<xsl:param name="LastRow" />
<script type="text/javascript">
function loadScript(url, callback)
{
// adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// then bind the event to the callback function
// there are several events for cross browser compatibility
script.onreadystatechange = callback;
script.onload = callback;
// fire the loading
head.appendChild(script);
}
function InitSlideControlNavButtons(slideshowObject) {
var btn_prev = document.getElementById("btn_prev");
AddEvtHandler(btn_prev, "onclick", function() { NextPrevious(slideshowObject, false);});
var btn_pp = document.getElementById("btn_pp");
AddEvtHandler(btn_pp, "onclick", function() { PlayPause(slideshowObject);});
var btn_next = document.getElementById("btn_next");
AddEvtHandler(btn_next, "onclick", function() { NextPrevious(slideshowObject, true);});
}
<xsl:text>var widthArray = [</xsl:text>
<xsl:for-each select="$Rows">
<xsl:value-of select="@ImageWidth" />
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
<xsl:text>];</xsl:text>
<xsl:text>var linkArray = [</xsl:text>
<xsl:for-each select="$Rows">
<xsl:value-of select="concat('&quot;',@LinkUrl,'&quot;')" />
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
<xsl:text>];</xsl:text>
<xsl:text>var heightArray = [</xsl:text>
<xsl:for-each select="$Rows">
<xsl:value-of select="@ImageHeight" />
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
<xsl:text>];</xsl:text>
<xsl:text>var pictureArray = [</xsl:text>
<xsl:for-each select="$Rows">
<xsl:value-of select="concat('&quot;',@LinkUrl,'&quot;')" />
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
<xsl:text>];</xsl:text>
<xsl:text>var titleArray = [</xsl:text>
<xsl:for-each select="$Rows">
<xsl:value-of select="concat('&quot;',@Title,'&quot;')" />
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
<xsl:text>];</xsl:text>
<xsl:text>var descriptionArray = [</xsl:text>
<xsl:for-each select="$Rows">
<xsl:value-of select="concat('&quot;',@Description,'&quot;')" />
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
<xsl:text>];</xsl:text>
loadScript("/_layouts/1033/imglib.js", function()
{
var slidecontrol = new SlideshowObject('slidecontrol_', pictureArray, linkArray, titleArray, descriptionArray, heightArray, widthArray, 15, 1.0);
ChangePic(slidecontrol);
InitSlideControlNavButtons(slidecontrol);
});
</script>
<xsl:call-template name="SlideShowControl" >
</xsl:call-template>
</xsl:template>
<xsl:template name="SlideShowControl">
<table border="0" style="table-layout: fixed">
<tbody>
<tr>
<td >
<div id="slidecontrol_cell" style="display: table-cell; vertical-align: middle; text-align: center;">
<span style="vertical-align: middle; height: 100%; display: inline-block"></span>
<a id="slidecontrol_link" target="_blank">
<img id="slidecontrol_curr" style="opacity: 0.9900000000000007; border: 0px; vertical-align: middle;" alt=""/>
</a>
</div>
</td>
</tr>
<tr>
<td style="height: 75px">
<div style="height: 75px; opacity: 0.9900000000000007;" id="slidecontrol_text">
<span id="slidecontrol_title" class="ms-slideshow-title"></span>
<br/>
</div>
</td>
</tr>
<tr>
<td style="text-align: center">
<a id="btn_prev" >
<img border="0" style="position: relative; cursor: hand" onmouseover="HiliteButton()" onmouseout="DemoteButton()" src="/_layouts/images/plprev1.gif" alt="Previous Image"/>
</a>
<a id="btn_pp" >
<img border="0" style="position: relative; cursor: hand" onmouseover="HiliteButton()" onmouseout="DemoteButton()" src="/_layouts/images/plpause1.gif" id="slidecontrol_playpause" alt="Pause"/>
</a>
<a id="btn_next">
<img border="0" style="position: relative; cursor: hand" onmouseover="HiliteButton()" onmouseout="DemoteButton()" src="/_layouts/images/plnext1.gif" alt="Next Image"/>
</a>
</td>
</tr>
</tbody>
</table>
<img id="slidecontrol_next" width="0" height="0" style="visibility: hidden" />
<img id="slidecontrol_prev" width="0" height="0" style="visibility: hidden" />
<img id="slidecontrol_pp" width="0" height="0" style="visibility: hidden" />
</xsl:template>

Usage

  • Configure source properties (List Type: Picture Library, Content Type:  Picture)PicturesCQWP
  • Specify additional fields for retrieving via  CommonViewFields property. For more details how to display custom fields in a CQWP, follow this article


<property name="CommonViewFields" type="string">Description,Text;ImageWidth,Integer;ImageHeight,Integer;Title,Text;</property>

  • Replace OuterTemplate.Body template with OuterTemplate.SlideShowBody in ContentQueryMain.xsl. For more details how to customize XSL for the Content Query Web Part follow this article

Conclusion

The main idea of this post  was to demonstrate how to combine different components available in SharePoint 2010 in order to build new functionality without creating new one from scratch (i.e.: new web parts) or using third party components.

20 thoughts on “Beyond the Slideshow web part capabilities in SharePoint 2010

  1. HI, thank you so much for providing this information. I am using the option 2, “Customize the display for Slideshow control: display original pictures to force 100% of image size in the Slideshow web part.”

    I am having success EXCEPT that the very first image is still displaying at the reduced size; once the slideshow moves to the second image and beyond, the images appear full-size expected. Can you advise on why is image #1 not also appearing full-size?

    • Hi Nancy,
      I suspect it is related with how the page loading is taking place.
      So, in case of embedding JavaScript code using CEWP, please place the CEWP and Slideshow WP in the same zone and also place the CEWP before Slideshow WP.

      • Hi Vadim,
        exactly reverse in my case, first image is getting shown correctly with original but rest of the images are not showing correct. For rest of the images it is taking from _w folder.
        Any help is appriciated.

        Thank you.

  2. I am having a similar yet different problem with option 2. My slideshow is displaying the pics in thumbnail size originally, then changing them to full size, which causes a jump effect on screen as each picture loads. I have the script running ahead of the slideshow but cannot get this working.

    Any help would be much appreciated.

    Thanks.

    • Thank you so much for this code in Option 2, except I’m having the same problem – I’ve been looking for the answer for this for days. There’s a jump in the screen when the pictures transition. I tried moving the CEWP before the slideshow but it didn’t work. Please post a solution to this, thanks so much again.

      • Did anyone ever figure this out, i am using this code an am still having the jumping issue upon transition

  3. How do i get my Slideshow to Center on my page? I seen some entires for doing this by changing the master style sheet using the code below, however I do not have access to edit the master style sheet. I tried adding this code to a content editor, but it doesn’t seem to be working…Anything jump out as being wrong here?

    .ms-WPBody.noindex{
    font-size:8pt;
    font-family:”Segoe UI” !important;
    }

    .ms-WPBody.noindex table{
    font-size:1em;
    width:100% !important;
    height:100% !important;

    }

    .ms-WPBody.noindex td{
    font-size:10pt;
    font-family:”Segoe UI” !important;
    width:100% !important;
    height:200px !important;
    margin-left:auto !important;margin-right:auto !important;
    /* text-align:center !important;*/
    }

    .ms-WPBody.noindex td div{
    height:auto !important;
    width:100% !important;
    text-align:center !important;
    display:block !important;;
    }

    .ms-WPBody.noindex td div span{
    width:100% !important;
    }

    .ms-WPBody.noindex td img{
    height:100% !important;
    width:100% !important;
    }

  4. Very helpful post !
    I searched how to display the original Size – but how can i disable the hyperlink on the slideshow ?

    Thank you 🙂

  5. Vadim: This post is incredibly helpful. I used your StackExchange answer to the question of how to change the link from linking to the image to linking somewhere else. I was able to get that working, but it only lets me set one link. I tried setting ssObj.link.href to an array (the way linkArray is set up), but it still only links my images to the one custom URL.

    Is there a way to apply an array of URLs, so that each image links to a different URL? Ideally, I would reference a column created in the image library, but am OK hard-wiring the list of over-ride URLs. I just need a unique URL for each image in the library. I would greatly appreciate an answer.

  6. Excellent post!

    I am trying to show additional information same as option:1 in picture library slideshow page. Kindly share me the steps and code to achieve this. Thanks in advance.

  7. Pingback: How to display original images in SlideShow web part | Rafael de la Cruz' Blog

  8. I really hope someone is able to help me. Here’s the situation:
    I have a slideshow with 3 images. I want each image to have a different link. In Sharepoint, I’ve added an extra column to the picture library, so each image wil have its own link (text, not hyperlink).

    I used the JavaScript code from here: https://sharepoint.stackexchange.com/questions/13503/webpartpagespicturelibraryslideshowwebpart-adding-links/66988#66988

    This code works. However, this way the link will be the same for all 3 images. What I would like to do is get the text/value from my Sharepoint column, instead of a static link. I have no clue how to do this as I’m new to JavaScript, but I can imagine there is a way to achieve the value of a column, that can be used as the hyperlink?

    Please help me out 🙂 At work we’re working with Sharepoint 2013 on premise.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.