Creating a Category Menu Dynamically Using the HoverMenuExtender

Saturday, September 20, 2008


When building an eCommerce website, there are a multitude of ways to display categories an subcategories that are dynamically retrieved from a database.  In this sample, I will show how to display list of categories that when you hover over the category with your mouse, a popup menu will appear with the subcategories.  To do this I am going use the AjaxControlToolKit HoverMenuExtender.


The Master Page

I am going to place this menu on my master page so it can be used by all pages related to searching for a product.  The first thing you will always need when using any of the AJAX Controls is the ScriptManager.

   16     <cc1:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">

   17     </cc1:ToolkitScriptManager>

 The next thing I need to add is the markup for the categories.

   20             <asp:Repeater ID="RepeaterCategories" runat="server" OnItemDataBound="RepeaterCategories_ItemDataBound"

   21                 DataMember="CategoryId">

   22                 <ItemTemplate>

   23                     <asp:Panel class="categoryItem" runat="server" ID="categoryPanel">

   24                         <asp:LinkButton runat="server" ID="linkCategory" Text='<%#Eval("CategoryName")%>'></asp:LinkButton>

   25                         <asp:HiddenField ID="hiddenCategory" runat="server" Value='<%#Eval("CategoryId") %>' />

   26                     </asp:Panel>

   27                     <asp:Panel class="subCategoryList" runat="server" ID="subCategoryPanel">

   28                         <asp:Repeater ID="RepeaterSubCategories" runat="server">

   29                             <ItemTemplate>

   30                                 <div class="categoryItem">

   31                                     <a href="#">

   32                                         <%#Eval("CategoryName")%>

   33                                     </a>

   34                                 </div>

   35                             </ItemTemplate>

   36                         </asp:Repeater>

   37                     </asp:Panel>

   38                     <cc1:HoverMenuExtender ID="HoverMenuExtender1" runat="server" PopupPosition="Right"

   39                         PopupControlID="subCategoryPanel" TargetControlID="linkCategory" HoverCssClass="popupHover">

   40                     </cc1:HoverMenuExtender>

   41                 </ItemTemplate>

   42             </asp:Repeater>

Here I have a repeater control which will repeat for each main category.  Inside the ItemTemplate for that control, I have two panels, one for the main category links and the other which will be the container for the subcategories.  Make sure your style for subcategory panel is defaulted to display equals none and visibility equals hidden.  This will prevent the panel from flashing when the page first loads.  Inside the panel for the subcategories I have a nested repeater which will retrieve the subcategories for each category.  To get the subcategories I will need to fire off the OnItemDataBound event on the main category repeater to make a call to the database and get the subcategories.  The subcategory link would most likely have a link to a product page.

The OnItemDataBound Event

On the OnItemDataBound event,  I need retrieve the current item being bound to the control and if the item is of the appropriate type, then pass the necessary Category Id to my middle tier to retrieve the corresponding subcategories.

   46         protected void RepeaterCategories_ItemDataBound(object sender, RepeaterItemEventArgs e)

   47         {

   48             RepeaterItem item = e.Item;


   50             if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)

   51             {

   52                 HiddenField category = item.FindControl("hiddenCategory") as HiddenField;

   53                 int catId = Convert.ToInt32( category.Value );

   54                 Repeater subcategoryControl = (Repeater)e.Item.FindControl("RepeaterSubCategories");

   55                 subcategoryControl.DataSource = presenter.OnCategoryItemBound(catId);

   56                 subcategoryControl.DataBind();


   58             }

   59         }

 In this case I am retrieving the Category ID from the hidden tag placed in the same row as the category name.

 The Result

Okay, so this is not the prettiest sample in the world, but you get the idea.  Perhaps you can jaz this up a bit with a shadow back drop and a rounded corners but the intent was just show how to make it work, and all though I did not show it, I used LINQ  behind the scenes so all in all, there was very little code to do this.



comments powered by Disqus