Monday, October 05, 2009

Customizing Asp.net menu control to use jQuery,Superfish and CSS Friendly Control Adapters

I have used Asp.net menu controls in a lot of applications earlier but now a days with so many new things and controls asp.net menu control seems to lag in many basic functionalities, there are various other options available to be used as a replacement of the asp.net menu control.

But what i loved with the asp.net menu control was its seamless integration with the sitemap datasource and with no hassle i could display whole of my site’s navigation in the menu control by just configuring them in the sitemap file.

What i disliked most was that the menu control by default is rendered as a table structure and not as div structure.

So to fight this abnormality Microsoft released CSS Friendly Control Adapters so that most of the controls which are rendered as tables can be rendered as a simple and clean div structure.

But today i was experimenting with other available options and i found a really cool Superfish jQuery plug-in which we can attach with the asp.net menu control to achieve very cool affects.

In this article i will share the steps on how to hook up the Superfish jQuery Menu plug-in into your asp.net website to beautify your asp.net menu control.

Also please check various option available with the Superfish plug-in on how it can be customized from the Superfish plug-in website.

http://users.tpg.com.au/j_birch/plugins/superfish/#examples

Now let’s look at the steps to integrate superfish menu with asp.net menu

Main JavaScript file which is required is superfish.js along with jQuery any version.js rest files are optional and are used if we use some advanced features and customizations with the superfish menu.

Main CSS file is superfish.css and for this demo we will modify this file only.

  • After downloading the superfish menu files now we should download the CSS Friendly Adapter from http://cssfriendly.codeplex.com/
  • Place the CSSFriendly.dll into your website bin folder and the CSSFriendlyAdapters.browser in your App_Browser folder.Also remember to comment out the unwanted code from the CSSFriendlyAdapters.browser file as we are dealing only with the menu.
 <controlAdapters>
      <adapter controlType="System.Web.UI.WebControls.Menu"
               adapterType="CSSFriendly.MenuAdapter" />
      <!--adapter controlType="System.Web.UI.WebControls.TreeView"
               adapterType="CSSFriendly.TreeViewAdapter" />
      <adapter controlType="System.Web.UI.WebControls.DetailsView"
               adapterType="CSSFriendly.DetailsViewAdapter" />
      <adapter controlType="System.Web.UI.WebControls.FormView"
               adapterType="CSSFriendly.FormViewAdapter" />
      <adapter controlType="System.Web.UI.WebControls.DataList"
               adapterType="CSSFriendly.DataListAdapter" />
      <adapter controlType="System.Web.UI.WebControls.GridView"
               adapterType="CSSFriendly.GridViewAdapter" />
      <adapter controlType="System.Web.UI.WebControls.ChangePassword"
               adapterType="CSSFriendly.ChangePasswordAdapter" />
      <adapter controlType="System.Web.UI.WebControls.Login"
               adapterType="CSSFriendly.LoginAdapter" />
      <adapter controlType="System.Web.UI.WebControls.LoginStatus"
               adapterType="CSSFriendly.LoginStatusAdapter" />
      <adapter controlType="System.Web.UI.WebControls.CreateUserWizard"
               adapterType="CSSFriendly.CreateUserWizardAdapter" />
      <adapter controlType="System.Web.UI.WebControls.PasswordRecovery"
               adapterType="CSSFriendly.PasswordRecoveryAdapter" /-->
    </controlAdapters>

 

  • Also download the latest version of jQuery, otherwise there is already a version of jQuery in the Superfish package.
  • Now start creating your pages and once you are done , just create a sitemap file to list your whole website.
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="" title=""  description="">
        <siteMapNode url="Default.aspx" title="Home" description=""/>
        <siteMapNode url="AboutUs.aspx" title="About Us"  description="" />
        <siteMapNode url="Services.aspx" title="Services"  description="" >
            <siteMapNode url="Services/Service1.aspx" title="Service1" description="">
                <siteMapNode url="Services/SubService1.aspx" title="SubService1" description="" />
                <siteMapNode url="Services/SubService2.aspx" title="SubService2" description="" />
                <siteMapNode url="Services/SubService3.aspx" title="SubService3" description="" />
                <siteMapNode url="Services/SubService4.aspx" title="SubService4" description="" />
            </siteMapNode>
            <siteMapNode url="Services/Service2.aspx" title="Service2" description=""/>
            <siteMapNode url="Services/Service3.aspx" title="Service3" description=""/>
            <siteMapNode url="Services/Service4.aspx" title="Service4" description=""/>
        </siteMapNode>
        <siteMapNode url="ContactUs.aspx" title="Contact Us" description=""/>
    </siteMapNode>
