ASP.NET MVC में Html.ActionLink में "एक्टिव" क्लास कैसे जोड़ें


128

मैं एमवीसी में अपने बूटस्ट्रैप नौबार में एक "सक्रिय" वर्ग जोड़ने की कोशिश कर रहा हूं, लेकिन निम्नलिखित सक्रिय वर्ग को नहीं दिखाता है जैसे कि:

<ul class="nav navbar-nav">
  <li>@Html.ActionLink("Home", "Index", "Home", null, new {@class="active"})</li>
  <li>@Html.ActionLink("About", "About", "Home")</li>
  <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

यह एक सही स्वरूपित वर्ग की तरह दिखता है, लेकिन काम नहीं करता है:

<a class="active" href="/">Home</a>

बूटस्ट्रैप डॉक्यूमेंटेशन में यह कहा गया है कि 'ए' टैग्स को नेवबार में इस्तेमाल नहीं किया जाना चाहिए, लेकिन ऊपर बताया गया है कि मेरा मानना ​​है कि एक वर्ग को एचटीएमएल.एक्विंकल में जोड़ने का सही तरीका है। वहाँ एक और (साफ) तरीका है मैं यह कर सकता हूँ?


3
कोड जो हल करता है उसमें कक्षा = सक्रिय है। क्या ऐसा नहीं है कि आप जो कहते हैं वह अपने प्रश्न में चाहते हैं? आपके पास आपका कोड कैसे है मैं कक्षाओं को कैसे जोड़ता हूं
मैट बोडी

आप बहुत स्पष्ट नहीं हैं !!! मुझे ठीक से समझ में नहीं आ रहा है कि इसे नौसेना में जोड़ने में क्या समस्या है, फिर भी मुझे एक एहसास मिलता है, जिस तरह से यह ठीक होना चाहिए
JC Lizard

1
हल कोड के साथ समस्या क्या है? आप क्या उम्मीद कर रहे हैं क्या आप "काम नहीं करता है" की तुलना में अधिक विशिष्ट हो सकते हैं? आपका प्रश्न अभी आपकी सहायता के लिए पर्याप्त नहीं है।
डोम

संपादित! क्षमा करें, मेरा मतलब था कि "सक्रिय" वर्ग बिल्कुल नहीं दिखा रहा है
गिलेस्पी

2
बस बूटस्ट्रैप के डॉक्स पर नज़र रखी गई है और मुझे लगता है कि आपको activeकक्षा को liतत्व में जोड़ने की आवश्यकता है , न कि a। पहला उदाहरण यहाँ देखें: getbootstrap.com/compenders/#navbar
dom

जवाबों:


300

बूटस्ट्रैप में activeवर्ग को <li>तत्व पर लागू करने की आवश्यकता है, न कि <a>। पहला उदाहरण यहाँ देखें: http://getbootstrap.com/compenders/#navbar

जिस तरह से आप अपनी UI शैली को सक्रिय करते हैं उसके आधार पर संभालते हैं या ASP.NET MVC के ActionLinkसहायक के साथ कुछ नहीं करते हैं । बूटस्ट्रैप फ्रेमवर्क कैसे बनाया गया था, इसका पालन करने के लिए यह उचित समाधान है।

<ul class="nav navbar-nav">
    <li class="active">@Html.ActionLink("Home", "Index", "Home")</li>
    <li>@Html.ActionLink("About", "About", "Home")</li>
    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

संपादित करें:

चूंकि आप कई पृष्ठों पर अपने मेनू का पुन: उपयोग करने की संभावना रखेंगे, इसलिए कई बार मेनू को कॉपी करने के बजाय वर्तमान पृष्ठ के आधार पर उस चयनित वर्ग को स्वचालित रूप से लागू करने का एक तरीका होना स्मार्ट होगा।

सबसे आसान तरीका है बस मूल्यों में निहित उपयोग करने के लिए है ViewContext.RouteData, अर्थात् Actionऔर Controllerमूल्यों। हम वर्तमान में आपके साथ कुछ इस तरह का निर्माण कर सकते हैं:

<ul class="nav navbar-nav">
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

यह कोड में बहुत सुंदर नहीं है, लेकिन यह काम पूरा कर देगा और यदि आप चाहें तो अपने मेनू को एक आंशिक दृश्य में निकालने की अनुमति दे सकते हैं। वहाँ बहुत क्लीनर तरीके से ऐसा करने के तरीके हैं, लेकिन जब से आप बस शुरू कर रहे हैं मैं इसे उस पर छोड़ दूंगा। बेस्ट ऑफ़ लक लर्निंग ASP.NET MVC!


देर से संपादित करें:

