Peter's Blog   

Tourism in Czech Republic and other stuff



Recently I've been asked to create a mega menu on an ASP.NET website which was using a standard ASP.NET menu control. Luckily for me I came across an article how to create a jQuery Mega Menu.

What I wanted to do is to combine the jQuery Mega Menu with standard ASP.NET menu using sitemap datasource.

Let's build a new website project from scratch so you can see clearly what you need to do to get your mega menu working with asp.net menu.

I'm going to repeat here some steps which are in the jQuery Mega Menu article

You need to download the following files and place them inside your website project.

- jkmegamenu.css - place this file in yoursite\App_Themes\Theme1\jkmegamenu.css
- jkmegamenu.js - place this file in yoursite\jscript\jkmegamenu.js
- jquery-1.3.2.min.js - place this file in yoursite\jscript\jquery-1.3.2.min.js





Step 1: Create a new master page. In the head tag you need to enter the following

<head runat="server">
<title>My Site</title>
<script type="text/javascript" src="jscript/jquery-1.3.2.min.js"></script>

<script type="text/javascript" src="jscript/jkmegamenu.js">
/***********************************************
* jQuery Mega Menu- by JavaScript Kit (www.javascriptkit.com)
* This notice must stay intact for usage
* Visit JavaScript Kit at http://www.javascriptkit.com/ for full source code
***********************************************/
</script>
</head>



Step 2: Now create a web.sitemap which will be used as our datasource for the menu.

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

<siteMapNode url="~" title="Root"  description="">
<siteMapNode url="~/Default.aspx" title="Page1"  />
<siteMapNode url="~/Default2.aspx" title="Page2" >
<siteMapNode url="~/Default2_1.aspx" title="Page2_1" >
<siteMapNode url="~/Default2_1_1.aspx" title="Page2_1_1" />
<siteMapNode url="~/Default2_1_2.aspx" title="Page2_1_2" />
<siteMapNode url="~/Default2_1_3.aspx" title="Page2_1_3" />
</siteMapNode>
<siteMapNode url="~/Default2_2.aspx" title="Page2_2" >

<siteMapNode url="~/Default2_2_1.aspx" title="Page2_2_1" />
<siteMapNode url="~/Default2_2_2.aspx" title="Page2_2_2" />
<siteMapNode url="~/Default2_2_3.aspx" title="Page2_2_3" />
<siteMapNode url="~/Default2_2_4.aspx" title="Page2_2_4" />
<siteMapNode url="~/Default2_2_5.aspx" title="Page2_2_5" />
</siteMapNode>
<siteMapNode url="~/Default2_3.aspx" title="Page2_3" >
</siteMapNode>
</siteMapNode>

<siteMapNode url="~/Default3.aspx" title="Page3" >
</siteMapNode>
<siteMapNode url="~/Default4.aspx" title="Page4" >
</siteMapNode>
</siteMapNode>
</siteMap>



Step 3: Enter the following code in the master page within the form tag. Here we have our menu bound to SiteMapDataSource. We need to generate anchors ("anchorLiteral") and also html code for our mega menus ("menuLiteral"). I set the menu to fire OnDataBound event. Inside this event we can generate all the required code.

<asp:Literal ID="anchorLiteral" runat="server"></asp:Literal>
<asp:Literal ID="menuLiteral" runat="server"></asp:Literal>
<asp:Menu ID="Menu1" runat="server" StaticDisplayLevels="1" 
MaximumDynamicDisplayLevels="2" DataSourceID="SiteMapDataSource1" 
Orientation="Horizontal" OnDataBound="Menu1_DataBound">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" 
ShowStartingNode="False" />




Step 4: Now we need to write the code behind the master page. The code loops through the menu items and generates required html code and scripts to get basic menu with mega menu dropdown.

