Build a Better Photo Gallery for SharePoint using REST and Handlebars

Working with SharePoint’s REST API is pretty cool. Lately, I’ve been writing plenty of applications where the entire CRUD is involved; all using SharePoint lists behind the scenes. Meaning, the entire front end is entirely up to me to build. This way, I can use different Javascript libraries and frameworks when building these interfaces.

View in Github

Today, let’s look at something pretty simple. Let’s build a photo gallery using SharePoint Picture library as the backend, together with Handlebars.js – a good Javascript templating system. With this knowledge, you will gain good understanding on how to select items with SharePoint’s REST API, which I happen to have a post on.

bspg2

Ready to get started? Roll up your sleeves and let’s write some code. Note that I will not go over the entire code base in this tutorial – just the meat of the logic.

Setup the Gallery

First we need to make sure we have a gallery to connect to. In SharePoint, you do this by going to “View All Site Content” and adding a new Picture Library. Note that for this demo I’m using SharePoint 2010 – I believe in newer versions you have to “Add an App” > “Photo Library”.

Be sure to note the name of your library:

sp-photo-gallery-3

Upload some images to your newly created library. Now we can continue and pull our images in the front end.

The Javascript

Create a Javasript file and name it sp-gallery.js. You can place it inside any SharePoint document library – and simply map to it using Windows Explorer so you can write to it just like you would as if it was a local file.

Let’s setup the wrapper for our gallery. We’re using the “Revealing Module” pattern so we can have methods that are public and private, as well as we keep our logic real tidy. We’re adding private variables inside our class so we can use it all over our code.

Get the List Count

Our first method is to grab the number of photos in our library. This is important so we can decide whether to show our “show more” button or not. Note the use our our “webUrl” and “listName” variables in our method. Add this code inside our gallery wrapper. This method is internal, so we create a function declaration:

The above will return a “promise” object that we can use to manipulate later on. In the case above, it’s simply a number.

Get the Gallery Items

This method is the call to grab our list items. Again, we’re using jQuery’s “Ajax” method, returning a promise object.

Compile with HandleBars

This method is taking the data that is returned from our ajax promise above, and compiling it with handlbars. We haven’t built our HTML yet – which contains the actual handebars template. Note that this is a public function, so we’re creating the function as a “function expression”:

Also note that I’ve added a “popup” functionality which we’ve instantiated in the code above. We’re using magnificpopup.js for this awesome feature.

The “Show More” button

We’re only loading a certain subset of photos in our gallery. We will have a button in the bottom of our images that when clicked, will do another fetch to our list and add them below. Again, this is public, so it’s a “function expression”.

This sort of acts like an “infinite scroll” functionality – but with a button. I’m not particularly fond of that automatic loading.

Initializing the Gallery

Now that our methods are in place, it is time to tie them all together and returning them so we can call them outside of our class. We do this by creating an “init” function.

Notice that we are only returning the public functions above. So we are keeping our variables and private functions inaccessible from the outside world. Let’s move on to our helpers:

HandleBar Helpers

These methods doesn’t have to be our gallery code. This can live outside, so it can be accessed by Handlebars. The code is namespaced using the Handlebars object. I’ll explain what the do below:

We will use a “findGroup” helper inside our templates so we can “group” our photos together. This is what our “Magnificpopup” plugin requires – so when you click “next” or “previous” – it knows which photo to show.

The “imgSrc” helper simply returns the source of the images, while the “imgSrcThumb” returns the thumbnail path. Note that this helper only supports jpegs at the moment.

The CSS

We are simply displaying the thumbnails in a grid fashion, so our styles are quite basic. I’m using this inside a Bootstrap wrapper, so you can see the “.col” classes in our HTML later. Create a file and name it sp-gallery.css and add the code below:

I’ve also added extra “col” classes for my own grid styles when the viewport is decreased. Also notice the .mfp classes are necessary for our magnific popup to work “magnificently”.

The HTML

Finally, this is the file that we add to any page of our SharePoint site. Create a text file – name it “sp-gallery.txt” and add the code below:

