Jan 25, 2013

Responsive ASP.NET Menu Control With Twitter Bootstrap

In this tutorial, We will implement collapsing responsive navigation bar using ASP.NET menu control and Twitter Bootstrap. Lets start with the default view of ASP.NET Menu control as follows:


 <asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false"                   IncludeStyleBlock="false" Orientation="Horizontal">
                    <Items>
                        <asp:MenuItem Text="Home" ToolTip="Home">  </asp:MenuItem>
                            <asp:MenuItem Text="Music" ToolTip="Music">
                                <asp:MenuItem Text="Classical" ToolTip="Classical" />
                                <asp:MenuItem Text="Rock" ToolTip="Rock" />
                                <asp:MenuItem Text="Jazz" ToolTip="Jazz" />
                            </asp:MenuItem>
                            <asp:MenuItem Text="Movies" ToolTip="Movies">
                                <asp:MenuItem Text="Action" ToolTip="Action" />
                                <asp:MenuItem Text="Drama" ToolTip="Drama" />
                                <asp:MenuItem Text="Musical" ToolTip="Musical" />
                            </asp:MenuItem>
                      
                    </Items>
                </asp:Menu>
responsive menu

1. We will update the default UI using bootstrap framework as in above image. To install Bootstrap, run the following command in the Package Manager Console:

Install-Package Twitter.Bootstrap

2. Add bootstrap CSS files in the page


	<link href="Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <link href="Content/bootstrap-responsive.min.css" rel="stylesheet" type="text/css" />
    <style type="text/css">
        .nav
        {
            width:100%;
            padding-left:15px;
        }

    </style> 

3. I like fixed top navigation bar, so we assign "navbar navbar-fixed-top" to menu control css class.

CssClass="navbar navbar-fixed-top"

4. For list, use nav class to list

StaticMenuStyle-CssClass= "nav"

5. For active item, use activeclass

StaticSelectedStyle-CssClass="active"

6. To display sub-menu as dynamic dropdown, we use dropdown-menu class

DynamicMenuStyle-CssClass="dropdown-menu"

Now we get the layout as in the top image and the code looks as follows


  <asp:Menu ID="NavigationMenu" runat="server"  EnableViewState="false"  
            IncludeStyleBlock="false" Orientation="Horizontal" 
            CssClass="navbar navbar-fixed-top" 
            StaticMenuStyle-CssClass= "nav" 
            StaticSelectedStyle-CssClass="active"
            DynamicMenuStyle-CssClass="dropdown-menu" 
             >
            <Items>
              <!-- menu items -->    
            </Items>
        </asp:Menu>
 

Responsive Menu:

For background image and proper layout we put the menu in div (navbar > navbar-inner > container).

To implement a collapsing responsive navbar, wrap your navbar content in a containing div, .nav-collapse.collapse, and add the navbar toggle button, .btn-navbar.


        <div class="navbar">
            <div class="navbar-inner">
                <div class="container">
				 <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
                    <a class="btn btn-navbar" data-target=".nav-collapse" data-toggle="collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </a>
				<!-- Everything you want hidden at 940px or less, place within here -->
                    <div class="nav-collapse collapse">
                        <asp:Menu ID="NavigationMenu" runat="server" EnableViewState="false"
                            IncludeStyleBlock="false" Orientation="Horizontal"
                            CssClass="navbar navbar-fixed-top"
                            StaticMenuStyle-CssClass="nav"
                            StaticSelectedStyle-CssClass="active"
                            DynamicMenuStyle-CssClass="dropdown-menu">
                            <Items>
                                <asp:MenuItem Text="Home" ToolTip="Home"></asp:MenuItem>
                                <asp:MenuItem Text="Music" ToolTip="Music">
                                    <asp:MenuItem Text="Classical" ToolTip="Classical" />
                                    <asp:MenuItem Text="Rock" ToolTip="Rock" />
                                    <asp:MenuItem Text="Jazz" ToolTip="Jazz" />
                                </asp:MenuItem>
                                <asp:MenuItem Text="Movies" ToolTip="Movies">
                                    <asp:MenuItem Text="Action" ToolTip="Action" />
                                    <asp:MenuItem Text="Drama" ToolTip="Drama" />
                                    <asp:MenuItem Text="Musical" ToolTip="Musical" />
                                </asp:MenuItem>
                            </Items>
                        </asp:Menu>
                    </div>
                </div>
            </div>
        </div>


ASP.NET Menu creates its own styles and classes which creates problem in Bootstrap working. So we remove some styles using jQuery.


 $(".nav li,.nav li a,.nav li ul").removeAttr('style'); 
 

To add down arrow for sub-menu indication:


 $(".dropdown-menu").parent().removeClass().addClass('dropdown');
 $(".dropdown>a").removeClass().addClass('dropdown-toggle').append('<b class="caret"></b>').attr('data-toggle', 'dropdown');

There is no mouseover event for mobile and onclick of ASP.NET menu causes postback. To avoid postback and remove click handler:


            $('.dropdown-toggle').attr('onclick', '').off('click');

Now on clicking parent menu item, sub menu will be displayed.

Here is the overall script structure:


 <script src="Scripts/jquery-1.9.0.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(function () {
            //to fix collapse mode width issue
            $(".nav li,.nav li a,.nav li ul").removeAttr('style');

            //for dropdown menu
            $(".dropdown-menu").parent().removeClass().addClass('dropdown');
            $(".dropdown>a").removeClass().addClass('dropdown-toggle').append('<b class="caret"></b>').attr('data-toggle', 'dropdown');

            //remove default click redirect effect           
            $('.dropdown-toggle').attr('onclick', '').off('click');

        });
    </script>
    <script src="Scripts/bootstrap.min.js" type="text/javascript"></script>
responsive menu

Hope, you enjoy it.