A Lightbox Web Part for SharePoint 2010

Written by Denis Stadler on . Posted in jQuery, SharePoint 2010

Even though SharePoint 2010 provides out of the box a Picture Library Slide Show Web Part, I’ve noticed that the content editors feel more comfortable when they have a true Lightbox implementation available.

So what I will present next is a SharePoint implementation of Lokesh Dhakar’s Lightbox 2.


You can download the full source as Visual Studio solution – Stadler.Lightbox. The solution is packaged as a site collection feature.

If you don’t have jQuery activated inside your site collection (and the web part needs it), you could deploy it using the solution presented on this post – Step by Step: How to Add jQuery to a SharePoint 2010 Site Collection.

Implementation

Basically what I did was to pack all the original Lightbox files as SharePoint Package, correcting the JPG path into the CSS files.

From the SharePoint developer point of view the main challenge was to add a custom tool part for the web part.

Taking into consideration the user experience, I wanted to pre-load all the available picture libraries within my SharePoint site in order to eliminate the possibility of typing a wrong name in a text box (that would have been the easier option).

Then, for every picture library, I’m loading all the defined views in order to filter the pictures displayed in my web part (basically I’m re-using the view’s filter conditions).

To create a custom tool part you need to derive the ToolPart class, which exists inside the Microsoft.SharePoint.WebPartPages namespace. Then I rendered this custom tool part by overriding the CreateChildControls method and this is done exactly as in the case of a web part.

    public class SelectPictureLibraryToolPart : Microsoft.SharePoint.WebPartPages.ToolPart
    {
        // This is the actual dropdown control
        System.Web.UI.WebControls.DropDownList ddPictureLibrary = new System.Web.UI.WebControls.DropDownList();
        System.Web.UI.WebControls.DropDownList ddView = new System.Web.UI.WebControls.DropDownList();
        // Reference to the parent web part
        LightboxWebPart webpartParent = null;

        public SelectPictureLibraryToolPart()
        {
            // Set the title of our toolpart
            this.Title = "Choose Picture Library";
        }

        void ddPictureLibrary_SelectedIndexChanged(object sender, EventArgs e)
        {
            ddView.Items.Clear();

            SPWeb webCurrent = SPContext.Current.Web;
            SPPictureLibrary listPictures;
            try
            {
                listPictures = (SPPictureLibrary)webCurrent.Lists[ddPictureLibrary.SelectedValue];
            }
            catch
            {
                ddView.Items.Clear();
                return;
            }

            ddView.Items.Add("");

            foreach (SPView v in listPictures.Views)
            {
                ddView.Items.Add(v.Title);
            }
        }

        protected override void CreateChildControls()
        {
            ddPictureLibrary.SelectedIndexChanged += new EventHandler(ddPictureLibrary_SelectedIndexChanged);
            ddPictureLibrary.AutoPostBack = true;

            // Get the instance of the web part
            webpartParent = (LightboxWebPart)ParentToolPane.SelectedWebPart;

            ddPictureLibrary.Items.Add("");

            SPWeb webCurrent = SPContext.Current.Web;
            // Add some items to the dropdown, this is also where you would dynamically populate any items to add
            foreach (SPList l in webCurrent.Lists)
            {
                if (l.BaseTemplate == SPListTemplateType.PictureLibrary)
                {
                    ddPictureLibrary.Items.Add(l.Title);
                }
            }

            ddPictureLibrary.SelectedValue = webpartParent.PictureLibrary;

            if (!string.IsNullOrEmpty(webpartParent.PictureLibrary))
            {
                ddView.Items.Add("");
                foreach (SPView v in webCurrent.Lists[webpartParent.PictureLibrary].Views)
                {
                    ddView.Items.Add(v.Title);
                }

                ddView.SelectedValue = webpartParent.View;
            }

            // Add the dropdown to the actual toolpart controls
            this.Controls.Add(new LiteralControl("Picture Library: "));
            this.Controls.Add(ddPictureLibrary);
            this.Controls.Add(new LiteralControl("<br/><br/>Select View: "));
            this.Controls.Add(ddView);
            this.Controls.Add(new LiteralControl("<br/><br/>"));

            base.CreateChildControls();
        }

        public override void ApplyChanges()
        {
            // Set the value on apply. This is using a public property on the webpart
            webpartParent.PictureLibrary = ddPictureLibrary.SelectedValue;
            webpartParent.View = ddView.SelectedValue;
        }

    }