यह सवाल थोड़ा ट्रैफ़िक ले रहा है इसलिए मुझे लगा कि मैं एक HtmlHelperएक्सटेंशन का उपयोग करके अधिक सुरुचिपूर्ण समाधान में फेंक दूंगा।

03-24-2015 को संपादित करें: चयनित व्यवहार को ट्रिगर करने वाले कई कार्यों और नियंत्रकों के लिए अनुमति देने के लिए इस पद्धति को फिर से लिखना था, साथ ही जब बच्चे को कार्रवाई से देखने के लिए विधि कहा जाता है तो आंशिक रूप से देखें, मुझे लगा कि मैं अपडेट साझा करूंगा!

public static string IsSelected(this HtmlHelper html, string controllers = "", string actions = "", string cssClass = "selected")
{
    ViewContext viewContext = html.ViewContext;
    bool isChildAction = viewContext.Controller.ControllerContext.IsChildAction;

    if (isChildAction)
        viewContext = html.ViewContext.ParentActionViewContext;

    RouteValueDictionary routeValues = viewContext.RouteData.Values;
    string currentAction = routeValues["action"].ToString();
    string currentController = routeValues["controller"].ToString();

    if (String.IsNullOrEmpty(actions))
        actions = currentAction;

    if (String.IsNullOrEmpty(controllers))
        controllers = currentController;

    string[] acceptedActions = actions.Trim().Split(',').Distinct().ToArray();
    string[] acceptedControllers = controllers.Trim().Split(',').Distinct().ToArray();

    return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
        cssClass : String.Empty;
}

.NET कोर के साथ काम करता है:

public static string IsSelected(this IHtmlHelper htmlHelper, string controllers, string actions, string cssClass = "selected")
{
    string currentAction = htmlHelper.ViewContext.RouteData.Values["action"] as string;
    string currentController = htmlHelper.ViewContext.RouteData.Values["controller"] as string;

    IEnumerable<string> acceptedActions = (actions ?? currentAction).Split(',');
    IEnumerable<string> acceptedControllers = (controllers ?? currentController).Split(',');

    return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
        cssClass : String.Empty;
}

नमूना उपयोग:

<ul>
    <li class="@Html.IsSelected(actions: "Home", controllers: "Default")">
        <a href="@Url.Action("Home", "Default")">Home</a>
    </li>
    <li class="@Html.IsSelected(actions: "List,Detail", controllers: "Default")">
        <a href="@Url.Action("List", "Default")">List</a>
    </li>
</ul>

धन्यवाद, जैसा कि मैंने उल्लेख किया है कि यह मेरे पास मूल रूप से कैसे है, लेकिन मैं चयनित वस्तुओं के बीच "सक्रिय" वर्ग को बदलने के अपने कोड में एक विधि होने की उम्मीद कर रहा था।
गिलेस्पी

2
@ गिलेस्पी कोई चिंता नहीं! मैंने अपना उत्तर कुछ जानकारी जोड़ने के लिए संपादित किया है जो आपकी थोड़ी और मदद कर सकती है।
डोम

5
पहले संपादन के संबंध में, यह वास्तव में केवल इंडेक्स पेज के लिए काम करता था। ऐसा लगता है कि जब यह तुलना कर रहा था, तो यह ViewContext.RouteData.Values ​​["Action"] के रूप में विफल रहा है, एक स्ट्रिंग प्रकार की वस्तु वापस नहीं करता है (फिर भी यह नहीं जानता कि यह पहले पृष्ठ के लिए कैसे काम किया ....) । जब मैंने सभी ViewContext.RouteData.Values ​​[[Action]] को ViewContext.RouteData.Values ​​["Action"] में बदल दिया। toString (), इसने सभी पृष्ठों के लिए काम किया। यदि कोई व्यक्ति समान समस्या का अनुभव करता है, तो अपने समाधान में इसे जोड़ना चाहेगा।
14:32 बजे user3281466

2
@LonelyPixel शायद यह जवाब आपके लिए काम करे?
डोम

1
VB.NET उपयोगकर्ताओं के लिए: <li class = "@ (if (ViewContext.RouteData.Values ​​(" Action ")। ToString () =" Index "," active "," "))"> "Html.ActionLink (") होम "," इंडेक्स "," होम ") </ li>
एंड्रिया एंटांगेली

28

एक्सटेंशन:

public static MvcHtmlString LiActionLink(this HtmlHelper html, string text, string action, string controller)
{
    var context = html.ViewContext;
    if (context.Controller.ControllerContext.IsChildAction)
        context = html.ViewContext.ParentActionViewContext;
    var routeValues = context.RouteData.Values;
    var currentAction = routeValues["action"].ToString();
    var currentController = routeValues["controller"].ToString();

    var str = String.Format("<li role=\"presentation\"{0}>{1}</li>",
        currentAction.Equals(action, StringComparison.InvariantCulture) &&
        currentController.Equals(controller, StringComparison.InvariantCulture) ?
        " class=\"active\"" :
        String.Empty, html.ActionLink(text, action, controller).ToHtmlString()
    );
    return new MvcHtmlString(str);
}

