import {NgModule,Component,ElementRef,AfterViewInit,OnDestroy,Input,Output,Renderer2,HostListener,ViewChild,Inject,forwardRef} from '@angular/core'; import {CommonModule} from '@angular/common'; import {DomHandler} from '../dom/domhandler'; import {MenuItem} from '../common/menuitem'; import {RouterModule} from '@angular/router'; @Component({ selector: '[pMenuItemContent]', template: ` {{item.label}} {{item.label}} ` }) export class MenuItemContent { @Input("pMenuItemContent") item: MenuItem; constructor(@Inject(forwardRef(() => Menu)) public menu: Menu) {} } @Component({ selector: 'p-menu', template: `
`, providers: [DomHandler], host: {'(window:resize)': 'onResize($event)'} }) export class Menu implements AfterViewInit,OnDestroy { @Input() model: MenuItem[]; @Input() popup: boolean; @Input() style: any; @Input() styleClass: string; @Input() appendTo: any; @Input() autoZIndex: boolean = true; @Input() baseZIndex: number = 0; @ViewChild('container') containerViewChild: ElementRef; container: HTMLDivElement; documentClickListener: any; preventDocumentDefault: any; onResizeTarget: any; constructor(public el: ElementRef, public domHandler: DomHandler, public renderer: Renderer2) {} ngAfterViewInit() { this.container = this.containerViewChild.nativeElement; if(this.popup) { if(this.appendTo) { if(this.appendTo === 'body') document.body.appendChild(this.container); else this.domHandler.appendChild(this.container, this.appendTo); } this.documentClickListener = this.renderer.listen('document', 'click', () => { if(!this.preventDocumentDefault) { this.hide(); } this.preventDocumentDefault = false; }); } } toggle(event) { if(this.container.offsetParent) this.hide(); else this.show(event); this.preventDocumentDefault = true; } onResize(event) { if(this.onResizeTarget && this.container.offsetParent) { this.domHandler.absolutePosition(this.container, this.onResizeTarget); } } show(event) { let target = event.currentTarget; this.onResizeTarget = event.currentTarget; this.moveOnTop(); this.container.style.display = 'block'; this.domHandler.absolutePosition(this.container, target); this.domHandler.fadeIn(this.container, 250); this.preventDocumentDefault = true; } moveOnTop() { if(this.autoZIndex) { this.containerViewChild.nativeElement.style.zIndex = String(this.baseZIndex + (++DomHandler.zindex)); } } hide() { this.container.style.display = 'none'; } itemClick(event, item: MenuItem) { if(item.disabled) { event.preventDefault(); return; } if(!item.url) { event.preventDefault(); } if(item.command) { item.command({ originalEvent: event, item: item }); } if(this.popup) { this.hide(); } } ngOnDestroy() { if(this.popup) { if(this.documentClickListener) { this.documentClickListener(); } if(this.appendTo) { this.el.nativeElement.appendChild(this.container); } } } hasSubMenu(): boolean { if(this.model) { for(var item of this.model) { if(item.items) { return true; } } } return false; } } @NgModule({ imports: [CommonModule,RouterModule], exports: [Menu,RouterModule], declarations: [Menu,MenuItemContent] }) export class MenuModule { }