2012-05-10 27 views
4

で私は_Layout.cshtmlでこのメニューがあります:アクションリンクの1つをクリックするとどのように動的に設定するスタイルのリスト項目で_Layout.cshtml

<td class="MenuStructure"> 
    <ul id="menu"> 
     <li>@Html.ActionLink("First Page", "Page1Action", "Main")</li> 
     <li>@Html.ActionLink("Second Page", "Page2Action", "Main")</li> 
     <li>@Html.ActionLink("Third Page", "Page3Action", "Second")</li> 
    </ul> 
</td> 

を、私は<のクラスを設定したいです"選択された"とそれ以外のクラスのクラスを含む "li>"要素を ""に追加します。

これは動作します:

<script type="text/javascript"> 
     $(document).ready(function() { 
     var selMenu = '@ViewBag.SelectedMenu'; 
      if (selMenu == "page1") { 
       $("#page1").attr('class', 'selected'); 
       $("#page2").attr('class', ''); 
       $("#page3").attr('class', ''); 
      } 
      if (selMenu == "page2") { 
       $("#page1").attr('class', ''); 
       $("#page2").attr('class', 'selected'); 
       $("#page3").attr('class', ''); 
      } 
     }); 
    </script> 

が、それはひどく醜いです。誰かが私にこれを行うよりエレガントな方法を示すことができますか?

答えて

2

a要素のグループにクリックイベントハンドラを追加すると、クリックした要素のliにクラスを簡単に追加して、いくつの兄弟に関係なくすべての兄弟に対してそのクラスを削除できます。これにより、if文が不要になり、liごとにattrが更新されなくなります。

http://jsfiddle.net/JjBgm/4/

マークアップ:

<ul id="menu"> 
    <li><a href="#">one</a></li> 
    <li><a href="#">two</a></li> 
    <li><a href="#">three</a></li> 
</ul> 

のjQuery:

がここにサンプルの

$(document).ready(function() { 

    $('#menu li a').click(function() { 
     $(this).parent().addClass('selected').siblings().removeClass('selected'); 
    }); 

}); 

あなたは明らかにMVCであなたのニーズに、このアプローチを変更する必要があると思います、概念は機能するはずです。

編集:上記のようなサーバーへの往復があると述べたので、上記はうまく動作しない可能性があります。その場合は、選択したメニューに基づいてclientside idを作成し、そこでクラスを制御することができます。

$(document).ready(function() { 
    var selMenu = '@ViewBag.SelectedMenu'; 
    $("#" + selMenu).addClass('selected').siblings().removeClass('selected'); 
}); 

これは、サーバーの処理後に結果のマークアップを見ることなく<li>要素を参照するなど、#page2#page1を想定しています。 #page1<a>タグを参照している場合

、その後、あなたの文は次のようになります。当然の

$("#" + selMenu).parent().addClass('selected').siblings().removeClass('selected'); 

未テスト。メインポイントはセレクタを動的に構築し、必要に応じて兄弟と親セレクタを使用してクラスをクリアします。はるかにクリーンです。

+0

私のli要素内の@ Html.ActionLinkがあればわからない(ポストバックが発生しますこれはMVC3の正しい用語です)、これはうまくいきますが、ページがリフレッシュされる前の短い瞬間に限り、 "選択された"クラスがなくなりました。 – KennyZ

+0

@KennyZああ、はい、往復を考慮しなかった...私は更新する –

+0

ありがとう!私はそのコードをチェックするともっと気分が良くなる! – KennyZ

0

これはサイトの主なナビゲーションであり、正確な行動をしていなくてもトップメニューを「選択」したままにしておくことを前提としています(リンクはリストに表示されますが、 「編集」ページなど)。

これには2通りの方法があります。 1つは、ビューバックにプロパティを配置し、レンダリング時に_layout.cshtmlファイルでそのプロパティを確認することです。

// in controller Action method 
ViewBag.SelectedMenu = "first" 
// in view 
<li class="@((ViewBag.SelectedMenu == "first") ? "selected-class" : "")">first link</li> 

第二の方法は、(我々が使用していること)(NuGetからインストール)Sitemapパッケージを使用することです。次に、ルート内のサイトマップファイルを編集し、すべてのリンクをそこに配置します(ナビゲーションに直接使用しない場合も同様です)。次に、コントロールを<ul><li>'sのためにレンダリングします。それはあなたが現在持っているのと同じhtmlを出しているので、CSSはまだ動作するはずです。

  • サイトマップは[許可する]属性、または他のフィルタを尊重し、一箇所ですべてのメニューのものは、ログイン中に隠れのみ
  • は(/実際には存在しない可能性がありますメニューのショーのノードを非表示にすることができますリンクします再マップのURLなど)他のちょっといい機能の
  • たくさん

Mvc.sitemapファイル:

<mvcSiteMapNode title="Home" controller="Home" action="Index"> 
<mvcSiteMapNode title="Get a car" controller="Cars" action="Buy"/> 
    <mvcSiteMapNode title="Reports" controller="Report" action="AllReports"> 
     <mvcSiteMapNode title="" controller="Report" action="ViewMPG"/> 
    </mvcSiteMapNode> 
</mvcSiteMapNode> 

そして、あなたの_Layout.cshtmlファイルに:その後、

<td class="MenuStructure"> 
    <!-- one level menu starting at top (home), including the "home" link --> 
    @Html.MvcSiteMap().Menu(0, true, true, 1) 
</td> 

とスタイルを変更するにはViews\Shared\MenuHelperModel.cshtmlを変更します。

<ul id="menu"> 
    @foreach (var node in Model.Nodes) 
    { 
     var show = node.IsInCurrentPath && (!node.IsRootNode || node.IsCurrentNode); 
     var cls = show ? "selected" : ""; 
     <li class="@cls">@Html.DisplayFor(m => node)</li> 
    } 
</ul> 
+0

興味深い。しかし、サイトマップのソリューションは、選択されたliノードのクラスを設定し、それを兄弟から削除する方法をどのように扱いますか? – KennyZ

+0

申し訳ありませんが、私は1つの部分を忘れてしまった!それは非常に遅い(私のために)中国時間。私はそれを追加します。テンプレートを編集することは、それほど標準的ではなく、私の脳をノックすることさえできませんでした。しかし、少なくともViewBagのアイデアは、それを今選択された答えにしました。最終的には、各アクション(とエラー、投稿など)にViewBagプロパティが設定されていることを手動で確認するよりもサイトマップの方が望ましいと思います。私はその方法も考慮しましたが、_every_コントローラのコード行です。 –

関連する問題