उपयोग:

<ul class="nav navbar-nav">
    @Html.LiActionLink("About", "About", "Home")
    @Html.LiActionLink("Contact", "Contact", "Home")
</ul>

1
यह एक सुंदर कुशल विस्तार है। पूरी तरह से काम करता है और काफी सुरुचिपूर्ण है। आपको सलाम, प्रो! मेरी एकमात्र पकड़ उसके साथ है role="presentation", जो एक प्राथमिक नेविगेशनल मेनू ( john.foliot.ca/aria-hidden/#pr ) के लिए बिल्कुल उपयुक्त नहीं है । एक अनियंत्रित सूची लिंक के एक संबंधित सेट के लिए बहुत उपयुक्त कंटेनर है, क्योंकि यह उन्हें तार्किक तरीके से एक साथ जोड़ता है।
रेने काबिस

@ रेने कबीस ने इसे बूटस्ट्रैप नाशन के लिए getbootstrap.com/compenders/#nav-tabs
Prof

1
यह तब काम नहीं कर रहा है जब उपयोगकर्ता मैन्युअल रूप से छोटे केस लेटर या अपर केस लेटर में url इनपुट करता है, जैसे। " domain.com/Login " और " domain.com/LOGIN "। समाधान के लिए, var str = String.Format("<li role=\"presentation\"{0}>{1}</li>", currentAction.toLower().Equals(action.toLower(), StringComparison.InvariantCulture) && currentController.toLower().Equals(controller.toLower(), StringComparison.InvariantCulture) ? " class=\"active\"" : String.Empty, html.ActionLink(text, action, controller).ToHtmlString() );
Sky91

20

मैं asp.net mvc में एक दृश्य बैग पैरामीटर जोड़कर ऐसा करने का प्रयास किया। यहाँ मैंने क्या किया है

जोड़ा गया ViewBag.Current = "Scheduler";प्रत्येक पृष्ठ में पैरामीटर की तरह

लेआउट पृष्ठ में

<ul class="nav navbar-nav">
     <li class="@(ViewBag.Current == "Scheduler" ? "active" : "") "><a href="@Url.Action("Index","Scheduler")" target="_self">Scheduler</a></li>
 </ul>

इससे मेरी समस्या हल हो गई।


सरल और आसान उपाय।
जपेस सोफी

13

थोड़ी देर हो सकती है। लेकिन उम्मीद है कि यह मदद करता है।

public static class Utilities
{
    public static string IsActive(this HtmlHelper html, 
                                  string control,
                                  string action)
    {
        var routeData = html.ViewContext.RouteData;

        var routeAction = (string)routeData.Values["action"];
        var routeControl = (string)routeData.Values["controller"];

        // both must match
        var returnActive = control == routeControl &&
                           action == routeAction;

        return returnActive ? "active" : "";
    }
}

और अनुसरण के रूप में उपयोग करें:

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li class='@Html.IsActive("Home", "Index")'>
            @Html.ActionLink("Home", "Index", "Home")
        </li>
        <li class='@Html.IsActive("Home", "About")'>
            @Html.ActionLink("About", "About", "Home")
        </li>
        <li class='@Html.IsActive("Home", "Contact")'>
            @Html.ActionLink("Contact", "Contact", "Home")
        </li>
    </ul>
</div>

Http://www.codingeverything.com/2014/05/mvcbootstrapactivenavbar.html से संदर्भ प्राप्त करें


1
बहुत उपमा और सुरुचिपूर्ण समाधान। मैंने यहाँ कुछ सुधार किया। gist.github.com/jean-rakotozafy/… सभी नियंत्रक क्रियाओं के लिए एक मेनू पर प्रकाश डालने के लिए।
ज़ैन रोटो

5

मुझे पता है कि यह सवाल पुराना है, लेकिन मैं यहां अपनी आवाज जोड़ना चाहूंगा। मेरा मानना ​​है कि यह एक अच्छा विचार है कि यह देखने के नियंत्रक के लिए एक लिंक सक्रिय है या नहीं, इसका ज्ञान छोड़ दें।

मैं बस नियंत्रक कार्रवाई में प्रत्येक दृश्य के लिए एक अद्वितीय मूल्य निर्धारित करूंगा। उदाहरण के लिए, अगर मैं होम पेज लिंक को सक्रिय बनाना चाहता था, तो मैं कुछ इस तरह से करूंगा:

public ActionResult Index()
{            
    ViewBag.Title = "Home";
    ViewBag.Home = "class = active";
    return View();
}

तब मेरे विचार में, मैं कुछ इस तरह लिखूंगा:

<li @ViewBag.Home>@Html.ActionLink("Home", "Index", "Home", null, new { title = "Go home" })</li>

जब आप किसी भिन्न पृष्ठ पर जाते हैं, तो प्रोग्राम्स देखें, ViewBag.Home मौजूद नहीं है (इसके बजाय ViewBag.Programs करता है); इसलिए, कुछ भी प्रदान नहीं किया गया है, वर्ग भी नहीं = ""। मुझे लगता है कि यह स्थिरता और स्वच्छता दोनों के लिए क्लीनर है। मैं हमेशा तर्क को उस दृश्य से बाहर छोड़ना चाहता हूं जितना मैं कर सकता हूं।


4

दमित ने जो पोस्ट किया है, उसे देखते हुए, मुझे लगता है कि आप व्यूबैग द्वारा सक्रिय रूप से अर्हता प्राप्त कर सकते हैं। यह आपके _Layout.cshtmlपेज को लिंक लिंक रखने की अनुमति देने वाले आपके सामग्री पृष्ठों में इसे आबाद करने का सबसे अच्छा अभ्यास है )। यह भी ध्यान दें कि यदि आप उप-मेनू आइटम का उपयोग कर रहे हैं तो यह भी ठीक काम करता है:

