2011-01-18 15 views
64

"アクティブ/カレント"クラスをマスターページのメニュー項目に割り当てるための適切な解決策を見つけることを試みています。このクライアントとサーバー側のどちらを行うかについては、行が中央に分割されています。アクティブなメニュー項目 - asp.net mvc3マスターページ

真実私はJavaScriptとMVCの両方に新しいので、私は意見がありません。私はこれを "最もクリーン"かつ最も適切な方法で行うことを好むでしょう。

<li>アイテムに「アクティブ」クラスを割り当てるための次のjQueryコードがあります...唯一の問題は、「インデックス」またはデフォルトのビューメニューアイテムが常にアクティブクラスに割り当てられることです。他のメニューリンクの部分文字列です:

(default) index = localhost/ 
link 1 = localhost/home/link1 
link 2 = localhost/home/link1 

$(function() { 
var str = location.href.toLowerCase(); 
    $('#nav ul li a').each(function() { 
    if (str.indexOf(this.href.toLowerCase()) > -1) { 
    $(this).parent().attr("class","active"); //hightlight parent tab 
    } 
}); 

これを行うには良い方法がありますか?誰かが少なくとも私はクライアント側のバージョンを弾丸になるのに役立つだろうか?したがって、 "インデックス"またはデフォルトのリンクは常に "アクティブ"ですか?インデックスメソッドに偽の拡張を割り当てる方法はありますか?ベースURLの代わりにlocalhost/home/dashboardとなるように、すべてのリンクの部分文字列ではないでしょうか?

真実に、私はこのサーバーサイドを行う方法を実際には追いつかないので、jQueryを使ってクライアントサイドをやろうとしているのです。

答えて

114

カスタムHTMLヘルパーは通常、細かい仕事をしていません:

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 = "current" 
      }); 
    } 
    return htmlHelper.ActionLink(linkText, actionName, controllerName); 
} 

とあなたのマスターページで:

<ul> 
    <li>@Html.MenuLink("Link 1", "link1", "Home")</li> 
    <li>@Html.MenuLink("Link 2", "link2", "Home")</li> 
</ul> 

残っているのは.current CSSクラスです。

+27

注目すべき価値htmlHelper.ActionLink()には "using System.Web.Mvc.Html;"が必要です – 4imble

+1

素晴らしい作品+1 – 4imble

+5

MVC3でRazorを使用する場合は、ビューに@を追加するだけで、これを行うことができます。 – Duncan

-1

私が通常行っていることは、パスパーツに基づくbodyタグにクラスを割り当てることです。それで、あなたがString.Replaceを行うと、/ blogs/posts/1をclass = "blogs posts 1"にすることができます。

次に、それを処理するCSSルールを割り当てることができます。あなたは「ブログ」のメニュー項目を持っている場合たとえば、あなただけの

BODY.blogs li.blogs { /* your style */} 

のような規則を行うことができますかどうかは、特定のスタイルをしたい場合は、あなたのポストあなたはブログのルートにしている場合のみ、副上ページ

BODY.blogs.posts li.blogs {/* your style */} 
+1

は...のクラスを作成する必要がありますすべての単一のメニュー項目、それはありませんか? – Michael

4

これは私のこの問題の解決方法です。

私はHtmlHelpersクラスの拡張メソッド、次の作成:

public static class HtmlHelpers 
{ 
    public static string SetMenuItemClass(this HtmlHelper helper, string actionName) 
    { 
     if (actionName == helper.ViewContext.RouteData.Values["action"].ToString()) 
      return "menu_on"; 
     else 
      return "menu_off"; 
    } 

をそれから私は私のmenublockを持っています。

<div id="MenuBlock"> 
    <div class="@Html.SetMenuItemClass("About")"> 
     <a>@Html.ActionLink("About", "About", "Home")</a></div> 
    <img height="31" width="2" class="line" alt="|" src="@Url.Content("~/Content/theme/images/menu_line.gif")"/> 
    <div class="@Html.SetMenuItemClass("Prices")"> 
     <a>@Html.ActionLink("Prices", "Prices", "Home")</a></div> 
</div> 

私のメソッドは、ホームコントローラの現在の動作に従ってクラス名を各divに返します。 同じ名前で異なるコントローラーのアクションがある場合、深刻になり、メソッドに1つのパラメーターを追加して、問題を回避するコントローラーの名前を指定することができます。

5
エリアの

のサポートが追加されました:jQueryの経由

public static class MenuExtensions 
{ 
    public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper, string text, string action, string controller, string area = null) 
    { 

     var li = new TagBuilder("li"); 
     var routeData = htmlHelper.ViewContext.RouteData; 

     var currentAction = routeData.GetRequiredString("action"); 
     var currentController = routeData.GetRequiredString("controller"); 
     var currentArea = routeData.DataTokens["area"] as string; 

     if (string.Equals(currentAction, action, StringComparison.OrdinalIgnoreCase) && 
      string.Equals(currentController, controller, StringComparison.OrdinalIgnoreCase) && 
      string.Equals(currentArea, area, StringComparison.OrdinalIgnoreCase)) 
     { 
      li.AddCssClass("active"); 
     } 
     li.InnerHtml = htmlHelper.ActionLink(text, action, controller, new {area}, null).ToHtmlString(); 
     return MvcHtmlString.Create(li.ToString()); 
    } 
} 
2

uは次のように行うことができます。

$(document).ready(function() { 
    highlightActiveMenuItem(); 
}); 

highlightActiveMenuItem = function() { 
    var url = window.location.pathname; 
    $('.menu a[href="' + url + '"]').addClass('active_menu_item'); 
}; 

.active_menu_item { 
    color: #000 !important; 
    font-weight: bold !important; 
} 

オリジナル:このソリューションに夢中ではないhttp://www.paulund.co.uk/use-jquery-to-highlight-active-menu-item

関連する問題