Search code examples
c#htmlasp.netmodel-view-controller

ASP.Net Core Web App - How can i prevent Navbar style from reloading when navigating to other pages?


I am having a problem with the style refreshing on my navbar I click on a link to go to a new page. Is there any way i can fix this? I am new to using ASP.NET core webapp.

Here is a video of the issue I am having: Video

Here is my Shared/_Layout.cshtml

<body >
    <header>
        
        <!-- Navbar -->
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light gradient-custom border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Watch It Later</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            @Html.ActionLink("Home", "Index", "Home",null, new {@class = "navlink-custom"})
                        </li>
                        <li class="nav-item">
                            @Html.ActionLink("Privacy", "Privacy", "Home",null, new {@class = "navlink-custom"})
                            
                        </li>
                        <li class="nav-item">
                            @Html.ActionLink("Watch List", "Index", "Movies",null, new {@class = "navlink-custom"})
                        </li>
                        <li class="nav-item">
                            @Html.ActionLink("Find Movies", "ShowSearchForm", "Movies",null, new {@class = "navlink-custom"})
                        </li>
                    </ul>
                    <partial name="_LoginPartial" />
                </div>
            </div>
        </nav>
    </header>
    <div class="page-stack">
        <div class="container">
            <main role="main" class="pb-3">
                @RenderBody()
            </main>
        </div>

        <footer>
            <div class="container">
                &copy; 2023 - WishlistWebApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
            </div>
        </footer>
    </div>
    
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>

Is there a way to prevent the navbar from reloading?


Solution

  • I'm assuming you are trying to retain a 'selected' style on your nav item across page navigations. If I am correct then you don't want to take your approach where you 'prevent nav style from reloading on navigation'.

    The way to do this is with a custom HtmlHelper method. You create the helper method and then append it to the li elements class. When the page loads it determines the route values and sets the style based on the current route values.


    Create a Html Helper Extension method. This method will be called each page load and will use the route values to determine the current page, then based on these values it will apply the 'selected' css style to the 'li' element where the 'action' and 'controller' parameters match the current route.

    public static class HtmlHelperExtensions
    {
        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;
        }
    }
    
    

    Then use it your navigation on the li element, like so...

    <li class="nav-item @Html.IsSelected(actions:"Index", controllers: "Home")">
        @Html.ActionLink("Home", "Index", "Home",null, new {@class = "navlink-custom"})
    </li>
    <li class="nav-item @Html.IsSelected(actions:"Privacy", controllers: "Home")">
        @Html.ActionLink("Privacy", "Privacy", "Home",null, new {@class = "navlink-custom"})
    </li>
    <li class="nav-item @Html.IsSelected(actions:"Index", controllers: "Movies")">
        @Html.ActionLink("Watch List", "Index", "Movies",null, new {@class = "navlink-custom"})
    </li>
    <li class="nav-item @Html.IsSelected(actions:"ShowSearchForm", controllers: "Movies")">
        @Html.ActionLink("Find Movies", "ShowSearchForm", "Movies",null, new {@class = "navlink-custom"})
    </li>
    

    ... and don't forget to add a css style...

    .selected {
        background-color: #d0eef9;
        border-radius: .4em;
    }