<li class="has-sub @(ViewBag.Title == "Dashboard 1" || ViewBag.Title == "Dashboard 2" ? "active" : "" )">
    <a href="javascript:;">
        <b class="caret"></b>
        <i class="fa fa-th-large"></i>
        <span>Dashboard</span>
    </a>
    <ul class="sub-menu">
        <li class="@(ViewBag.Title == "Dashboard 1" ? "active" : "")"><a href="index.html">Dashboard v1</a></li>
        <li class="@(ViewBag.Title == "Dashboard 2" ? "active" : "")"><a href="index_v2.html">Dashboard v2</a></li>
    </ul>
</li>

स्वच्छ और कुशल!
मग्ग्लुसेविक

3

मैंने डोम के "सुंदर नहीं" उत्तर को संशोधित किया और इसे बदसूरत बना दिया। कभी-कभी दो नियंत्रकों में परस्पर विरोधी कार्रवाई नाम (यानी इंडेक्स) होता है, इसलिए मैं ऐसा करता हूं:

<ul class="nav navbar-nav">
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "HomeIndex" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "AboutIndex" ? "active" : "")">@Html.ActionLink("About", "Index", "About")</li>
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "ContactHome" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

3

आप यह कोशिश कर सकते हैं: मेरे मामले में मैं भूमिका के आधार पर डेटाबेस से मेनू लोड कर रहा हूं, अपने हर दृश्य पर कोड लिखें, जो आपके दृश्य के आधार पर सक्रिय करना चाहते हैं।

<script type="text/javascript">
        $(document).ready(function () {         
            $('li.active active-menu').removeClass('active active-menu');
            $('a[href="https://stackoverflow.com/MgtCustomer/Index"]').closest('li').addClass('active active-menu');
        });
</script>

3

यह समाधान Asp.net MCV 5 के लिए सरल है।

  1. उदाहरण के लिए, एक स्थिर वर्ग बनाएँ Utilitarios.cs

  2. कक्षा के अंदर एक स्थिर विधि बनाएँ:

    public static string IsLinkActive(this UrlHelper url, string action, string controller)
    {
        if (url.RequestContext.RouteData.Values["controller"].ToString() == controller &&
            url.RequestContext.RouteData.Values["action"].ToString() == action)
        {
            return "active";
        }
    
        return "";
    }
  3. इस तरह से कॉल करें

    <ul class="sidebar-menu" data-widget="tree">
        <li class="header">HEADER</li>
        <li class="@Url.IsLinkActive("Index", "Home")">
            <a href="@Url.Action("Index", "Home")"><i class="fa fa-link"></i> <span>Home</span></a>
        </li>
        <li class="@Url.IsLinkActive("About", "Home")">
            <a href="@Url.Action("About", "Home")"><i class="fa fa-link"></i><span>About</span></a>
        </li>
    </ul>

3

ASP.NET कोर और बूटस्ट्रैप 4

अधिकांश अप-टू-डेट उत्तर

मैं एक अद्यतन, ASP.NET कोर और बूटस्ट्रैप 4 संगत तरीके से एक विस्तार विधि के आधार पर इस समस्या को हल करने के लिए @crush के स्वच्छ समाधान पर फिर से काम किया है :IHtmlHelper