</siteMap>
  • After building all this your solution architecture should be like this.

  • Now just the master page configuration is left and you are ready to go then
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Default.master.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>

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

    <script type="text/javascript" src="Scripts/superfish.js"></script>

    <link type="text/css" href="~/Styles/superfish.css" rel="stylesheet" media="screen"
        runat="server" />
    <link href="Styles/stylemain.css" rel="stylesheet" type="text/css" />

    <script type="text/javascript">
        $(document).ready(function() {
            $('ul.AspNet-Menu').superfish();
        }); 
    </script>

    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
    <div id="outerWrapper">
        <div id="header">
            <div id="logo">
                <asp:HyperLink runat="server" NavigateUrl="~/Default.aspx" ID="lnkLogo">    
                </asp:HyperLink>
            </div>
        </div>
        <div id="menu">
            <asp:Menu ID="menuMain" runat="server" DataSourceID="stmpDataSource" Orientation="Horizontal">
            </asp:Menu>
            <asp:SiteMapDataSource ID="stmpDataSource" runat="server" ShowStartingNode="false" />
        </div>
        <div id="mainContent">
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
            </asp:ContentPlaceHolder>
        </div>
        <div id="footer">
        </div>
    </div>
    </form>
</body>
</html>
  • Important :- By default the Superfish menu css file contains the settings aligned with the ul name sf-menu but the asp.net menu control renders the ul element as AspNet-menu so the important step is to replace all the occurrences of sf-menu in the superfish.css with AspNet-menu to make this menu work.

        You can download the sample project and plug and play with the CSS file customized for the asp.net menu if you find difficulties in customizing by your self.

        After embedding this in your master page you are done with the settings and customization and you are ready to go, i got this menu in just 15 minutes so simple and so easy.

        Working Demo can be seen here http://www.smallworkarounds.com/demos/superfish.demo/

        Download the Demo from http://www.smallworkarounds.com/blog/democode/Superfish/Superfish.Demo.zip

        Happy Programming!!!!!!!!!!!!!!!!!!!!

        Submit this story to DotNetKicks

        del.icio.usSave Total0 users

        5 comments:

        Anonymous said...

        This is great - it works really well.
        One question:
        http://users.tpg.com.au/j_birch/plugins/superfish/#examples displays arrows in the menu.
        Why isn’t the arrows displayed in your superfish demo?

        Anonymous said...

        Anonymous -- I had the same trouble; fixed it by adding

        ul.sf-menu li span.sf-sub-indicator,
        ul.AspNet-Menu li span.sf-sub-indicator
        {
        height:30px !important;
        }

        to my CSS. So I didn't have to monkey around with the stylesheet so much, I simply added the sf-menu class to the AspNet-Menu objects:

        if (!($('ul.AspNet-Menu').hasClass('sf-menu')))
        {
        $('ul.AspNet-Menu').addClass('sf-menu');
        }
        $('ul.sf-menu').superfish();

        IAn said...

        ^ You can turn them off in the superfish.js file too:

        autoArrows : true,

        just change true to false.

        Anonymous said...

        not working in IE6!

        Anonymous said...

        Nice tutorial and thanks a millions...One simple question is what about selected menu item? how do you differentiate between selected/active menu from the rest?

        Post a Comment