The above contains the references to the files we need. Note to change the paths to your sp-gallery.css and sp-gallery.js that we’ve created above, to your local one – IF you followed the tutorial. If you keep them as is, they’re pointing to the development GIT files – which may change in time.

We went ahead and create our gallery and pass in the name of our Photo Gallery above. We then initialize and add the “showmore” handler when our button is clicked.

Add our Handlebars template to the text file:

The above template is what we need for our gallery to work. This code represents each tile that we will produce in our gallery.

Save this text file (along with the .js and .css) and add it to any SharePoint page. Add a Content Editor WebPart, and add a link to an external file – to our .txt file.

sp-photo-gallery-2

I usually edit the webpart to “NOT” show the chrome.

Final Result

Save the page and if everything works well, you should see something like below:

bspg

A simple photo gallery with popup and paging functionality. It surely looks better than the “out of the box” photo gallery that SP provides. Furthermore, you have complete ability to change the look as much as you want.

But the real value is the introductory lesson to working with SharePoint’s REST api. Be sure to stay tuned for more stuff like this. Leave your comments below.

34 Comments

  1. Hi Michael,

    Thank you for this wonderful! This is my first rest app and was able to use it in SharePoint Online.
    Thanks a lot.

    Reply
  2. Hey Michael,

    Thanks for the awesome post. Can you please let me know how can I create a photo gallery which shows only black color as thumbnail and after clicking on it, it redirects to respective document library with different color icon.

    Thanks,
    Rishabh

    Reply
  3. It shows ‘gallery’ is undefined. Had queries in sequence of code and braces. Will it be correct or the brace for var gallery needs to be closed before??

    var gallery = function(list){
    //our private vars here…
    //init function
    //the rest of the methods here…
    }
    //below returns our public methods for use:
    return {
    init : init,
    showmore : showmore,
    buildGallery : buildGallery
    }

    Reply
  4. Hi Micheal,
    After I setup all the things in the sharepoint – changing the js,css and sp-gallery.js path.
    and put the text file to the CEWP, the only thing that came out was the square outline of the picture box (got 4 picture in the gallery). Therefore, the web show 4 square box with no image in it.
    when i check the box url link, it not the path of the image where it should be,

    Here what is the box url link: sharepoint.com/sites/subsite01/sites/subsite01/subsite02/Gallery/car.jpg
    Here is what I think it should be : sharepoint.com/sites/subsite01/subsite02/Gallery/car.jpg

    When I try to change the sp-gallery.js at the handlebars.registerHelper(‘imgSrc’,function(data)
    well nothing change..it still show the same url with that duplicate subsite.

    Thanks.

    Reply
    • Hi Ikki,
      view your webpage using Chrome and open the console. this will show you what’s going on – usually for broken images – it will show you where it’s looking, and you figure out how to fix.

      Reply
      • Michael I am getting a similar problem. The Chrome console is telling me it can’t find the thumbnail in the “_t” subfolder – do I have to generate thumbnails some how first?

      • The document library you’re using is probably not a “Picture Library”. Try creating a “Picture Library” and add the photos there and point to it. SharePoint generates the thumbnails inside a “_t” subfolder

    • can you go inside the same handlebars helper (imgSrc) and do a console log on what “data.Path” is? That is what’s causing the duplicate “subsite01/subsite02/”

      Reply
      • can you go inside the same handlebars helper (imgSrc) and do a console log on what “data.Path” is? Just write this line:
        console.log(data.Path);
        inside the helper, then do a refresh on the webpage and see the console.
        I think that’s what’s causing the duplicate “subsite01/subsite02/”

      • Yes, data.path is always “/sites/mySite/myPictures” thus adding the doublicate site.

        Another question: Are you planning to add folder support? Would be awesome to use that clean gallery together with folder navigation.

        Great work, cheers

  5. This doesn’t work for me unfortunately. Using SharePoint 2010 and followed instructions… all that appears on my page is the Show more button. Any ideas

    Reply
    • Use chrome so you can debug easier. Press F12 and check out the “console” tab. You will see JavaScript errors in there. Post your findings here and I’ll help you.

      Reply
  6. Hi Michael
    Thanks for your great work for this beautiful Gallery.

    Sadly I got the same problem on our SP2013 platform: “shows only squares on the page and after clicking on it,’The Image could not be loaded’ appears”. Press F12 debug console displayed “SCRIPT5: Access is denied.”
    Microsoft Dev Network:
    https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=DE-CH&k=k(VS.WebClient.Help.SCRIPT5)

    Advise: “If you’re trying to call a REST API, refactor this call to your server-side code, then expose a new REST endpoint for your client-side scripts.”

    How can I create this REST-endpoint script including in your script?

    Every other resource is available locally.

    Thanks in advance

    Reply
    • What they’re referring to is writing it in c# – which is not covered in this tutorial. This is all front end code. Or you add more permissions to your gallery.

      Reply
  7. I replaced the line “return url” in .JS to “return url.replace(‘/sites/photos’,”);” (photos is my sitecollection) and now it works.
    I also added to Handlebars line #4 this “background-repeat: no-repeat;”
    And disabled SharePoint Minimal Download Strategy that can make troubles.
    Now it is working fine.

    Reply
  8. Getting this error for the popup:

    sp-gallery.js:46 Uncaught TypeError: $(…).magnificPopup is not a function
    at buildGallery (sp-gallery.js:46)
    at Object. (sp-gallery.js:20)
    at c (jquery.min.js:3)
    at Object.fireWith [as resolveWith] (jquery.min.js:3)
    at k (jquery.min.js:5)
    at XMLHttpRequest.r (jquery.min.js:5)

    Seems to work after a page reload but not at first post. Any ideas?

    Thanks

    Reply
  9. Hi i am able to generate gallery. But when I click the thumbnail image . The image could not be loaded message is coming . Please help

    Reply
  10. HI, i have this problem: Uncaught TypeError: Cannot read property ‘replace’ of undefined sp-gallery.js:104
    at Object. (sp-gallery.js:104)
    at eval (eval at createFunctionContext (handlebars.min.js:28), :8:111)
    at h (handlebars.min.js:27)
    at c (handlebars.min.js:27)
    at Object. (handlebars.min.js:27)
    at Object.eval [as main] (eval at createFunctionContext (handlebars.min.js:28), :6:31)
    at c (handlebars.min.js:27)
    at d (handlebars.min.js:27)
    at e (handlebars.min.js:28)
    at buildGallery (sp-gallery.js:47)
    shellplusg2m_73d3a900.js:29 Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘https://portal.office.com’) does not match the recipient window’s origin (‘https://login.microsoftonline.com’).

    Reply
    • Hi All
      I’m getting the same problem as Andreas, take a look:

      Uncaught TypeError: Cannot read property ‘replace’ of undefined
      at Object. (sp-gallery.js:104)
      at eval (eval at createFunctionContext (handlebars.min.js:28), :8:111)
      at h (handlebars.min.js:27)
      at c (handlebars.min.js:27)
      at Object. (handlebars.min.js:27)
      at Object.eval [as main] (eval at createFunctionContext (handlebars.min.js:28), :6:31)
      at c (handlebars.min.js:27)
      at d (handlebars.min.js:27)
      at e (handlebars.min.js:28)
      at buildGallery (sp-gallery.js:47)

      Any suggestion to fix it? I’m using SharePoint Online.

      Thanks!

      Reply
      • this is an error in handlebars – so try to debug even before compiling the template. My hunch is some of the items do not have a value.

  11. Failed to load resource: the server responded with a status of 404 ()
    /sites/myngn/_catalogs/masterpage/NGN/js/sp-gallery.js:64 error in fetching list count
    /sites/myngn/_catalogs/masterpage/NGN/js/sp-gallery.js:65 Object
    /sites/myngn/_vti_bin/listdata.svc/stockphotos?$top=20&$skip=0 Failed to load resource: the server responded with a status of 404 ()
    /sites/myngn/_catalogs/masterpage/NGN/js/sp-gallery.js:85 Object

    Any ideas?

    Reply

Leave a Comment.