public static class LinkExtensions
{
    public static IHtmlContent ActiveActionLink(this IHtmlHelper html, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
    {
        return ActiveActionLink(html, linkText, actionName, controllerName, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    public static IHtmlContent ActiveActionLink(this IHtmlHelper html, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
    {
        var routeData = html.ViewContext.RouteData;
        var routeAction = (string)routeData.Values["action"];
        var routeController = (string)routeData.Values["controller"];

        var active = controllerName.Equals(routeController) && actionName.Equals(routeAction);

        using (var writer = new StringWriter())
        {
            writer.WriteLine($"<li class='nav-item {(active ? "active" : "")}'>");
            html.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes).WriteTo(writer, HtmlEncoder.Default);
            writer.WriteLine("</li>");
            return new HtmlString(writer.ToString());
        }
    }
}

प्रयोग

<nav class="navbar">
    <div class="collapse navbar-collapse">
        <ul class="navbar-nav">
            @Html.ActiveActionLink("Home", "Index", "Home", null, new { @class = "nav-link" })
            @Html.ActiveActionLink("About", "About", "Home", null, new { @class = "nav-link" })
            @Html.ActiveActionLink("Contact", "Contact", "TimeTracking", null, new { @class = "nav-link" })
        </ul>
    </div>
</nav>

1
बहुत अच्छा उपाय है। आपके उदाहरण में, मैं 'संपर्क' को डिफ़ॉल्ट रूप से कैसे सक्रिय कर सकता हूं?
एमडी। सुमन कबीर

1
धन्यवाद। अच्छी बात यह है कि आपको एक सक्रिय तत्व सेट करने की आवश्यकता नहीं है। जैसे ही 'संपर्क' पृष्ठ पर ActiveActionLink()<li>
जाया जाता है

आप चेक एरिया कहाँ है
मोहम्मद

@ मोहम्मद मुझे समझ नहीं आ रहा है। क्या आप कृपया अपना प्रश्न विस्तृत कर सकते हैं?
WoIIe

LinkExtension वर्ग में आपको रूटडेटा से क्षेत्र नहीं मिला!
मोहम्मद

3

आसान ASP.NET Core 3.0 और TagHelpers

[HtmlTargetElement("li", Attributes = "active-when")]
public class LiTagHelper : TagHelper
{
    public string ActiveWhen { get; set; }

    [ViewContext]
    [HtmlAttributeNotBound]
    public ViewContext ViewContextData { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if (ActiveWhen == null)
            return;

        var targetController = ActiveWhen.Split("/")[1];
        var targetAction = ActiveWhen.Split("/")[2];

        var currentController = ViewContextData.RouteData.Values["controller"].ToString();
        var currentAction = ViewContextData.RouteData.Values["action"].ToString();

        if (currentController.Equals(targetController) && currentAction.Equals(targetAction))
        {
            if (output.Attributes.ContainsName("class"))
            {
                output.Attributes.SetAttribute("class", $"{output.Attributes["class"].Value} active");
            }
            else
            {
                output.Attributes.SetAttribute("class", "active");
            }
        }
    }
}

अपने _ViewImports.cs में शामिल करें:

@addTagHelper *, YourAssemblyName

उपयोग:

 <li active-when="/Home/Index">

2

ASP.NET MVC पर तुलना करने के लिए '.TString' जोड़ें

<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>

-


यदि दो अलग-अलग नियंत्रकों में समान कार्य नाम हैं तो यह काम नहीं करेगा। इंडेक्स एक्शन के साथ होम और कंट्रोलर्स के साथ इसका परीक्षण करें।
हायड जूल

u रेजर पर फ़ंक्शन सर्वर को डिफाइंड कर सकता है जैसे: @functions { public bool IsActive(string action, string controller) { var actionRoute = ViewContext.RouteData.Values["Action"].ToString(); var controlRoute = ViewContext.RouteData.Values["Controller"].ToString(); return controller.Equals(controlRoute)&& actionRoute.Equals(actionRoute); } }और उपयोग: <li class="@(IsActive("Index", "Home")? "active": "")">
हुआ ट्रुंग

2

हम UrlHelperRequestContext से भी बना सकते हैं जिसे हम MvcHandler से प्राप्त कर सकते हैं। इसलिए मैं किसी ऐसे व्यक्ति के लिए निष्ठावान हूं जो इस तर्क को रेजर के खाके में रखना चाहता है, जो निम्न प्रकार से सहायक होगा:

  1. प्रोजेक्ट रूट में नाम का फोल्डर बनाते हैं AppCode
  2. वहां एक फाइल बनाएं जिसका नाम है HtmlHelpers.cshtml
  3. वहाँ एक सहायक बनाएँ:

    @helper MenuItem(string action, string controller)
    {
         var mvcHandler = Context.CurrentHandler as MvcHandler;
         if (mvcHandler != null)
         {
             var url = new UrlHelper(mvcHandler.RequestContext);
             var routeData = mvcHandler.RequestContext.RouteData;
             var currentAction = routeData.Values["action"].ToString();
             var currentController = routeData.Values["controller"].ToString();
             var isCurrent = string.Equals(currentAction, action, StringComparison.InvariantCultureIgnoreCase) &&
                             string.Equals(currentController, controller, StringComparison.InvariantCultureIgnoreCase);
    
            <div class="@(isCurrent ? "active" : "")">
                <div>@url.Action(action, controller)</div>
            </div>
         }   
    }
  4. फिर हम इस तरह से अपने विचारों का उपयोग कर सकते हैं:

    @HtmlHelpers.MenuItem("Default", "Home")

आशा है कि यह किसी की मदद करता है।


यह वास्ताव में अच्छा है। क्या यहां कोई प्रदर्शन कमियां हैं?
क्रश करें

@ क्रश, मैंने इसे मापा नहीं है, लेकिन मुझे उम्मीद है कि इसका प्रदर्शन कम होगा, क्योंकि मुझे लगता है कि फ्रेमवर्क UrlHelperआपके द्वारा बनाए गए समान लॉजिक का उपयोग करता है Controller.Url। केवल एक चीज यह है कि हम शायद UrlHelperप्रत्येक कॉल के लिए क्रिएट करना नहीं चाहते हैं MenuItemइसलिए हम इसे हेल्परकोटेक्स्ट आइटम में सहेजने का एक टिक लगा सकते हैं, पहला कॉल हेल्पर को करने के बाद इसलिए हम इसे केवल एक बार अनुरोध के अनुसार करते हैं।
ओलेक्सी अजा

2

एक मेमने के कार्य के साथ संभव है

@{
string controllerAction = ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString();
    Func<string, string> IsSelected= x => x==controllerAction ? "active" : "";
}

तो उपयोग करें

 @Html.ActionLink("Inicio", "Index", "Home", new { area = "" }, new { @class = IsSelected("HomeIndex")})

2

मैंने एक HtmlHelperएक्सटेंशन बनाया ActiveActionLinkजो आप में से उन लोगों के लिए एक विधि जोड़ता है जो "सक्रिय" वर्ग को लिंक के <li>आसपास के बजाय लिंक से जोड़ना चाहते हैं ।


public static class LinkExtensions
{
    public static MvcHtmlString ActiveActionLink(this HtmlHelper html, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
    {
        return ActiveActionLink(html, linkText, actionName, controllerName, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    public static MvcHtmlString ActiveActionLink(this HtmlHelper html, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
    {
        const string activeClassName = "active";

        var routeData = html.ViewContext.RouteData;

        var routeAction = (string)routeData.Values["action"];
        var routeController = (string)routeData.Values["controller"];

        var active = controllerName.Equals(routeController) && actionName.Equals(routeAction);

        if (active)
        {
            var @class = (string)htmlAttributes["class"];

            htmlAttributes["class"] = string.IsNullOrEmpty(@class)
                ? activeClassName
                : @class + " active";
        }

        var link = html.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);

        return link;
    }
}

उपयोग निम्नानुसार है:

@Html.ActiveActionLink("Home", "Index", "Home", new { area = "" }, new { @class = "nav-item nav-link" })

1

@dombenoit द्वारा जवाब काम करता है। हालांकि यह बनाए रखने के लिए कुछ कोड पेश करता है। इस सिंटैक्स की जाँच करें:

using (var nav = Html.Bootstrap().Begin(new Nav().Style(NavType.NavBar).SetLinksActiveByControllerAndAction()))
{
    @nav.ActionLink("Link 1", "action1")
    @nav.ActionLink("Link 2", "action2")
    @nav.Link("External Link", "#")
}

.SetLinksActiveByControllerAndAction()विधि के उपयोग पर ध्यान दें ।

यदि आपको आश्चर्य है कि इस वाक्यविन्यास को क्या संभव बनाता है, तो TwitterBootstrapMVC देखें


उत्तर के लिए धन्यवाद दिमित्री, मैं बाहर का परीक्षण कर रहा हूँ TwitterBootstrapMVC
गिलेस्पी

1

मैं भी एक समाधान की तलाश में था और jQuery ने बहुत मदद की। सबसे पहले, आपको अपने <li>तत्वों को 'आईडी' देना होगा ।

<li id="listguides"><a href='/Guides/List'>List Guides</a></li>

अपने लेआउट पृष्ठ में ऐसा करने के बाद, आप jQuery को बता सकते हैं कि <li>आपके विचार में कौन सा तत्व 'चयनित' होना चाहिए।

@section Scripts{
    <script type="text/javascript">
        $('#listguides').addClass('selected');
    </script>
}

नोट: आपको उस अनुभाग को जोड़ने के @RenderSection("scripts", required: false)लिए </body>टैग से ठीक पहले अपने लेआउट पृष्ठ में होना चाहिए ।


1

मैं इस समाधान का प्रस्ताव करना चाहता हूं जो डोम के उत्तर के पहले भाग पर आधारित है।

हम पहले दो चर, "क्रिया" और "नियंत्रक" को परिभाषित करते हैं और सक्रिय लिंक को निर्धारित करने के लिए उनका उपयोग करते हैं:

{ string controller = ViewContext.RouteData.Values["Controller"].ToString();
string action = ViewContext.RouteData.Values["Action"].ToString();}

और तब:

<ul class="nav navbar-nav">
    <li class="@((controller == "Home" && action == "Index") ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
    <li class="@((controller == "Home" && action == "About") ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
    <li class="@((controller == "Home" && action == "Contact") ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

अब यह अच्छा लग रहा है और अधिक जटिल समाधानों की आवश्यकता नहीं है।


0

यदि यह बिल्कुल नहीं दिख रहा है, तो इसका कारण यह है कि आपको दो @ चिह्न की आवश्यकता है:

@@class

लेकिन, मेरा मानना ​​है कि आपको "ली" टैग पर सक्रिय वर्ग की आवश्यकता हो सकती है न कि "ए" टैग पर। बूटस्ट्रैप डॉक्स ( http://getbootstrap.com/compenders/#navbar-default ) के अनुसार :

<ul class="nav navbar-nav">
  <li class="active"><a href="#">Home</a></li>
  <li><a href="#">Profile</a></li>
  <li><a href="#">Messages</a></li>
</ul>

इसलिए आपका कोड होगा:

<ul class="nav navbar-nav">
  <li class="active">@Html.ActionLink("Home", "Index", "Home", null)</li>
  <li>@Html.ActionLink("About", "About", "Home")</li>
  <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

@@ वर्ग एक त्रुटि फेंकता है, मेरे पास मूल रूप से आपका कोड उदाहरण ऊपर था, जो काम करता है, लेकिन एक्शनलिंक "जैसा" नहीं होना चाहिए?
गिलेस्पी

संपादित। @@ की आवश्यकता नहीं है। आपको ईए
जेसी छिपकली

0

आशा है कि यह मदद करता है, नीचे आपका मेनू कैसा हो सकता है:

 <ul class="nav navbar-nav">
   <li><a href="@Url.Action("Index", "Home")" class="@IsMenuSelected("Index","Home", "active")">Home</a></li>
   <li><a href="@Url.Action("About", "Home")" class="@IsMenuSelected("About", "Home", "active")">About</a></li>
   <li><a href="@Url.Action("Contact", "Home")" class="@IsMenuSelected("Contact", "Home", "active")">Contact</a></li>
 </ul>

और html टैग के नीचे MVC हेल्पर फंक्शन जोड़ें।

 @helper IsMenuSelected(string actionName, string controllerName, string className)
    {
            var conname = ViewContext.RouteData.Values["controller"].ToString().ToLower();
            var actname = ViewContext.RouteData.Values["action"].ToString().ToLower();

            if (conname == controllerName.ToLower() && actname == actionName.ToLower())
        {
            @className;
        }
    }

मैंने http://questionbox.in/add-active-class-menu-link-html-actionlink-asp-net-mvc/ से उत्तर को संदर्भित किया


0

मुझे एहसास हुआ कि यह समस्या हम में से कुछ के लिए एक सामान्य समस्या थी, इसलिए मैंने नगेट पैकेज का उपयोग करके अपना समाधान प्रकाशित किया। नीचे आप देख सकते हैं कि यह कैसे काम करता है। मुझे उम्मीद है कि यह उपयोगी होगा।

नोट: यह नगेट पैकेज मेरा पहला पैकेज है। इसलिए यदि आपको कोई गलती दिखाई देती है, तो कृपया प्रतिक्रिया दें। धन्यवाद।

  1. पैकेज स्थापित करें या स्रोत कोड डाउनलोड करें और अपना प्रोजेक्ट जोड़ें

    -Install-Package Betalgo.MvcMenuNavigator
  2. अपने पृष्ठों को एक एनम में जोड़ें

    public enum HeaderTop
    {
        Dashboard,
        Product
    }
    public enum HeaderSub
    {
        Index
    }
  3. फ़िल्टर को अपने कंट्रोलर या एक्शन के शीर्ष पर रखें

    [MenuNavigator(HeaderTop.Product, HeaderSub.Index)]
    public class ProductsController : Controller
    {
        public async Task<ActionResult> Index()
        {
            return View();
        }
    
        [MenuNavigator(HeaderTop.Dashboard, HeaderSub.Index)]
        public async Task<ActionResult> Dashboard()
        {
            return View();
        }
    }
  4. और इसका उपयोग अपने हेडर लेआउट में इस तरह से करें

    @{
    var headerTop = (HeaderTop?)MenuNavigatorPageDataNavigatorPageData.HeaderTop;
    var headerSub = (HeaderSub?)MenuNavigatorPageDataNavigatorPageData.HeaderSub;
    }
    <div class="nav-collapse collapse navbar-collapse navbar-responsive-collapse">
    <ul class="nav navbar-nav">
        <li class="@(headerTop==HeaderTop.Dashboard?"active selected open":"")">
            <a href="@Url.Action("Index","Home")">Dashboard</a>
        </li>
        <li class="@(headerTop==HeaderTop.Product?"active selected open":"")">
            <a href="@Url.Action("Index", "Products")">Products</a>
        </li>
    </ul>

अधिक जानकारी: https://github.com/betalgo/MvcMenuNavigator


0

मेरा मानना ​​है कि चयनित मेनू को "सक्रिय" होने के लिए एक क्लीनर और छोटा कोड है:

 <ul class="navbar-nav mr-auto">
                <li class="nav-item @Html.IfSelected("Index")">
                    <a class="nav-link" href="@Url.Action("Index", "Home")">Home</a>
                </li>
                <li class="nav-item @Html.IfSelected("Controls")">
                    <a class="nav-link" href="@Url.Action("Controls", "Home")">MVC Controls</a>
                </li>
                <li class="nav-item @Html.IfSelected("About")">
                    <a class="nav-link" href="@Url.Action("About", "Home")">About</a>
                </li>
</ul>

 public static string IfSelected(this HtmlHelper html, string action)
        {
            return html
                       .ViewContext
                       .RouteData
                       .Values["action"]
                       .ToString() == action
                            ? " active"
                            : "";
        }

अच्छा है, हालांकि शायद कुछ मामलों में नियंत्रक और क्षेत्र के लिए विस्तारित करने की आवश्यकता है
ग्रहलेयर

-1

मैंने उपरोक्त उत्तरों का संयोजन किया है और अपना समाधान बनाया है।

इसलिए..

पहले रेजर ब्लॉक में एक स्ट्रिंग वेरिएबल बनाएं जिसमें कंट्रोलर और एक्शन का नाम वैल्यू होगा जो यूजर द्वारा कहा जाता है।

    @{
        string controllerAction =  ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString(); 
    }

फिर HTML और रेजर कोड के संयोजन का उपयोग करें:

    <ul class="nav navbar-nav">
        <li class="@(controllerAction == "HomeIndex" ? "active" : "" )">@Html.ActionLink("Home", "Index", "Home")</li>
        <li class="@(controllerAction == "AboutIndex" ? "active" : "" )">@Html.ActionLink("About", "Index", "About")</li>
        <li class="@(controllerAction == "HomeContact" ? "active" : "" )">@Html.ActionLink("Contact", "Contact", "Home")</li>
    </ul>

मुझे लगता है, यह अच्छा है क्योंकि आपको नियंत्रक नाम और कार्रवाई नाम प्राप्त करने के लिए प्रत्येक बार "ViewContext.RouteData.Values" तक पहुंचने की आवश्यकता नहीं है।


-1

इस समस्या का मेरा समाधान है

<li class="@(Context.Request.Path.Value.ToLower().Contains("about") ? "active " : "" ) nav-item">
                <a class="nav-link" asp-area="" asp-controller="Home" asp-action="About">About</a>
            </li>

लिंक के साथ तुलना किए जाने के लिए वर्तमान पथ को वापस करने के लिए एक बेहतर तरीका एक एचटीएमएल एक्सटेंशन विधि जोड़ सकता है


-1

इसे मैने किया है:

मेनू आंशिक दृश्य में सहायक बनाया गया

 @helper RouterLink(string action, string controller)
{
    var IsActive = ViewContext.RouteData.Values["Controller"].ToString() == controller && ViewContext.RouteData.Values["Action"].ToString() == action;
    <text>href="@Url.Action(action, controller)"</text>if (IsActive){ <text>class="active"</text>}
}

फिर इसे इस तरह एंकर टैग में इस्तेमाल किया:

<li><a @RouterLink("Index","Home")>Home</a></li>

मेरे आवेदन में कोई क्षेत्र नहीं था, लेकिन इसे हेल्पर फ़ंक्शन के दूसरे चर के रूप में भी शामिल किया जा सकता है। और मुझे अपने विचार में एंकर टैग के लिए सक्रिय वर्ग पास करना पड़ा। लेकिन liइस तरह भी कॉन्फ़िगर किया जा सकता है।


1
यदि आप कारण का उल्लेख नहीं करते हैं, तो आप वास्तव में मदद नहीं करते हैं।
अनूप शर्मा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.