| 

.NET C# Java Javascript Exception

5
Dieses "Problem" müsste eigentlich jeder kennen der schon mein eine Webseite mit mehreren Bereichen erstellt hat. Wie kann ich den Menüpunkt der aktuell angezeigten Seite hervorheben? Hier gibt es viele Ansätze. Ich hatte schon Seiten, die die CSS Klassen ins HTML hardcoden, irgendwelche anderen Schandtaten betreiben oder nicht wirklich schöne If-Abfragen um die Menüpunkte legen. <li @if (activeMenu.Equals("Home")) { <text>class="active"</text> }>@Html.ActionLink("Home", "index", "home")</li> Hier muss man natürlich noch bedenken, dass ein entsprechender ViewBag-Eintrag namens "activeMenu" in jeder Action gesetzt werden muss. urgs Ich möchte diese ganze Logik nicht in den Views haben. Daher habe ich eine kleine ExtensionMethot für den HtmlHelper geschrieben. Diese Extension generiert für mich die Menülinks und prüft […]

Dieses "Problem" müsste eigentlich jeder kennen der schon mein eine Webseite mit mehreren Bereichen erstellt hat. Wie kann ich den Menüpunkt der aktuell angezeigten Seite hervorheben?

Hier gibt es viele Ansätze. Ich hatte schon Seiten, die die CSS Klassen ins HTML hardcoden, irgendwelche anderen Schandtaten betreiben oder nicht wirklich schöne If-Abfragen um die Menüpunkte legen.


 <li @if (activeMenu.Equals("Home"))
 {
 <text>class="active"</text>
 }>@Html.ActionLink("Home", "index", "home")</li>

Hier muss man natürlich noch bedenken, dass ein entsprechender ViewBag-Eintrag namens "activeMenu" in jeder Action gesetzt werden muss. urgs

Ich möchte diese ganze Logik nicht in den Views haben. Daher habe ich eine kleine ExtensionMethot für den HtmlHelper geschrieben.

Diese Extension generiert für mich die Menülinks und prüft beim Generieren des Links ob das Ziel des Links mit dem aktuellen Controller und der aktuellen View übereinstimmt. Wenn das der Fall ist wird dieser Link als aktiv markiert. So sieht das Ganze aus:


public static MvcHtmlString NavigationActionLink(
 this HtmlHelper htmlHelper, string linkText,
 string actionName, string controllerName, object routeValues = null,
 object htmlAttributes = null, 
 string wrapperElement = "li", string flag = "active")
{
 var generatedLink = HtmlHelper.GenerateLink(
 htmlHelper.ViewContext.RequestContext,
 htmlHelper.RouteCollection, linkText,
 (string)null, actionName, controllerName,
 new RouteValueDictionary(routeValues), 
 (IDictionary<string, object>)HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

 var wrappedElement = WrapGeneratedLink(
 htmlHelper, actionName, 
 controllerName, wrapperElement, flag, generatedLink);

 return MvcHtmlString.Create(wrappedElement.ToString(TagRenderMode.Normal));
}

private static TagBuilder WrapGeneratedLink(
 HtmlHelper htmlHelper, string actionName, string controllerName,
 string wrapper, string flag, string generatedLink)
{
 var wrapperElement = new TagBuilder(wrapper)
 {
 InnerHtml = generatedLink
 };

 if (CurrentRouteMatchesGeneratedUrl(actionName, controllerName, htmlHelper))
 {
 wrapperElement.AddCssClass(flag);
 }
 return wrapperElement;
}

private static bool CurrentRouteMatchesGeneratedUrl(
 string actionName, string controllerName, HtmlHelper htmlHelper)
{
 var currentAction = (string)htmlHelper.ViewContext.RouteData.Values["action"];
 var currentController = (string)htmlHelper.ViewContext.RouteData.Values["controller"];

 return string.Equals(currentAction, actionName, 
 StringComparison.CurrentCultureIgnoreCase) &amp;&amp;
 string.Equals(currentController, controllerName, 
 StringComparison.CurrentCultureIgnoreCase);
}

Hier der Code nochmal etwas schöner formatiert.

Dieser Helper orientiert sich an dem gewöhnlichen ActionLink und hat die gleichen Parameter bis auf die letzten zwei, mit denen man bestimmen kann wie der Link hervorgehoben werden soll.

So könnte man nun die Menülinks verwenden am Beispiel Twitter Bootstrap:


<div class="navbar navbar-inverse navbar-fixed-top">
 <div class="navbar-inner">
 <div class="container">
 <div class="nav-collapse">
 <ul class="nav">
 @Html.NavigationActionLink("meinlink", "index", "home")
 @Html.NavigationActionLink("meinlink", "index", "account", null, null, "div", "selected")
 </ul>
 </div>
 </div>
 </div>
</div> 

So würde der erste Link folgendes generieren:


<li class="active"><a href="/">meinlink</a></li>

Und der zweite Link das hier:


<div class="selected"><a href="/">meinlink</a></div>

Auf diese Weise kann mann etwas Einfluss darauf nehmen was da generiert wird und mit welcher Klasse das erzeugte Feld markiert wird.

Der zweite Link macht natürlich keinen Sinn in dem Twitter Bootstrap Beispiel und wurde nur zu Demonstrationszwecken genutzt :)

So entfernt man den hässlichen Code aus den Views und muss sich darum keinen Kopf mehr machen.

Übrigens: In dem meisten Fällen reicht es wenn man nur nach dem Controller prüft, da häufig mehrere Actions zu einem Menüpunkt gehören und man dann einen Menüpunkt mit einem Controller abdeckt.

Wie macht ihr das?

Wie ist eure Methode um diese kleine Problematik zu lösen? Habt ihr vielleicht einen schöneren/einfacheren Ansatz? Dann würde ich mich sehr freuen wenn ihr mich belehren würdet :)

flattr this!

flattr this!

.net asp.net tipps-und-tricks programmierung tutorials asp mvc
Schreibe einen Kommentar:
Themen:
mvc asp tutorials programmierung tipps-und-tricks asp.net .net
Entweder einloggen... ...oder ohne Wartezeit registrieren
Benutzername
Passwort
Passwort wiederholen
E-Mail
TOP TECHNOLOGIES CONSULTING GmbH