Then, when creating the web part I changed the parent class to: Microsoft.SharePoint.WebPartPages.WebPart.

    [ToolboxItemAttribute(false)]
    public class LightboxWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {

        #region Properties
        private string strName = "Lightbox";

        [WebBrowsable(true),
        Category("Configuration"),
        Personalizable(PersonalizationScope.Shared),
        WebDisplayName("Lightbox Name"),
        WebDescription("Please choose a name for the Lightbox.")]
        public string Name
        {
            get { return strName; }
            set { strName = value; }
        }


        private string strPictureLibrary = string.Empty;
        // This is what we use to set the value from the toolpart's ApplyChanges() method
        public string PictureLibrary
        {
            get
            {
                return strPictureLibrary;
            }
            set
            {
                strPictureLibrary = value;
            }
        }

        private string strView = string.Empty;
        public string View
        {
            get
            {
                return strView;
            }
            set
            {
                strView = value;
            }
        }
        #endregion

        #region Add the Custom Tool Part
        // This is the overwritten method to get the custom toolpart
        public override ToolPart[] GetToolParts()
        {
            // Create an array of toolparts to return
            ToolPart[] toReturn = new ToolPart[3];
            // Normal webpart properties like size, width, title, etc
            WebPartToolPart wptp = new WebPartToolPart();
            // Any properties that would come from your webpart
            CustomPropertyToolPart cptp = new CustomPropertyToolPart();
            // Add your custom toolpart
            SelectPictureLibraryToolPart pltp = new SelectPictureLibraryToolPart();
            toReturn[0] = wptp;
            toReturn[1] = cptp;
            toReturn[2] = pltp;
            return toReturn;
        }
        #endregion

        #region Create Child Controls
        protected override void CreateChildControls()
        {
            SPWeb webCurrent = SPContext.Current.Web;

            #region Get Picture Library
            SPPictureLibrary listPictures;
            try
            {
                listPictures = (SPPictureLibrary)webCurrent.Lists[strPictureLibrary];
            }
            catch
            {
                Controls.Add(new LiteralControl("Please check the selected pictures library under the Choose Picture Library web part settings!"));
                return;
            }
            #endregion

            #region Get Pictures from View
            SPListItemCollection collPictures;
            try
            {
                SPQuery q = new SPQuery();
                q.Query = listPictures.Views[strView].Query;
                q.ViewFields = string.Concat(
                                   "<FieldRef Name='Title' />",
                                   "<FieldRef Name='Name' />",
                                   "<FieldRef Name='EncodedAbsUrl' />",
                                   "<FieldRef Name='EncodedAbsThumbnailUrl' />");
                q.ViewFieldsOnly = true;

                collPictures = listPictures.GetItems(q);
            }
            catch
            {
                Controls.Add(new LiteralControl("Please check the selected view under the Choose Picture Library web part settings!"));
                return;
            }
            #endregion

            foreach (SPListItem i in collPictures)
            {
                try
                {
                    LiteralControl l = new LiteralControl();

                    string strTitle = string.Empty;

                    try
                    {
                        strTitle = i.Title;
                    }
                    catch
                    {
                        strTitle = i.Name;
                    }

                    string strFullImage = new Uri((string)i["EncodedAbsUrl"]).AbsolutePath;
                    //string strWebImage = new Uri((string)i["EncodedAbsWebImgUrl"]).AbsolutePath;
                    string strThumbnail = new Uri((string)i["EncodedAbsThumbnailUrl"]).AbsolutePath;

                    l.Text = string.Format("<div class=\"lightbox-photo-box\"><a href=\"{0}\" rel=\"lightbox[{1}]\" title=\"{2}\" class=\"lightbox-photo-a\"><img src=\"{3}\"/></a></div>", strFullImage, strName, strTitle, strThumbnail);

                    Controls.Add(l);
                }
                catch { }
            }

        }
        #endregion
    }

The idea behind the rendering of the web part is quite simple: all the pictures stored in a picture library, have a 160*160px thumbnail, which is automatically generated when the item is saved.

The thumbnail URL can always be read from the following library field: EncodedAbsThumbnailUrl.

I used also the Title field (when it has value, otherwise the code reads the file name) to generate the caption of the Lightbox.

CSS

Every picture’s thumbnail is encapsulated in a div having the following class: lightbox-photo-box

The build-in CSS stands as follows:

