MVCSitemapProvider indicates current node and parent node

I would like to mark the current node and parent with the css class. I searched and found these links:

http://mvcsitemap.codeplex.com/discussions/257786 http://mvcsitemap.codeplex.com/discussions/245000

So, I changed SiteMapNodeModelList.cshtml and now the current node is highlighted. But I don’t know how I should allocate the parent node.

<ul> @foreach (var node in Model) { <li class="@(node.IsCurrentNode ? "current" : "")" >@Html.DisplayFor(m => node) @if (node.Children.Any()) { @Html.DisplayFor(m => node.Children) } </li> } </ul> 

To mark the parent node, I built an extension method that checks all immediate children (I only have 2 levels):

  public static bool IsCurrentNodeOrChild(this SiteMapNodeModel node) { if (node.IsCurrentNode) return true; return node.Children.Any(n => n.IsCurrentNode); } 

And changed MenuHelperModel.cshtml as follows:

 <ul id="menu"> @foreach (var node in Model.Nodes) { <li class="@(node.IsCurrentNodeOrChild() ? "current" : "d")" >@Html.DisplayFor(m => node) @if (node.Children.Any()) { @Html.DisplayFor(m => node.Children) } </li> } </ul> 

Now it works fine. But is there really no simpler approach? Can't be the first person on earth to need this?

+6
source share
3 answers

You may well be the first person on Earth who needs it. Again, I suspect there are dozens of libraries of useful methods that can make MvcSiteMapProvider more useful.

MvcSiteMapProvider - open source collaboration. If you notice something like this that can be useful for a large number of people, we will be grateful for contributing to the pull @ GitHub request in the dev branch . This idea will make a very good contribution. I suggest adding a method directly to the SiteMapNodeModel object.

+3
source

This is really great, but when I continue to create extensions for this and that, I used a different approach, but I should note that it is based on your idea: D

MainMenu.cshtml:

 @model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel @using MvcSiteMapProvider.Web.Html.Models @foreach (var node in Model.Nodes) { <li @((node.IsCurrentNode || node.Children.Any(n => n.IsCurrentNode)) ? "class=active" : "")>@Html.DisplayFor(m => node)</li> } 

and paste this in

_Layout.cshtml

 @Html.MvcSiteMap().Menu("MainMenu") 

It basically does the same thing, a little cleaner (in my opinion)

+5
source

This is a great post!

while I disagree with the comment from another poster, this page was what I was looking for. My client got lost in large menus with submenus of submenus ... until I am a fan of this, this is what they wanted.

I would like to improve what Theodore suggested. instead of using node. Children, use node.Descendants. thus, if you are in the 2nd sublist, it is still displayed at the top!

 @model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel @using System.Web.Mvc.Html @using MvcSiteMapProvider.Web.Html.Models @helper TopMenu(List<SiteMapNodeModel> nodeList) { <nav class="navbar navbar-default" role="navigation"> <div class="container-fluid"> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav"> @foreach (SiteMapNodeModel node in nodeList) { string url = node.IsClickable ? node.Url : "#"; if (!node.Children.Any()) { <li class="@((node.IsCurrentNode || node.Descendants.Any(n => n.IsCurrentNode)) ? "active" : "")"><a href="@url">@node.Title</a></li> } else { <li class="dropdown @((node.IsCurrentNode || node.Descendants.Any(n => n.IsCurrentNode)) ? "active" : "")"><a class="dropdown-toggle" data-toggle="dropdown">@node.Title <span class="caret"></span></a>@DropDownMenu(node.Children)</li> } if (node != nodeList.Last()) { <li class="divider-vertical"></li> } } </ul> </div> </div> </nav> } @helper DropDownMenu(SiteMapNodeModelList nodeList) { <ul class="dropdown-menu" role="menu"> @foreach (SiteMapNodeModel node in nodeList) { if (node.Title == "Separator") { <li class="divider"></li> continue; } string url = node.IsClickable ? node.Url : "#"; if (!node.Children.Any()) { <li class="@((node.IsCurrentNode || node.Descendants.Any(n => n.IsCurrentNode)) ? "active" : "d")"><a href="@url">@node.Title</a></li> } else { <li class="dropdown-submenu @((node.IsCurrentNode || node.Descendants.Any(n => n.IsCurrentNode)) ? "active" : "d")"><a href="@url">@node.Title</a>@DropDownMenu(node.Children)</li> } } </ul> } @TopMenu(Model.Nodes) 
0
source

Source: https://habr.com/ru/post/958656/


All Articles