Now on clicking of the hamburger menu i am getting drop down list instead i need it on mouse hover on hamburger menu here is the stack blitz link.
You can do this using matMenuTrigger
Directive
<button mat-icon-button [matMenuTriggerFor]="menu"
#menuTrigger="matMenuTrigger" (mouseenter)="menuTrigger.openMenu()">
To hide menu, add mouseleave
event for a menu.
Bundle all your menu items within a span
or div
tag. And then attach (mouseleave)
event to it
<mat-menu #menu="matMenu" [overlapTrigger]="false">
<span (mouseleave)="menuTrigger.closeMenu()">
<button mat-menu-item>
<mat-icon>home</mat-icon>
<span>Home</span>
........
<mat-icon>exit_to_app</mat-icon>
<span>Logout</span>
</button>
</span>
</mat-menu>
Forked DEMO
I know I am very late to the party, but none of the above really did the trick for me. I ended up writing a directive so solve this issue for me.
HoverDropDownDirective
import { NgModule } from '@angular/core';
import { Directive, Input, ElementRef, OnInit } from '@angular/core';
import { MatMenuTrigger, _MatMenu } from '@angular/material';
@Directive({
selector: '[hoverDropDown]'
})
export class HoverDropDownDirective implements OnInit {
isInHoverBlock = false;
constructor(private el: ElementRef) {}
@Input() hoverTrigger: MatMenuTrigger;
@Input() menu: any;
ngOnInit() {
this.el.nativeElement.addEventListener('mouseenter', () => {
this.setHoverState(true);
this.hoverTrigger.openMenu();
const openMenu = document.querySelector(`.mat-menu-after.${this.menu._elementRef.nativeElement.className}`);
if (!openMenu) {
this.hoverTrigger.closeMenu();
return;
}
openMenu.addEventListener('mouseenter', () => {
this.setHoverState(true);
});
openMenu.addEventListener('mouseleave', () => {
this.setHoverState(false);
});
});
this.el.nativeElement.addEventListener('mouseleave', () => {
this.setHoverState(false);
});
}
private setHoverState(isInBlock: boolean) {
this.isInHoverBlock = isInBlock;
if (!isInBlock) {
this.checkHover();
}
}
private checkHover() {
setTimeout(() => {
if (!this.isInHoverBlock && this.hoverTrigger.menuOpen) {
this.hoverTrigger.closeMenu();
}
}, 50);
}
}
@NgModule({
declarations: [
HoverDropDownDirective
],
exports: [
HoverDropDownDirective
]
})
export class HoverDropDownDirectiveModule {}
app.module
import { HoverDropDownDirectiveModule } from '../../directives/hover-drop-down.directive';
imports: [
HoverDropDownDirectiveModule
]
HTML
<div *ngFor="let category of categories">
<button #menuTrigger="matMenuTrigger"
mat-button
[matMenuTriggerFor]="children"
(click)="navigateMain(category.Category)"
hoverDropDown
[menu]="children"
[hoverTrigger]="menuTrigger">
{{category.Category.Description}}
</button>
<mat-menu #children="matMenu" hasBackdrop="false">
<button mat-menu-item *ngFor="let sub of category.SubCategories" (click)="navigateSubCategory(sub)">{{sub.Description}}</button>
</mat-menu>
</div>
2 things to note:
hasBackdrop="false"
attribute in the mat-menuThe hasBackdrop="false"
attribute is documented on Angular Material. Hope this works for you...
Add a reference variable for the mat button, use to fire click
on a mouseover
event.
<button mat-icon-button
#matBtn
(mouseover)="matBtn._elementRef.nativeElement.click()"
[matMenuTriggerFor]="menu"
>
Note: I really don't prefer accessing "private" properties of an object like this, this solution of mine is more of a workaround, please use this if you don't find any other.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With