ASP.NET MVC: Masterpage: как установить класс CSS для активного пункта меню - PullRequest
13 голосов
/ 03 июня 2009

У меня на главной странице следующее меню:

<ul id="menu" class="lavaLampBottomStyle">
    <li>
        <%= Html.ActionLink("Employees", "Index", "Employees")%></li>
    <li>
        <%= Html.ActionLink("Customer", "Details", "Account")%></li>
</ul>

Мне нужен способ установить класс css текущего активного li в значение "current".

Мое первое предположение это сделать с помощью JavaScript.

Я бы добавил что-то подобное на главной странице:

  $("#menu li a").each(){
    if($(this).attr("href") == '<%= *GET CURRENT PAGE* %>'){
       $(this).parent("li").addClass("current");
    }
  }

Это хороший подход?

Если это так, как я могу получить текущую часть URL, как в href?

Если это не так, что вы предлагаете? : -)

К вашему сведению, сгенерированный html, который я ищу:

<ul id="menu" class="lavaLampBottomStyle">
    <li>
        <a href="/KszEmployees/Index">Employees</a></li>
    <li>
        <a class="current" href="/">Customer</a></li>
</ul>

Ответы [ 5 ]

15 голосов
/ 03 июня 2009

Если вы хотите сделать все это на стороне сервера, я делал это раньше. Создайте атрибут фильтра действий:

public class PageOptionsAttribute : ActionFilterAttribute
{
    public string Title { get; set; }
    public string Section { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var controller = filterContext.Controller as ControllerBase;
        if (controller != null)
        {
            controller.SetPageSection(this.Section);
            controller.SetPageTitle(this.Title);
        }

        base.OnActionExecuting(filterContext);
    }
}

Это вызывает два метода в моем классе ControllerBase, от которых наследуются все мои контроллеры:

public class ControllerBase : Controller
{
    public void SetPageSection(string section)
    {
                    // use the section defined or the controller name if none
        ViewData["PageSection"] = section != null ? 
                        section : this.RouteData.Values["controller"].ToString();
    }

    public void SetPageTitle(string title)
    {
        ViewData["PageTitle"] = title;
    }
}

Установите заголовок и раздел страницы на методы вашего контроллера:

public class HomeController : ControllerBase
{
    [PageOptions(Title="Home Page", Section="Home")]
    public ActionResult Index()
    { }
 }

Затем я вызываю значение ViewData со своей главной страницы (это не будет мешать ViewData.Model):

<body class="<%=ViewData["PageSection"] %>">

Затем для ссылки через CSS вместо вызова .current присвойте каждому элементу навигации идентификатор и затем используйте класс body в сочетании с этим идентификатором для определения текущей страницы.

body.home #HomeNav { /* selected */  }
body.about #AboutNav { /* selected */  }
9 голосов
/ 03 июня 2009

Извлечение текущего местоположения из window.location. Затем используйте селектор, который задает значение атрибута href, чтобы выбрать только те элементы, которые соответствуют (предположительно, только один).

 var currentLocation = window.location.href;
 // probably needs to be massaged to extract just the path so that it works in dev/prod

$("#menu li a[href$="+currentLocation+"]").addClass("current");
6 голосов
/ 03 июня 2009

Это, наверное, наименее интенсивный способ сделать это. Если вы можете рассчитывать на то, что у пользователей будет включен javascript, я не вижу в этом ничего плохого и иногда делал это сам.

Request.Url - интересующий вас объект для получения текущей страницы на стороне сервера. Предложение использовать window.location.href от tvanfosson также неплохо, если вы хотите сохранить его полностью на стороне клиента.

Преимущество использования серверной части заключается в том, что Request.Url имеет легкодоступные части URL, такие как Request.Url.Host и т. Д., Чтобы помочь с вашими потребностями в обработке ссылок.

0 голосов
/ 04 декабря 2012

У меня была такая же проблема. Используя следующие ответы, мне удалось собрать решение ниже.

https://stackoverflow.com/a/4733394/280972

https://stackoverflow.com/a/5650735/280972

В HtmlHelpers.cs:

public static class HtmlHelpers
{
    public static HtmlString MenuLink(
        this HtmlHelper htmlHelper,
        string linkText,
        string actionName,
        string controllerName
    )
    {
        var currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
        var currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
        var link = htmlHelper.ActionLink(linkText, actionName, controllerName);
        var prefix = (actionName == currentAction && controllerName == currentController) ? String.Format("<li class=\"current\">") : String.Format("<li>");
        const string suffix = "</li>";
        return new HtmlString(prefix + link + suffix);
    }
}

В макете:

<ul class="nav nav-list">
    <li class="nav-header">Statistics</li>
    @Html.MenuLink("Number of logins", "Logins", "Statistics")
</ul>

Обратите внимание, что помощник MenuLink создает как тег li, так и тег a.

Отзывы об этом решении очень приветствуются!

0 голосов
/ 03 июня 2009

Это НЕ должно быть сделано с Javascript! Решение о том, на какой странице вы находитесь, является задачей кода на стороне сервера, а не поведением пользовательского интерфейса.

Имейте меню в качестве пользовательского элемента управления и передавайте ему значение, чтобы указать, какая часть меню должна быть выделена. Я фронтмен, а не разработчик .NET, но примерно так:

<yourControl:menuControl runat="server" ID="menu" selectedPage="4" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...