How to keep the active menu item highlighted when visiting pages in ASP.Net MVC 5 application?

Viewed 12467

So, I have one ASP.Net MVC 5 application. In that one of page hasfour menu items. When page loads first menu item is selected by default (so it should be highlighted as soon as the page loads). And now as soon as user clicks on any other menu, that other menu should be in highlighted stage, so that user knows which menu he is currently on. Below is my attempt:

My thinking:

a. add a click event on the ul tag.

b. when clicked find "active" class inside ul tag and remove it.

c. now add active class to the source of click event (which means the li tag on which user clicked).

Issue:

The selected/clicked menu gets highlighted for a second, and then automatically first menu gets highlighted. So as soon as the whole page corresponding to the newly clicked menu item reloads the first menu item gets highlighted back.

My Attempt

P.S: This is a partial View, And all redirects will load this partial view afresh.

@if (Request.IsAuthenticated)
{
    <ul style="list-style-type:none;">
        <li class="active setBtnMargin">
            <a href="@Url.Action("Index", "Resume")" class="btn btn-block">My Resume </a>
        </li>
        <li class="setBtnMargin">
            <a href="@Url.Action("Index", "CoverLetter")" class="btn btn-block">My Cover Letter </a>
        </li>
        <li class="setBtnMargin">
            <a href="@Url.Action("Index", "Home")" class="btn btn-block">My Account </a>
        </li>
        <li class="setBtnMargin">
            <a href="@Url.Action("Index", "Home")" class="btn  btn-block">Get Rewards </a>
        </li>
    </ul>
}

<script>
// ATTEMPT 1
    $("ul").on("click", "li", function () {
        $('ul li').removeAttr('active');
        $(this).addClass('active');
    });

// ATTEMPT 2
    //$("li").click(function () {
    //    //$("ul li").removeClass("active");
    //    $(this).addClass("active");
    //});
</script>

EDIT 1

So the problem is as the page gets redirected. The active tag again gets appened to the first menu item when entire DOM gets reloaded because all the landing pages use the same partial view.

5 Answers

I took a different approach, leveraging the fact that I use a load script for each partial view to load data into DataTables on that view.

I started by added an "id" to each of the menu items.

<ul class="nav navbar-nav">
    <li id="Index"><a asp-page="/Index">Reportables</a></li>
    <li id="TaskAssayExclusion"><a asp-page="/TaskAssayExclusion">Task Assay Exclusions</a></li>
    <li id="SpecimenSite"><a asp-page="/SpecimenSite">Specimen Site</a></li>
    <li id="SnomedCT"><a asp-page="/SnomedCT">Snomed CT</a></li>
    <li id="Loinc"><a asp-page="/Loinc">LOINC</a></li>
    <li id="Search"><a asp-page="/Search">Search Messages</a></li>
</ul>

At the bottom of each partial view I have a snippet of JavaScript that gets executed when that view loads. An example of the snippet for the Index page is shown below.

<script type="text/javascript">
    function partialIndexModelScript() {
        $('li#Index').addClass('menu_item_active');
        filterLoadComplete = false;
        selectLoadComplete = false;
        loadReportableResultData();
    }
</script>

In my main JavaScript file, near the end of the $(document).ready() function I use 'typeof' to execute the relevant JavaScript snippet.

if (typeof partialIndexModelScript !== "undefined") partialIndexModelScript();
if (typeof partialSpecimenSiteModelScript !== "undefined") partialSpecimenSiteModelScript();
if (typeof partialNormalcyModelScript !== "undefined") partialNormalcyModelScript();
if (typeof partialSnomedCTModelScript !== "undefined") partialSnomedCTModelScript();
if (typeof partialLoincModelScript !== "undefined") partialLoincModelScript();
if (typeof partialTaskAssayExclusionModelScript !== "undefined") partialTaskAssayExclusionModelScript();
if (typeof partialSearchModelScript !== "undefined") partialSearchModelScript();

And finally the CSS which is nearly identical to the :hover CSS except that
I've included the font-weight: bolder !important to really make the selected menu item stand out.

.menu_item_active {
    color: #B8B7DA !important;
    background-color: #514689 !important;
    text-decoration: underline !important;
    font-weight: bolder !important;
}

The final result:

Related