.lightbox-photo-box
{
    background:url("/_layouts/images/selbg.png") repeat-x left top;
	background-color:#f7f7f7;
	border:1px solid;
	border-top-color:#e4e4e4;
	border-right-color:#cdcdcd;
	border-bottom-color:#d6d6d6;
	border-left-color:#e4e4e4;
	width:170px;
    height:170px;
	float:left;
	text-align:center;
	margin-right:10px;
	margin-top:10px;
}

.lightbox-photo-box  img {
	border:0;
	display:none;
}

Basically that’s all folks :) ! Et voilà!

Tags: , , , , ,

Trackback from your site.

Denis Stadler

I'm a technology enthusiast, with more than 10 years of experience in SharePoint and Dynamics CRM projects. To find more details about, please visit the about me page.

Comments (21)

  • Pran

    |

    Hi,
    I am getting the error “Microsoft JScript runtime error: ‘jQuery’ is undefined”
    Pls let me know on this?

    Reply

    • Denis Stadler

      |

      You need to enable jQuery to your site collection. Just check one more time this updated post…

      Reply

      • Pran

        |

        Thanks for the Reply.
        Before that could you pls tell me will this functionality work as sandbox solution?if no, could you please help with the code change?

        Reply

        • Denis Stadler

          |

          Yes it should work as a sandbox solution. You need to change the “Sandboxed Solution” attribute in the project properties to True, then close and re-open Visual Studio and re-compile the solution.

          Reply

          • Pran

            |

            Hi..Thanks again for response.
            I tried what u had suggested.But i am getting error as :-
            “Error 10 The deployment type “TemplateFile” of file “StadlerFeature.gif” in Project Item “Images” is not compatible with a Package in a Sandboxed Solution.”
            Similar errors for all those which we have mapped the folder.
            I guess sandbox solution doesnt support for mapped folder references.
            Let me know ur views on this! Thanks!

            Reply

  • Pontus

    |

    Great stuff. Against all odds I managed to add lightbox to my Win7 SharePoint site. Next step would be to show metadata as well and have some form of paging. Big pictures fill the screen.

    Reply

  • Leandro Monticelli

    |

    Hi, i’m doing something like you do. I create three dropdownlist and i want to get all site collection at first, all webs at second control and finally get all document library in the last control. My problem is that when i change the selected index at the dropdown the event is not throw, can you help me? i do all just like you maybe i miss some details,

    regards,

    Leandro

    Reply

    • Denis Stadler

      |

      Every Drop Down in ASP.NET has a property called AutoPostBack. Set it to true (dropdown.AutoPostBack = true;) and it should trigger the event.

      Reply

  • Ben

    |

    Hi,

    I’ve installed this solution but I have an issue, when you click on an image, the screen goes dark but no larger image is displayed, any idea what could cause this to happen?

    Reply

      • Michael

        |

        I am also experiencing Bens problem.
        Using Firefox 20.0.1 , Chrome 28.0.1500.95 does the same thing.
        Using IE9 or IE10 results in a page with thumbnail icons but no pictures.

        Reply

  • Maciej

    |

    Hi, It’s great web part. I have one question: how to re-size pictures? I have big pictures (1600×1000) and where i should correct for example to display pctures 800×600?
    Thanks for reply.

    Reply

  • Scott

    |

    I am having an issue where after I put in the webpart and choose the picture library, the pictures only show up as gray boxes, I am unable to click on them or open them. Any ideas on what I am doing wrong?

    Reply

      • Scott

        |

        I think so. I added the jQuery code that was listed in your set by step guide into my /head tag. I am not getting any error messages and the thumbnails boxes show up but just no pictures in the boxes. I have tried it both with Google Chrome and IE 9

        Reply

        • Scott

          |

          I got the jQuery code loading now, I found where my issue was. Now the thumbnails show up but when I click on them the screen goes dark but no image shows up. I tried it in both IE9 and Chrome

          Reply

          • Denis Stadler

            |

            I’ll test on my system and revert to you

            Reply

          • Sammy

            |

            I followed the steps and got the same problem. The screen just goes dark and no image is shown.

            Reply

          • Denis Stadler

            |

            Could you confirm that jQuery is deployed and working in your master page?

            Reply

  • AR

    |

    nice article…and great work.. ;)

    Reply

  • Justin

    |

    Very helpful article! Thanks for taking the time to post!

    Reply

Leave a comment

*