+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

How to create lightbox gallery in a custom module

by Zheyna Peleva
We have received a request for the ability to create a lightbox type of gallery with images from a custom module. This blog post will show you how to achieve this. There are two possible approaches. Both of them require mapping the template of the dynamic module widget. This is done by creating an .ascx file and setting it in the TemplatePath property of the designer of the widget (you need to replace the list template, so you should choose the TemplatePath for DynamicContentMasterView). Then copy the template from the widget and paste it in the ascx file. Now, the benefit of this is that you can use the code-behind of the ascx file.
  1.  First approach:
  2. You subscribe to the ItemDatabound event of the radListView. Here's the ascx file:
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ImageModule.ascx.cs" Inherits="SitefinityWebApp.ImageModule" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.ContentUI" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.Comments" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.Fields" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.ContentUI" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit" Assembly="Telerik.Sitefinity" %>
      
    <sf:ResourceLinks ID="resourcesLinks" runat="server">
        <sf:ResourceFile JavaScriptLibrary="JQuery" />
        <sf:ResourceFile JavaScriptLibrary="JQueryFancyBox" />
    </sf:ResourceLinks>
    <telerik:RadListView ID="dynamicContentListView" ItemPlaceholderID="ItemsContainer" runat="server" EnableEmbeddedSkins="false" EnableEmbeddedBaseStylesheet="false" OnItemDataBound="dynamicContentListView_ItemDataBound">
        <LayoutTemplate>
            <ul class="sfitemsList sfitemsListTitleDateTmb">
                <asp:PlaceHolder ID="ItemsContainer" runat="server" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
            <li class="sfitem sfClearfix">
                <sf:ImageAssetsField ID="ImageAssetsField1" runat="server" DataFieldName="ImageFIeld1" IsThumbnail="True" />
                <asp:HyperLink ID="HyperLink1" runat="server" CssClass="LightBox">
                    <asp:Image ID="Image1" runat="server"></asp:Image>
                </asp:HyperLink>
                <h2 class="sfitemTitle">
                    <sf:DetailsViewHyperLink ID="DetailsViewHyperLink" TextDataField="Title" runat="server" />
                </h2>
                <sf:FieldListView ID="PublicationDate" runat="server" Format="{PublicationDate.ToLocal():MMM d, yyyy, HH:mm tt}" WrapperTagName="div" WrapperTagCssClass="sfitemPublicationDate" />
                <%--<a href="<%# GetImageUrl("ImageFIeld1") %>">
                    <img src="<%# GetImageUrl("ImageFIeld1") %>" />
      
                </a>--%>
            </li>
        </ItemTemplate>
    </telerik:RadListView>
    <sf:Pager ID="pager" runat="server"></sf:Pager>
    <asp:PlaceHolder ID="socialOptionsContainer" runat="server"></asp:PlaceHolder>
    Notice the highlighted part, which consists of a hyperlink and an asp image control (to fulfill the FancyBox requirement to have an anchor and a nested image). In the code-behind we get the control with FindControl. Then we get the dataItem of the RadListView. Since the RadTreeView control is bound to dynamic module items, the dataitem, which is accessed on ItemDataBound is actually a DynamicContent item. This item has a custom field from type media (your image items), which actually is represented by an AssetsField control. This control ensures the link between the item and the image/s, which is/are set to this item. This is done by content links, which keep information about the parent (the item) and the child (the image, set to the item). What we do is, we get the image from the content link (the image is the child item, so we pass the ChildItemId to LibraryManager to retrieve it - we practically pass the id of the image to the library manager. The manager on the other hand returns the image and we have access to all its properties. The one that we need is the Media URL, which will later pass to the HyperLink control and the asp Image control. As a result you have the following markup on the front-end:
    <a href="#">
            <img src="#"/>
     </a>
    All you need now is to add a class to all anchor attributes and call the FancyBox function with a code, similar to this:
    <script type="text/javascript">
        $(document).ready(function() {
            $("a.lightBox").fancybox();
        })
    </script>
    Here's the code-behind of the template: 
    protected void dynamicContentListView_ItemDataBound(object sender, Telerik.Web.UI.RadListViewItemEventArgs e)
           {
               //Type dynamicmoduleitemType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.MyImages.Myimages");
               RadListViewDataItem item = (RadListViewDataItem)e.Item;
               var dataItem = item.DataItem as DynamicContent;
               if (e.Item.ItemType == RadListViewItemType.DataItem || e.Item.ItemType == RadListViewItemType.AlternatingItem)
               {
                   var imageControl = e.Item.FindControl("Image1") as System.Web.UI.WebControls.Image;
                   var link = e.Item.FindControl("HyperLink1") as HyperLink;
                   if (imageControl != null && link != null)
                   {
      
                       ContentLink[] contentLinks = (ContentLink[])dataItem.GetValue("ImageFIeld1");
                       ContentLink imageContentLink = contentLinks.FirstOrDefault();
                       LibrariesManager libraryManager = LibrariesManager.GetManager();
                       var image = libraryManager.GetImage(imageContentLink.ChildItemId);
                       imageControl.ImageUrl = image.MediaUrl;
                       link.NavigateUrl = image.MediaUrl;
                   }
               }
           }
  3. Second approach:
The second approach would be to create a simple method in the code behind, which will practically do the same thing as we did above. The only difference is that we will call this method with Eval directly on the template. I personally recommend the first approach, because it is better for the performance of the page. It won't make calls to the database on each execution of the method. However, here's the method in the code-behind:
public string GetImageUrl(string propertyName)
       {
           var contentLinks = Eval(propertyName) as ContentLink[];
           var imageContentLink = contentLinks.FirstOrDefault();
           var librariesManager = LibrariesManager.GetManager();
           var currentImage = librariesManager.GetImage(imageContentLink.ChildItemId);
           return currentImage.MediaUrl;
       }
On the template you need ordinary html controls - anchor and image, where in their href and src you will call the GetImageUrl method with eval, which will return the correct media url of the item:
<ItemTemplate>
        <li class="sfitem sfClearfix">
            <h2 class="sfitemTitle">
                <sf:DetailsViewHyperLink ID="DetailsViewHyperLink" TextDataField="Title" runat="server" />
            </h2>
            <sf:FieldListView ID="PublicationDate" runat="server" Format="{PublicationDate.ToLocal():MMM d, yyyy, HH:mm tt}" WrapperTagName="div" WrapperTagCssClass="sfitemPublicationDate" />
            <a href="<%# GetImageUrl("ImageFIeld1") %>">
                <img src="<%# GetImageUrl("ImageFIeld1") %>" />
  
            </a>
        </li>
    </ItemTemplate>
Then you need to add a class for FancyBox and call the fancyfox function again. For more reference:

http://fancybox.net/howto

Keep in mind that ImageFIeld1 is the name of my dynamic module field from type Media (where I store the images).

Hope you like the blog post!

Leave a comment