twitter-bootstrapblazor

Using ASP.NET Blazor, how do I make Bootstrap navbar collapse when menu item is clicked?


On mobile, I open the responsive menu and click on a menu item <NavLink>. I am routed to the new page, but the menu stays open and does not automatically collapse. When I click the <NavLink> a second time, the menu collapses. How do I make it auto collapse after clicking on <NavLink> the first time?

I'm using some of the code from the default Blazor template that looks like it would solve this problem, but it does not.

The navbar-collapse div when menu is opened by button: `

<div class="navbar-collapse justify-content-end collapse show" id="navbarNav" b-8i8utxilae="" style="">

The navbar-collapse div when clicked once:

<div class=" navbar-collapse justify-content-end" id="navbarNav" b-8i8utxilae="" style="">

The navbar-collapse div when clicked twice:

<div class="collapse navbar-collapse justify-content-end" id="navbarNav" b-8i8utxilae="" style="">

Here is all of the code.

<nav class="navbar navbar-expand-sm">
    <div class="container">
        <div class="d-inline-block" style="width: 50px;">
        <a class="navbar-brand fw-bold" href="/">
            <img class="w-100 me-3 my-2" src="/images/Magnolia_white.png" alt="no image" />
            <span class="no-mobile">Magnolia</span>
        </a>
        </div>
        <button type="button" class="navbar-toggler bg-secondary px-1" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="oi oi-menu text-light m-1"></span>
        </button>
        <div onclick="@ToggleNavMenu" class="@NavMenuCssClass navbar-collapse justify-content-end" id="navbarNav">
            <ul class="navbar-nav">
                <li class="nav-item ms-2">
                    <NavLink class="nav-link fw-bold" href="" Match="NavLinkMatch.All">
                        Home
                    </NavLink>
                </li>
            </ul>
        </div>
    </div>
</nav>
@code {
    private bool collapseNavMenu = true;

    private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }
}

Solution

  • Create a Javascript function to call the Bootstrap collapse method. Keeps the menu animation.

    In your Blazor component put the following.

    <li class="nav-item">
        <NavLink href="/Calendar" @onclick="CollapseMenu" class="nav-link">
            Calendar
        </NavLink>
    </li>
    
    async void CollapseMenu() => await JSRuntime.InvokeVoidAsync("myApp.collapseMenu");
    

    In your Javascript file put the following.

    myApp.collapseMenu = function () {
        let navbar = document.getElementById("myNavbar");
    
        if (navbar != null) {
            bootstrap.Collapse.getInstance(navbar).hide();
        }
    };
    

    Documentation found here, https://getbootstrap.com/docs/5.3/components/collapse/#usage

    The Bootstrap documentation provides the following example. However, this code will collapse every element with the class .collapse on the page. I had other collapsible elements on the page which I did not want to collapse and came up with the solution above.

    const collapseElementList = document.querySelectorAll('.collapse')
    const collapseList = [...collapseElementList].map(collapseEl => new bootstrap.Collapse(collapseEl))