krishna ram
krishna ram

Reputation: 105

how to create a nested menu using angular mat-nav material? (updated)

I'm trying to create a nested mat-menu items for my angular app. I got some solutions only where the nested options would appear as a pop-up, where i'm expecting it to be a drop-down where we could choose the menu lying under it when triggered.

I tried using the mat-sidenav-container and gave a few conditions to open the menu based on the condition

 <mat-nav-list>
     <mat-list-item (click)="showSubmenu = !showSubmenu" class="parent">
          <span class="full-width" *ngIf="isExpanded || 
            isShowing">Users</span>
       <mat-icon mat-list-icon>supervisor_account</mat-icon>
        <mat-icon class="menu-button" [ngClass]="{'rotated' : 
          showSubmenu}" *ngIf="isExpanded || 
             isShowing">expand_more</maticon>
        </mat-list-item>
        <div class="submenu" [ngClass]="{'expanded' : showSubmenu}" 
           *ngIf="isShowing || isExpanded">
          <div [routerLink]="['users']" routerLinkActive="active" 
             (click)="toggleSide()">Add Users</div>
          </div>
    </mat-nav-list>
``in the above code. i would like to nest Manage Users under Users list item``` and my .ts file follows:

showSubmenu: boolean = false;
  isShowing = false;
  showSubSubMenu: boolean = false;
  isExpanded = true;

i would like the expected result to be like this (https://stackblitz.com/edit/material-sidenav-example?file=app%2Fsidenav-autosize-example.html)

I did try using the same element as in the above link, but i couldn't get it working. i might be doing a very silly mistake. Thanks in advance !!

Upvotes: 9

Views: 33164

Answers (5)

Mohamed Ben Amar
Mohamed Ben Amar

Reputation: 131

You can implement a generic menu list item, Here is an example:

https://dynamic-nested-sidenav-menu.stackblitz.io

Here is a link to the source: https://stackblitz.com/edit/dynamic-nested-sidenav-menu?file=app%2Fmenu-list-item%2Fmenu-list-item.component.ts

Upvotes: 12

Simon_Weaver
Simon_Weaver

Reputation: 145890

Unrelated to the OP's specific needs, but here's a fun nested menu I just made:

It demonstrates how Angular templates work similar to Javascript in that templates create a sort of closure scope. Because of that I was able to create a dynamic nested menu with no duplicated code.

The key here is the method call setFont(target, font) where the value of target is 'closed' over so when the item is clicked it refers to the correct one.

<!-- fonts menu -->
<mat-menu #fontMenu="matMenu">

    <ng-container *ngFor="let target of ['Header', 'Body']">
        
        <!-- submenu for each target -->
        <button mat-menu-item [matMenuTriggerFor]="fontsMenu">
            <span>{{ target }} font</span>
        </button>

        <!-- submenu for each font -->
        <mat-menu #fontsMenu="matMenu">
            <ng-container *ngFor="let font of ['Arial', 'Comic Sans']">

                <button mat-menu-item (click)="setFont(target, font)">
                    <span>{{ font }}</span>
                </button>  

            </ng-container>
        </mat-menu>

    </ng-container>

</mat-menu>

enter image description here

Upvotes: 0

Agnitra Banerjee
Agnitra Banerjee

Reputation: 21

I did it like this

<mat-nav-list>
  <mat-accordion>
    <mat-expansion-panel style="box-shadow: none">
      <mat-expansion-panel-header style="margin-left: -8px">
        <mat-panel-title> <mat-icon>code</mat-icon>&nbsp;Developers </mat-panel-title>
      </mat-expansion-panel-header>
      <a
        mat-list-item
        routerLink="test"
        class="sidenav__list-item list-sub-item"
        [routerLinkActive]="['active']"
        (click)="handleClickEvent($event)"
      >
        <mat-icon>api</mat-icon>
        <span style="padding-top: 11px;">Api Keys</span>
      </a>
      <a
        mat-list-item
        routerLink="test1"
        class="sidenav__list-item list-sub-item"
        [routerLinkActive]="['active']"
        (click)="handleClickEvent($event)"
      >
        <mat-icon>webhook</mat-icon>
        <span style="padding-top: 11px;">Web Hooks</span>
      </a>
    </mat-expansion-panel>
  </mat-accordion>
</mat-nav-list>

this is how it looks finally

Upvotes: 2

Mohamed Ben Amar
Mohamed Ben Amar

Reputation: 131

From your code

     <mat-nav-list style="width:300px">
        <mat-list-item (click)="showSubmenu = !showSubmenu" class="parent">
            <span class="full-width" *ngIf="isExpanded || 
                isShowing">Users</span>
            <mat-icon mat-list-icon>supervisor_account</mat-icon>
            <mat-icon class="menu-button" [ngClass]="{'rotated' : 
              showSubmenu}" *ngIf="isExpanded || 
                 isShowing">expand_more</mat-icon>
            </mat-list-item>
        <div *ngIf="showSubmenu">
        <a menu-list-item >
          Mangage users
        </a>
        </div>
            <div class="submenu" [ngClass]="{'expanded' : showSubmenu}" 

               *ngIf="isShowing || isExpanded">
              <div  
                 (click)="toggleSide()">Add Users</div>
              </div>
        </mat-nav-list>

But this is not good in Practice and if you have a lot of nesting, in that case use a generic one.

Upvotes: 1

Mustafa Omran
Mustafa Omran

Reputation: 344

According to Angular material

     <button mat-button [matMenuTriggerFor]="animals">Animal index</button>

<mat-menu #animals="matMenu">
  <button mat-menu-item [matMenuTriggerFor]="vertebrates">Vertebrates</button>
  <button mat-menu-item [matMenuTriggerFor]="invertebrates">Invertebrates</button>
</mat-menu>

<mat-menu #vertebrates="matMenu">
  <button mat-menu-item [matMenuTriggerFor]="fish">Fishes</button>
  <button mat-menu-item [matMenuTriggerFor]="amphibians">Amphibians</button>
  <button mat-menu-item [matMenuTriggerFor]="reptiles">Reptiles</button>
  <button mat-menu-item>Birds</button>
  <button mat-menu-item>Mammals</button>
</mat-menu>

<mat-menu #invertebrates="matMenu">
  <button mat-menu-item>Insects</button>
  <button mat-menu-item>Molluscs</button>
  <button mat-menu-item>Crustaceans</button>
  <button mat-menu-item>Corals</button>
  <button mat-menu-item>Arachnids</button>
  <button mat-menu-item>Velvet worms</button>
  <button mat-menu-item>Horseshoe crabs</button>
</mat-menu>

<mat-menu #fish="matMenu">
  <button mat-menu-item>Baikal oilfish</button>
  <button mat-menu-item>Bala shark</button>
  <button mat-menu-item>Ballan wrasse</button>
  <button mat-menu-item>Bamboo shark</button>
  <button mat-menu-item>Banded killifish</button>
</mat-menu>

<mat-menu #amphibians="matMenu">
  <button mat-menu-item>Sonoran desert toad</button>
  <button mat-menu-item>Western toad</button>
  <button mat-menu-item>Arroyo toad</button>
  <button mat-menu-item>Yosemite toad</button>
</mat-menu>

<mat-menu #reptiles="matMenu">
  <button mat-menu-item>Banded Day Gecko</button>
  <button mat-menu-item>Banded Gila Monster</button>
  <button mat-menu-item>Black Tree Monitor</button>
  <button mat-menu-item>Blue Spiny Lizard</button>
  <button mat-menu-item disabled>Velociraptor</button>
</mat-menu>

Upvotes: 0

Related Questions