SharePoint 2013 Bootstrap Carousel Photo App Library and SPServices

Recently I have been working with quite a few different SharePoint 2013 sites. A few of these have had requests for image sliders. My go to framework for SharePoint 2013 has been the Bootstrap 3 responsive framework, so using the flexible Bootstrap 3 Carousel is a logical choice.

Note! This will only work if you are using the Bootstrap Framework already. If you are not, and would like a content slider check out some other options from Mark Rackley, Ben Tedder or Google.

The Carousel html is simple to setup in a static environment, but when it comes to loading data from a SharePoint 2013 library into the carousel we need to call upon the wonderful SPServices jQuery Library! There is a great youtube video by Mark Rackley showing how to use the Unslider in SharePoint with a different type of library that helped in the creation of this Bootstrap carousel.

There are four parts to this setup. Note! #2 is not a requirement.

  1. Create an App, a Photo Library app and call it HomepagePhotos and add some optimized (I used 970×400 jpg’s) images to it.
  2. Create an Image Rendition (If you can. Read Prerequisites on the MS page.) called HomepagePhotos and give it the dimensions you would like your slider image to be. I have mine set to 970×400 for example. Note the Image Rendition ID. It will probably be 5 if you add a new one.
  3. Create a single JavaScript file in your SiteAssets folder called slider.js and paste the code below into your slider.js file.
  4. Add a Content Editor WebPart to your page and load the ../SiteAssets/slider.js file.
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/2014.02/jquery.SPServices.min.js"></script><script type="text/javascript">
<script>
jQuery(document).ready(function($) {
   GetPics("HomepagePhotos");
});
  function GetPics(hp) {
      //query to retrieve all items
      var query = "<Query><Where><Neq><FieldRef Name='ID' /><Value Type='Number'></Value></Neq></Where></Query>";
      //fields containing Carousel infomration. FileRef is picture URL with some junk to strip
      var camlViewFields = "<ViewFields><FieldRef Name='FileRef' /><FieldRef Name='Title' /><FieldRef Name='Description' /></ViewFields>";
      //using a counter to find the FIRST slide and give it the class active.
      var i = 0;
      $().SPServices({
          operation: "GetListItems",
          async: true,
          listName: hp,
          CAMLViewFields: camlViewFields,
          CAMLQuery: query,
          completefunc: function(xData, Status) {
              $(xData.responseXML).SPFilterNode("z:row").each(function() {
                  //Define variables
                  //You can do a console.log(xData.responseXML) and see all the fields real quickly
                  var filename = ($(this).attr("ows_FileRef"));
                  var title = ($(this).attr("ows_Title"));
                  //Description here is what is used for Alt text
                  var desc = ($(this).attr("ows_Description"));
                  //Filename has some data before it, so replace 1;# info before URL     
                  var picture = filename.match(/(?:(?!#).)*$/);
                  //Check if it is the first entry... if so add active.
                  //You will see ?RenditionID=5 after the immage. I am using Image Reditions to make sure the images are the correct size... though this does not optimize. https://msdn.microsoft.com/en-us/library/office/jj720398.aspx
                  if (i == 0) {
                      $("#MyCarousel .carousel-indicators").append("<li data-target='#hubCarousel' data-slide-to=" + i + " class='active'></li>");
                      $("#MyCarousel .carousel-inner").append("<div class='item active'><img src='/" + picture + "?RenditionID=5' alt='" + desc + "'><div class='carousel-caption'><strong>" + title + "</strong></div></div>");

                  } else {
                      $("#MyCarousel .carousel-indicators").append("<li data-target='#hubCarousel' data-slide-to=" + i + "></li>");
                      $("#MyCarousel .carousel-inner").append("<div class='item'><img src='/" + picture + "?RenditionID=5' alt='" + desc + "'><div class='carousel-caption'><strong>" + title + "</strong></div></div>");
                  }
                  //increase count until .each is done.
                  i++;
              }); 
          }
      }); 
  }
</script>

<div id="MyCarousel" class="carousel slide" data-ride="carousel">
  <ol class="carousel-indicators"></ol>
  <div class="carousel-inner"></div>
  <a class="left carousel-control" href="#MyCarousel" role="button" data-slide="prev">
    <span class="fa fa-chevron-left"></span>
  </a>
  <a class="right carousel-control" href="#MyCarousel" role="button" data-slide="next">
    <span class="fa fa-chevron-right"></span>
  </a>
</div>

After you have added your CEW and linked to your slider.js file, save your page, check it in and publish it.

If all went well, you will see your Carousel begin. Hopefully this worked well for you. If you ran into issues, maybe I can help! Leave a comment below.

*BONUS! There is a wonderful set of Bootstrap Carousel’s by Rico Loschke on sevenx.de.

#Bootstrap#Carousel#featured#jQuery#sharepoint 2013#SPServices

Comments

  1. Patrick - May 29, 2015 @ 7:54 am

    I have implemented this solution, but none of my images are showing up after adding a content editor and linking to the .js file.

  2. jasonflaherty.com">Jason Flaherty - June 16, 2015 @ 10:06 am

    Make sure that your images are being found in the caml view fields. You can do a console.log(camlViewFields) to make sure you see the correct info.

  3. Ramses Reyes - January 18, 2016 @ 12:02 pm

    Hi Jason, I`m getting a “undefined” response when y call console.log(camlViewFields), my list name si PVM_slide so y call the function GetPics(“PVM_slide”); I need change anything else? navigation arrows from carousel are showing but without images on it.

  4. Brad - March 2, 2016 @ 5:12 pm

    Hi Jason – nice code… Few errors though:
    1. in the third line is duplicated from the end of the line above;
    2. “MyCarousel” is referenced in the ‘s but in the js code (data-target) hubCarousel is referenced – change one and it works.
    3. Not sure if it was my issue or what but the chevrons didn’t work properly so I changed to:
    Previous

    Oh – can watch the cut and paste… if you get weird chars – delete the whitespace and reformat.

  5. Marc - May 31, 2016 @ 7:23 am

    I’m using SharePoint 2010 but couldn’t get it to work using the code sample above. Also I use Picture Library as well. Did I do something different other than above? I want to copy/paste the code here but that will be too much.

  6. jasonflaherty.com">Jason Flaherty - February 10, 2017 @ 8:27 am

    Make sure you are console.log() the object so you can find the right pieces to read.

  7. jasonflaherty.com">Jason Flaherty - February 10, 2017 @ 8:29 am

    Thanks for the comment! I am missing the #1 item there? The chevrons might not work in IE if that is the browser… check in Chrome for confirmation.

  8. jasonflaherty.com">Jason Flaherty - February 10, 2017 @ 8:30 am

    You images must not be called correctly. console.log(xData.responseXML) to find the correct fields.

  9. jasonflaherty.com">Jason Flaherty - February 10, 2017 @ 8:31 am

    xData.responseXML try that in console rather than camlViewFields and see if you get response.

  10. jasonflaherty.com">Jason Flaherty - February 10, 2017 @ 8:32 am

    I feel like picture library was a strange one… i remember trying that at one point and not getting the results i needed. console.log() for fields and see if you can find what you need there?

  11. Vamshi Joshi - March 1, 2017 @ 7:02 pm

    Hi Jason, I receive an error “uncaught Type Error: Cannot read property ‘offsetWhidth’ of undefined at c.slide (bootstrap.min.js:) at c.next (bootstrap.min.js:6) at e (jquery.min.js:2). Any help will be much appreciated. Thanks

Leave a Reply

Your email address will not be published / Required fields are marked *