Tell don't ask

July 26, 2010

ASP.NET and JQuery MVC Menu Part 3 (AJAX)

Filed under: Uncategorized — telldontask @ 9:09 am
Other posts in this series:

Aaron has very kindly sent me an extension to the original code for creating a simple menu for ASP.NET MVC sites. His version employs the Microsoft AJAX library to “ajaxify” the links on the menu.

The main part of his code handles getting a List Item containing an AJAX link.

  1. public static class Extention
  2.     {
  3.         public static TagBuilder GetNavItem(this AjaxHelper ajax, MolineSoftware.SLAudit.Navigation navItem)
  4.         {
  5.             MvcHtmlString htmlTemplate = null;
  6.             if (navItem.Route == null)
  7.             {
  8.                 htmlTemplate =
  9.                     ajax.ActionLink(navItem.LinkText, navItem.ActionName, navItem.Controller,
  10.                                     new AjaxOptions
  11.                                         {
  12.                                             UpdateTargetId = navItem.UpdateTargetId,
  13.                                             OnSuccess = navItem.OnSuccess,
  14.                                             OnBegin = navItem.OnBegin
  15.                                         });
  16.             }
  17.             else
  18.             {
  19.                 htmlTemplate =
  20.                     ajax.ActionLink(navItem.LinkText, navItem.ActionName, navItem.Controller, navItem.Route,
  21.                                     new AjaxOptions
  22.                                         {
  23.                                             UpdateTargetId = navItem.UpdateTargetId,
  24.                                             OnSuccess = navItem.OnSuccess,
  25.                                             OnBegin = navItem.OnBegin
  26.                                         });
  27.             }
  28.             var builder = new TagBuilder("li");
  29.             if (IsCurrentAction(ajax, navItem.ActionName, navItem.Controller))
  30.                 builder.MergeAttribute("class", "current");
  31.             builder.InnerHtml = htmlTemplate.ToHtmlString();
  32.             return builder;
  33.         }
  34.         static bool IsCurrentAction(AjaxHelper ajax, string actionName, string controllerName)
  35.         {
  36.             string currentControllerName = (string) ajax.ViewContext.RouteData.Values["controller"];
  37.             string currentActionName = (string) ajax.ViewContext.RouteData.Values["action"];
  38.             if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) &&
  39.                 currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase))
  40.             {
  41.                 return true;
  42.             }
  43.             return false;
  44.         }
  45.     }
  46. }

You will notice the use of a class called Navigation (to build the actual link).

  1. public class Navigation
  2. {
  3.     #region | Public Properties |
  4.  
  5.     /// <summary>
  6.     /// Gets or Sets the ID
  7.     /// </summary>
  8.     public virtual Int32 Id { get; set; }
  9.  
  10.     /// <summary>
  11.     /// Gets or Sets the Display for the link
  12.     /// </summary>
  13.     public virtual String LinkText { get; set; }
  14.  
  15.     /// <summary>
  16.     /// Gets or Sets the ActionName.
  17.     /// </summary>
  18.     public virtual String ActionName { get; set; }
  19.  
  20.     /// <summary>
  21.     /// Gets or Sets the Controller
  22.     /// </summary>
  23.     public virtual String Controller { get; set; }
  24.  
  25.     /// <summary>
  26.     /// Gets or sets the Active flag.
  27.     /// </summary>
  28.     public virtual Boolean Active { get; set; }
  29.  
  30.     /// <summary>
  31.     /// Gets or sets the JavaScript function to call after the page is successfully updated.
  32.     /// </summary>
  33.     public virtual String OnSuccess { get; set; }
  34.  
  35.     /// <summary>
  36.     /// Gets or sets the name of the JavaScript function to call immediately before the page is updated.
  37.     /// </summary>
  38.     public virtual String OnBegin { get; set; }
  39.  
  40.     /// <summary>
  41.     /// Gets or sets the ID of the DOM element to update by using the response from the server.
  42.     /// </summary>
  43.     public virtual String UpdateTargetId { get; set; }
  44.  
  45.     /// <summary>
  46.     /// Gets or Sets the <see cref="RouteValueDictionary"/>
  47.     /// </summary>
  48.     public virtual object Route { get; set; }
  49.  
  50.     #endregion
  51. }

We can then create a collection of these navigation items…

  1. namespace MolineSoftware.SLAudit
  2. {
  3.     public class NavigationList : List<Navigation>
  4.     {
  5.         #region | Constructor |
  6.  
  7.         #endregion
  8.  
  9.         ///Returns a NavigationList of items ** TESTING ONLY
  10.         public NavigationList GetTestList()
  11.         {
  12.             NavigationList list = new NavigationList();
  13.  
  14.             list.Add(new Navigation
  15.                          {
  16.                              Active = true,
  17.                              Controller = "Home",
  18.                              OnBegin = "SetLoading",
  19.                              OnSuccess = "handleUpdate",
  20.                              Id = 1,
  21.                              LinkText = "Home",
  22.                              ActionName = "Index",
  23.                              UpdateTargetId = "output-data",
  24.                              Route = new {serverName = "MyServer"} //Example setting the route object
  25.                          });
  26.  
  27.  
  28.             list.Add(new Navigation
  29.                          {
  30.                              Active = true,
  31.                              Controller = "Home",
  32.                              OnBegin = "SetLoading",
  33.                              OnSuccess = "handleUpdate",
  34.                              Id = 2,
  35.                              LinkText = "About",
  36.                              ActionName = "About",
  37.                              UpdateTargetId = "output-data"
  38.                          });
  39.             return list;
  40.         }
  41.     }

Finally we can use this code (assuming model is an instance of our NavigationList class) to render the menu.

  1. <% foreach (var menu in Model as MolineSoftware.SLAudit.NavigationList) { %>
  2.     <%= Ajax.GetNavItem(menu)%>
  3. <% } %>

3 Comments »

  1. Hello! Thank you for this post. But I have a trouble with this code: when I press menu item I get a javascript error message “Error: ‘Sys’ is undefined” ( screenshot: http://yfrog.com/ngsitemenuerror2010100414j ). Could you explain how can I correct it. Thanx

    Comment by finnx — October 4, 2010 @ 11:00 am | Reply

  2. nice set of posts on menu, I would appreciate if you could help me in changing this and non ajax code with an added parameter to the action. Means the menu calls a single action but the parameters are different.

    Tx

    Comment by Arnab Choudhuri — April 30, 2011 @ 3:05 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: