Reputation: 105
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
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
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>
Upvotes: 0
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> 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>
Upvotes: 2
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
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