开发者

ASP.net MVC - Navigation and highlighting the "current" link

When you create a new MVC project it creates a Site.master with the following markup:

<div id="menucontainer">
    <ul id="menu">
        <li><%: Html.ActionLink("Home", "Index", "Home")%></li>
        <li><%: Html.ActionLink("About", "About", "Home")%></li>
    </ul>
&开发者_如何学Golt;/div>

I would like to put code in here that will highlight the current link if I am on that page.

If I add another link such as:

<li><%: Html.ActionLink("Products", "Index", "Products")%></li>

I would want the Products link to be active (using a css class like .active) if I'm on any action in the Products controller.

The About link should be active if I'm on the HomeController About action. The Home link should be active if I'm on the Index action of the HomeController.

What is the best way to do this in MVC?


Check out this blog post

It shows how to create an HTML Extension that you call instead of the usual Html.ActionLink The extension then appends class="selected" to the list item that is currently active.

You can then put whatever formatting/highlighting you want in your CSS

EDIT

Just adding some code to rather than just a link.

public static class HtmlHelpers
{

    public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper,
                                        string linkText,
                                        string actionName,
                                        string controllerName
                                        )
    {

        string currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
        string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");

        if (actionName == currentAction && controllerName == currentController)
        {
            return htmlHelper.ActionLink(linkText, actionName, controllerName, null, new { @class = "selected" });
        }

        return htmlHelper.ActionLink(linkText, actionName, controllerName);


    }
} 

Now you need to define your selected class in your CSS and then in your views add a using statement at the top.

@using ProjectNamespace.HtmlHelpers

And use the MenuLink instead of ActionLink

@Html.MenuLink("Your Menu Item", "Action", "Controller")


You could do this by using "data-" attributes to identify the container(s) then using jQuery change CSS class of the link, like the following:

<div class="..." data-navigation="true">
                    <ul class="...">
                        <li>@Html.ActionLink("About", "About", "Home")</li>
                        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                    </ul>
</div>

<script>
    $(function () {
        $("div[data-navigation='true']").find("li").children("a").each(function () {
            if ($(this).attr("href") === window.location.pathname) {
                $(this).parent().addClass("active");
            }
        });
    });
</script>


Here is a way to implement this as an MVC helper:

@helper NavigationLink(string linkText, string actionName, string controllerName)
{
    if(ViewContext.RouteData.GetRequiredString("action").Equals(actionName, StringComparison.OrdinalIgnoreCase) &&
       ViewContext.RouteData.GetRequiredString("controller").Equals(controllerName, StringComparison.OrdinalIgnoreCase))
    {
        <span>@linkText</span>
    }
    else
    {
        @Html.ActionLink(linkText, actionName, controllerName);
    }
}

It can then be used similar to the following:

@NavigationLink("Home", "index", "home")
@NavigationLink("About Us", "about", "home")

A good article on MVC helpers can be found here: http://weblogs.asp.net/scottgu/archive/2011/05/12/asp-net-mvc-3-and-the-helper-syntax-within-razor.aspx


I Used this approach with a htmlhelper for the problem:

public static class HtmlHelpers
{
    public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper,
                                            string linkText,
                                            string actionName,
                                            string controllerName
                                        )
    {

        string currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
        string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");

        if (actionName.Equals(currentAction, StringComparison.InvariantCultureIgnoreCase) && controllerName.Equals(currentController, StringComparison.InvariantCultureIgnoreCase))
        {
            return htmlHelper.ActionLink(linkText, actionName, controllerName, null, new { @class = "active" });
        }

        return htmlHelper.ActionLink(linkText, actionName, controllerName);

    }
}

and for the view

@Html.MenuLink"Linktext", "action", "controller")


You might like to check out my series of MVC navigation controls, which includes the ability to automatically highlight the current link:

http://mvcquicknav.apphb.com/


Thanks to @codingbadger for the solution.

I had to get my nav-links highlighted on multiple actions so I decided to add a few more parameters that contain the controller-action pairs and it'll highlight the link if either of those combinations is accessed too. And, in my case, the highlighting class was to be applied to a <li> element.

I'm putting my code here hoping it will help someone in the future:

  • Here's the helper method:

    /// <summary>
    /// The link will be highlighted when it is used to redirect and also be highlighted when any action-controller pair is used specified in the otherActions parameter.
    /// </summary>
    /// <param name="selectedClass">The CSS class that will be applied to the selected link</param>
    /// <param name="otherActions">A list of tuples containing pairs of Action Name and Controller Name respectively</param>
    public static MvcHtmlString NavLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string parentElement, string selectedClass, IEnumerable<Tuple<string, string>> otherActions)
    {
        string currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
        string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
    
        if ((actionName == currentAction && controllerName == currentController) || 
            (otherActions != null && otherActions.Any(pair => pair.Item1 == currentAction && pair.Item2 == currentController)))
        {
            return new MvcHtmlString($"<{parentElement} class=\"{selectedClass}\">{htmlHelper.ActionLink(linkText, actionName, controllerName)}</{parentElement}>");
        }
    
        return new MvcHtmlString($"<{parentElement}>{htmlHelper.ActionLink(linkText, actionName, controllerName)}</{parentElement}>");
    }
    
  • And, here's an example of how to use it:

<ul>
  @Html.NavLink("Check your eligibility", "CheckEligibility", "Eligibility", "li", "current-page", new Tuple<string, string>[]
   {
       new Tuple<string, string>("Index", "Eligibility"),
       new Tuple<string, string>("RecheckEligibility", "Eligibility")
   })
   @Html.NavLink("Apply for my loan", "Apply", "Loan", "li", "current-page")
</ul>


First Make a Helper Class and HTML Helper method

 public static string IsActive(this HtmlHelper html,string control,string action)
    {
        var routeData = html.ViewContext.RouteData;

        var routeAction = (string)routeData.Values["action"];
        var routeControl = (string)routeData.Values["controller"];

        // both must match
        var returnActive = control == routeControl &&
                           action == routeAction;

        return returnActive ? "active" : "";
    }

And in View or Layour Section Just Call the Helper Method with appropriate Conntroller and Action.

  @using YourNamespace.HtmlHelpermethodName

 <a class="nav-link @Html.IsActive("Dashboard","Index")" href="@Url.Action("Index","Dashboard")">

this will add "active" string in class attribute and it will show like

 <a class="nav-link active" href="@Url.Action("Index","Dashboard")">


public ActionResult SignIn(User user)
{
    User u = db.Users.Where(p=>p.Email == user.Email & p.Password == user.Password).FirstOrDefault();
    if (u == null)
    {
       return View();
    }
    var id = u.Id;
    Session["id_user"] = id;

    return RedirectToAction("Index", "Home");
}


<div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
                <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                <li>@Html.ActionLink("Products", "Index", "Products")</li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Archivo<b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li>@Html.ActionLink("Document Type", "Index", "DocumentTypes")</li>
                        <li>@Html.ActionLink("Employee", "Index", "Employees")</li>
                        <li>@Html.ActionLink("Suppliers", "Index", "Suppliers")</li>
                    </ul>
                </li>    
            </ul>
            @Html.Partial("_LoginPartial")
        </div>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