protected void Menu1_DataBound(object sender, EventArgs e)
    {
        //hide the asp menu
        Menu1.Visible = false;
        
        //holds html anchors
        anchorLiteral.Text = "";

        //holds html mega dropdown menu
        menuLiteral.Text = "";

        //register megamenu script and create anchor foreach top level

        StringBuilder mScript = new StringBuilder();
        StringBuilder anchorText = new StringBuilder();
        StringBuilder menuText = new StringBuilder();

        mScript.AppendLine(@"<script type='text/javascript'>");
        int cntLvl1 = 0;
        
        foreach (MenuItem lvl1 in Menu1.Items)
        {
            cntLvl1++;
            string anchorId = "megaanchor" + cntLvl1.ToString();
            string megamenuId = "megamenu" + cntLvl1.ToString();

            //anchor for each top level menu
            anchorText.AppendLine("<a href='" + lvl1.NavigateUrl + "' id='" +
                anchorId + "' class='topMenuCMSListMenuLinkHighlighted'>" +
                lvl1.Text + "</a>");

            //building mega menu div if menuitem has children
            if (lvl1.ChildItems.Count > 0)
            {
                int cntLvl2 = 0;
                //script for each top level menu
                mScript.Append(@"jkmegamenu.definemenu('" + anchorId + "', '" + 
                    megamenuId + "', 'mouseover');");

                menuText.AppendLine("<div id='" + megamenuId + "' class=megamenu>");
                
                //building columns within the mega menu
                foreach (MenuItem lvl2 in lvl1.ChildItems)
                {
                    cntLvl2++;
                    menuText.AppendLine("<div class='column'>");
                    menuText.AppendLine("<h3><a href='" + lvl2.NavigateUrl + "'>" + 
                        lvl2.Text + "</a></h3>");

                    //create ul list if any children
                    if (lvl2.ChildItems.Count > 0)
                    {
                        menuText.AppendLine("<ul>");
                        foreach (MenuItem lvl3 in lvl2.ChildItems)
                        {
                            menuText.AppendLine("<li><a href='" + lvl3.NavigateUrl + "'>" + 
                                lvl3.Text + "</a></li>");
                        }
                        menuText.AppendLine("</ul>");
                    }

                    menuText.AppendLine("</div>");

                    //break after 2 columns
                    if (cntLvl2 >= 2)
                    {
                        menuText.AppendLine("<br style='clear: left' />");
                        cntLvl2 = 0;
                    }
                }
                menuText.AppendLine("</div>");
            }
        }

        anchorText.AppendLine("</ul>");

        anchorLiteral.Text = anchorText.ToString();
        menuLiteral.Text = menuText.ToString();
        mScript.AppendLine(@"</script>");
        Guid gid = System.Guid.NewGuid();

        Page.ClientScript.RegisterStartupScript(this.GetType(), gid.ToString(), mScript.ToString());

    }





Now here is the result.....





A friend of mine asked me for a help with his new website. I agreed and told him that I look into it in my spare time. I’m a .Net developer so my choice would be an open source CMS which would run on .NET platform and I wouldn’t have to spend long time learning it.
My main criteria were that the CMS should be easy to install, fast and free. This website needed a forum, a blog and polls. Also I like to stress that this is not for a corporate website but a small hobby website.
After some search on the web I ended up trying Mojoportal, DotNetNuke (DNN) and Umbraco.
Each of these products has very respectful following and of and their users have plenty of good things to say about each. So I had to dive in and do my own research which CMS would suite most.

DotNetNuke
It has been around a very long time. It is developed in VB.Net which was a bit of a drawback since I use C# but luckily for me you can develop modules in C#.
Installation was very easy and creation of my first few pages too. It performed well on my test server. Then I started to play with it more and setup a few modules - forum and blogs. The performance dropped and became rather slow.
I was reading around and there could be many factors why DNN can be slow....too many or wrong modules etc. I actually couldn’t find the right answer.
However, what I really liked about DNN is the amount of modules and skins you can buy or get for free. I think DNN is very mature product and if you have the time to learn it, it certainly will pay off.

MojoPortal
Fairly new player in the CMS field, done in C#, already plus for me and has some moderate number of followers. There are not many modules as I can see which are developed outside the main development group. However, the modules it has suited me just fine. I think the main drawback for many people when looking at MojoPortal is the look and feel – skin. The best thing would be to choose from around 40 different skins which come with the installation and then modify them.
After installing MojoPortal I felt very comfortable with it. It is really straight forward no fuss CMS. Performance was really impressive with all the all the modules I needed for the website. I also created a new module just to test how hard it is….it wasn’t.
When it comes to updating MojoPortal, it is very easy. All you need to do is to remember to copy a config file over, your own modules and skins.

Umbraco
As I read some reviews of this product I was really impressed and had to try it. So I read some docs and realized that you cannot run it on virtual directory. So you cannot just simply open the solution in your visual studio and press F5. So I setup Cassini web server and ran it from there. This is a major drawback for me since I want to have the flexibility of running the CMS from virtual directory.
Once I got it running, I started to poke around. It has very impressive user interface. Creating standard pages was easy. Then I tried to add a forum to it and I hit a wall. Someone suggested that you can setup YetAnotherForum to run with Umbraco but I just think it’s too much work unless you are setting up some serious website.
I’m sure that if you have the time to do your research and lots of learning this could be the product for you but I certainly would not recommend if you want to get a website up and running in a few days.


Conclusion
In the end it was DotNetNuke versus MojoPortal.
I Like them both but for me MojoPortal was the winner since it was the easiest to work with and it is very fast (which was a bit of a concern with DNN).



Sign in