Making expandable NewsView control with jQuery

October 24, 2008 Digital Experience

Recently, we’ve seen a lot of people asking how to implement a NewsView control that would behave as a ExpandableList. After a short deliberation, jQuery came as a most natural solution. In this post I will explain how to modify current List & Page mode of the News View control to make it behave as an expandable list, but in one of the coming posts we’ll take it a step further and see how can we add a brand new PresentationMode to NewsView control.

The basic idea

The basic idea is to have NewsView control initially display only titles. When user clicks on a title, summary and the rest of information (including the link to the full story) should appear under it. You can see how the final results should look like in the Figure 1.


Figure 1: NewsView control with everything collapsed except news title. When news title is clicked date, summary and full story link expands

Implementation

First, download the sample project that comes with post from here. Copy the Scripts folder from the project to the root of your website. Scripts folder contains only one file – jQuery.js file which is jQuery framework.

Now that you have jQuery on your site, open following template:

~/Sitefinity/ControlTemplates/News/Modes/ListPageMaster.ascx

This is the template for the NewsView control when in List & Page presentation mode and in Master behavior mode. Once you’ve opened the file, the first thing we need to do is to reference the jQuery framework. We can do that with a helper JsLinkFile control. Please paste this code at the beginning of the template (after the registration statements):

<sf:JsFileLink ID="jQueryLink" runat="server" FileName="~/Scripts/jquery.js" /> 

The next thing we need to do is wrap all the controls (except the title) in the repeater ItemTemplate in a wrapper control, so that we can reference them all at once when hiding or showing them. We will do so by wrapping them in a div. We’ll also make div invisible by default. The modified ItemTemplate of the repeater should look like this:

<ItemTemplate> 
        <li> 
            <h2 class="sf_newsTitle">  
                <asp:HyperLink ID="fullContent1" runat="server">  
                    <asp:Literal ID="Title" runat="server"></asp:Literal> 
                </asp:HyperLink> 
            </h2> 
            <div style="display:none;">  
                <class="sf_newsDate">  
                    <asp:Literal ID="Publication_Date" runat="server" Text="{0}" /> 
                </p> 
                <p> 
                    <asp:Literal ID="Summary" runat="server" Text=""></asp:Literal> 
                </p> 
                <class="sf_readMore">  
                    <asp:HyperLink ID="fullContent2" runat="server">  
                        <asp:Literal ID="LiteralFS" runat="server" Text="<%$Resources:FullStory %>"></asp:Literal> 
                    </asp:HyperLink> 
                </p> 
                <asp:PlaceHolder ID="ThumbnailHolder" runat="server">  
                    <class="sf_newsThumbnail">  
                        <asp:Image ID="Thumbnail" runat="server" /></p>  
                </asp:PlaceHolder> 
                <class="sf_newsAuthor">  
                    <asp:Literal ID="Author" runat="server"></asp:Literal> 
                </p> 
                <p> 
                    <asp:Literal ID="Source" runat="server"></asp:Literal> 
                </p> 
                <class="sf_postCategory">  
                    <asp:HyperLink ID="Category" runat="server" /> 
                </p> 
                <class="sf_postTags">  
                    <asp:Repeater ID="Tags" runat="server">  
                        <ItemTemplate> 
                            <asp:HyperLink ID="tagLink" runat="server" /> 
                        </ItemTemplate> 
                    </asp:Repeater> 
                </p> 
            </div> 
        </li> 
    </ItemTemplate> 
 

Now that we have set the stage, it’s time for some jQuery magic. The last step is to attach an event to sf_newsTitle header to toggle the wrapper div when clicked. This we will do by simply placing following javascript in the template:

<script type="text/javascript">  
 
$(document).ready(function(){  
   $(".sf_newsTitle").click(function(event){  
     event.preventDefault();  
     $(this).next().toggle("slow");  
    });  
 });  
 
</script>  
 

The given javascript does following:
  • Waits to execute the code until page is ready
  • Once page is ready it attaches the onclick event handler to all elements with class “sf_newsTitle”
  • The click event handler slowly toggles (hides if visible, shows if hidden) the first sibling element of the element that was clicked
And that’s it. Save the template and give your NewsView control a spin.

In case you are unsure how the ListPageMaster.ascx template should look like you can find the final version of it in the project accompanying this post.

The Progress Team