Tar270
Tar270

Reputation: 77

Hide/Show menu in Navbar - blazor

I would like one of the menus in the navbar to be shown only when "/"(index page) is active.

On load, 'Menu5' is hidden. When I select a file on 'landingpage'(which is my on load page) , I am redirected to "/" (index page) using navigator. 'Menu5' need to be shown on NavBar when I am in "/".

NavBar.razor:

<li class="has-dropdown" hidden="@hideMenu">
       <a href="#.html">Menu5</a>

@code {
   public bool hideMenu= true;
} 

landingpage.Razor:

 @code{
         public bool hideMenu= true; 
 }

private async Task OnInputFileChange(InputFileChangeEventArgs e)
{
      hideMenu= true;
      UriHelper.NavigateTo("/");

} 

index.razor:

    public bool hideMenu= false; 

    [JSInvokable]
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        hideMenu= false;      // this line does not seem to work    
    }

Edited code:

My onload page is "landingpage". When I am on "landingpage", page2 and page3 menu should be hidden.

Second and third menu item need to be shown, when I navigate to 'Index' page ("/") on file selection thru code(UriHelper.NavigateTo) from 'landingpage'. Thank you.

Navbar.razor:

<nav class="navbar navbar-expand-lg navbar-light">
<div class="collapse navbar-collapse"
    <ul class="navbar-nav">

        <!-- first menu item-->
        <li class="nav-item"><a class="nav-link" href="landingpage">Landing Page</a></li>

       
        <!-- second menu item-->
        @if (routeData.PageType != typeof(Landingpage))
        {
            <li class="has-dropdown">
                <a href="#.html">page 2</a>  // its route path would be "/"
             </li>
         }

        <!-- third menu item -->
        @if (routeData.PageType != typeof(Landingpage))
        {
        <li class="has-dropdown">
            <a href="#.html">page 3</a>  
        </li>
        }
 
    </ul>
</div>
</nav>

Upvotes: 2

Views: 3567

Answers (1)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30016

As I can't build a minimum working example based on your code snippets here's code based on the standard Blazor Template that demonstrates how to turn off items in the NavMenu based on which page you are on. You should be able to adapt this code to fit your specific situation.

First we cascade the RouteData instance in App.razor. RouteData.PageType is the class type for the component that represents the current route. For example for "/" this will be Index.

<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <CascadingValue TValue="RouteData" value="@routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </CascadingValue>
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

Net5.0 version looks like this:

<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
    <Found Context="routeData">
        <CascadingValue TValue="RouteData" value="@routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        </CascadingValue>

    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

We can now use the cascading parameter in NavMenu to toggle menu items.

<div class="top-row ps-3 navbar navbar-dark">
    <div class="container-fluid">
        <a class="navbar-brand" href="">SO73610751</a>
        <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
            <span class="navbar-toggler-icon"></span>
        </button>
    </div>
</div>

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <nav class="flex-column">
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </div>
        @if(routeData.PageType != typeof(FetchData))
        {
            <div class="nav-item px-3">
                <NavLink class="nav-link" href="counter">
                    <span class="oi oi-plus" aria-hidden="true"></span> Counter
                </NavLink>
            </div>
        }
        @if (routeData.PageType != typeof(Counter))
        {
            <div class="nav-item px-3">
                <NavLink class="nav-link" href="fetchdata">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
            </NavLink>
        </div>
        }
    </nav>
</div>

@code {
    private bool collapseNavMenu = true;

    [CascadingParameter] private RouteData routeData { get; set; } = default!;

    protected override void OnInitialized()
    {
        if (routeData is null)
            throw new NullReferenceException("No Cascaded RouteData - You must cascade RouteData in App");
    }

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

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

Here's the view on Counter. Note FetchData is hidden.

enter image description here

And:

enter image description here

And:

enter image description here

Upvotes: 2

Related Questions