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.
- public static class Extention
- {
- public static TagBuilder GetNavItem(this AjaxHelper ajax, MolineSoftware.SLAudit.Navigation navItem)
- {
- MvcHtmlString htmlTemplate = null;
- if (navItem.Route == null)
- {
- htmlTemplate =
- ajax.ActionLink(navItem.LinkText, navItem.ActionName, navItem.Controller,
- new AjaxOptions
- {
- UpdateTargetId = navItem.UpdateTargetId,
- OnSuccess = navItem.OnSuccess,
- OnBegin = navItem.OnBegin
- });
- }
- else
- {
- htmlTemplate =
- ajax.ActionLink(navItem.LinkText, navItem.ActionName, navItem.Controller, navItem.Route,
- new AjaxOptions
- {
- UpdateTargetId = navItem.UpdateTargetId,
- OnSuccess = navItem.OnSuccess,
- OnBegin = navItem.OnBegin
- });
- }
- var builder = new TagBuilder("li");
- if (IsCurrentAction(ajax, navItem.ActionName, navItem.Controller))
- builder.MergeAttribute("class", "current");
- builder.InnerHtml = htmlTemplate.ToHtmlString();
- return builder;
- }
- static bool IsCurrentAction(AjaxHelper ajax, string actionName, string controllerName)
- {
- string currentControllerName = (string) ajax.ViewContext.RouteData.Values["controller"];
- string currentActionName = (string) ajax.ViewContext.RouteData.Values["action"];
- if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) &&
- currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase))
- {
- return true;
- }
- return false;
- }
- }
- }
You will notice the use of a class called Navigation (to build the actual link).
- public class Navigation
- {
- #region | Public Properties |
- /// <summary>
- /// Gets or Sets the ID
- /// </summary>
- public virtual Int32 Id { get; set; }
- /// <summary>
- /// Gets or Sets the Display for the link
- /// </summary>
- public virtual String LinkText { get; set; }
- /// <summary>
- /// Gets or Sets the ActionName.
- /// </summary>
- public virtual String ActionName { get; set; }
- /// <summary>
- /// Gets or Sets the Controller
- /// </summary>
- public virtual String Controller { get; set; }
- /// <summary>
- /// Gets or sets the Active flag.
- /// </summary>
- public virtual Boolean Active { get; set; }
- /// <summary>
- /// Gets or sets the JavaScript function to call after the page is successfully updated.
- /// </summary>
- public virtual String OnSuccess { get; set; }
- /// <summary>
- /// Gets or sets the name of the JavaScript function to call immediately before the page is updated.
- /// </summary>
- public virtual String OnBegin { get; set; }
- /// <summary>
- /// Gets or sets the ID of the DOM element to update by using the response from the server.
- /// </summary>
- public virtual String UpdateTargetId { get; set; }
- /// <summary>
- /// Gets or Sets the <see cref="RouteValueDictionary"/>
- /// </summary>
- public virtual object Route { get; set; }
- #endregion
- }
We can then create a collection of these navigation items…
- namespace MolineSoftware.SLAudit
- {
- public class NavigationList : List<Navigation>
- {
- #region | Constructor |
- #endregion
- ///Returns a NavigationList of items ** TESTING ONLY
- public NavigationList GetTestList()
- {
- NavigationList list = new NavigationList();
- list.Add(new Navigation
- {
- Active = true,
- Controller = "Home",
- OnBegin = "SetLoading",
- OnSuccess = "handleUpdate",
- Id = 1,
- LinkText = "Home",
- ActionName = "Index",
- UpdateTargetId = "output-data",
- Route = new {serverName = "MyServer"} //Example setting the route object
- });
- list.Add(new Navigation
- {
- Active = true,
- Controller = "Home",
- OnBegin = "SetLoading",
- OnSuccess = "handleUpdate",
- Id = 2,
- LinkText = "About",
- ActionName = "About",
- UpdateTargetId = "output-data"
- });
- return list;
- }
- }
Finally we can use this code (assuming model is an instance of our NavigationList class) to render the menu.
- <% foreach (var menu in Model as MolineSoftware.SLAudit.NavigationList) { %>
- <%= Ajax.GetNavItem(menu)%>
- <% } %>
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 |
Hi,
Perhaps this will help…
http://weblogs.asp.net/chrisri/archive/2007/02/02/demystifying-sys-is-undefined.aspx
Comment by telldontask — January 6, 2011 @ 8:24 am |
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 |