import {NgModule,Component,ElementRef,AfterViewInit,OnDestroy,Input,Output,AfterViewChecked,EventEmitter,Renderer2,ContentChild,NgZone} from '@angular/core'; import {trigger,state,style,transition,animate} from '@angular/animations'; import {CommonModule} from '@angular/common'; import {DomHandler} from '../dom/domhandler'; import {Header,Footer,SharedModule} from '../common/shared'; import {ButtonModule} from '../button/button'; import {Confirmation} from '../common/confirmation'; import {ConfirmationService} from '../common/confirmationservice'; import {Subscription} from 'rxjs/Subscription'; @Component({ selector: 'p-confirmDialog', template: `
{{header}}
`, animations: [ trigger('dialogState', [ state('hidden', style({ opacity: 0 })), state('visible', style({ opacity: 1 })), transition('visible => hidden', animate('400ms ease-in')), transition('hidden => visible', animate('400ms ease-out')) ]) ], providers: [DomHandler] }) export class ConfirmDialog implements AfterViewInit,AfterViewChecked,OnDestroy { @Input() header: string; @Input() icon: string; @Input() message: string; @Input() acceptIcon: string = 'fa-check'; @Input() acceptLabel: string = 'Yes'; @Input() acceptVisible: boolean = true; @Input() rejectIcon: string = 'fa-close'; @Input() rejectLabel: string = 'No'; @Input() rejectVisible: boolean = true; @Input() acceptButtonStyleClass: string; @Input() rejectButtonStyleClass: string; @Input() width: any; @Input() height: any; @Input() closeOnEscape: boolean = true; @Input() rtl: boolean; @Input() closable: boolean = true; @Input() responsive: boolean = true; @Input() appendTo: any; @Input() key: string; @ContentChild(Footer) footer; confirmation: Confirmation; _visible: boolean; documentEscapeListener: any; documentResponsiveListener: any; mask: any; contentContainer: any; positionInitialized: boolean; subscription: Subscription; executePostShowActions: boolean; constructor(public el: ElementRef, public domHandler: DomHandler, public renderer: Renderer2, private confirmationService: ConfirmationService, public zone: NgZone) { this.subscription = confirmationService.requireConfirmation$.subscribe(confirmation => { if(confirmation.key === this.key) { this.confirmation = confirmation; this.message = this.confirmation.message||this.message; this.icon = this.confirmation.icon||this.icon; this.header = this.confirmation.header||this.header; this.rejectVisible = this.confirmation.rejectVisible == null ? this.rejectVisible : this.confirmation.rejectVisible; this.acceptVisible = this.confirmation.acceptVisible == null ? this.acceptVisible : this.confirmation.acceptVisible; this.acceptLabel = this.confirmation.acceptLabel||this.acceptLabel; this.rejectLabel = this.confirmation.rejectLabel||this.rejectLabel; if(this.confirmation.accept) { this.confirmation.acceptEvent = new EventEmitter(); this.confirmation.acceptEvent.subscribe(this.confirmation.accept); } if(this.confirmation.reject) { this.confirmation.rejectEvent = new EventEmitter(); this.confirmation.rejectEvent.subscribe(this.confirmation.reject); } this.visible = true; } }); } @Input() get visible(): boolean { return this._visible; } set visible(val:boolean) { this._visible = val; if(this._visible) { if(!this.positionInitialized) { this.center(); this.positionInitialized = true; } this.el.nativeElement.children[0].style.zIndex = ++DomHandler.zindex; this.bindGlobalListeners(); this.executePostShowActions = true; } if(this._visible) this.enableModality(); else this.disableModality(); } ngAfterViewInit() { this.contentContainer = this.domHandler.findSingle(this.el.nativeElement, '.ui-dialog-content'); if(this.appendTo) { if(this.appendTo === 'body') document.body.appendChild(this.el.nativeElement); else this.domHandler.appendChild(this.el.nativeElement, this.appendTo); } } ngAfterViewChecked() { if(this.executePostShowActions) { this.domHandler.findSingle(this.el.nativeElement.children[0], 'button').focus(); this.executePostShowActions = false; } } center() { let container = this.el.nativeElement.children[0]; let elementWidth = this.domHandler.getOuterWidth(container); let elementHeight = this.domHandler.getOuterHeight(container); if(elementWidth == 0 && elementHeight == 0) { container.style.visibility = 'hidden'; container.style.display = 'block'; elementWidth = this.domHandler.getOuterWidth(container); elementHeight = this.domHandler.getOuterHeight(container); container.style.display = 'none'; container.style.visibility = 'visible'; } let viewport = this.domHandler.getViewport(); let x = (viewport.width - elementWidth) / 2; let y = (viewport.height - elementHeight) / 2; container.style.left = x + 'px'; container.style.top = y + 'px'; } enableModality() { if(!this.mask) { this.mask = document.createElement('div'); this.mask.style.zIndex = this.el.nativeElement.children[0].style.zIndex - 1; this.domHandler.addMultipleClasses(this.mask, 'ui-widget-overlay ui-dialog-mask'); document.body.appendChild(this.mask); this.domHandler.addClass(document.body, 'ui-overflow-hidden'); } } disableModality() { if(this.mask) { document.body.removeChild(this.mask); this.domHandler.removeClass(document.body, 'ui-overflow-hidden'); this.mask = null; } } close(event: Event) { if(this.confirmation.rejectEvent) { this.confirmation.rejectEvent.emit(); } this.hide(); event.preventDefault(); } hide() { this.visible = false; this.unbindGlobalListeners(); } moveOnTop() { this.el.nativeElement.children[0].style.zIndex = ++DomHandler.zindex; } bindGlobalListeners() { if(this.closeOnEscape && this.closable && !this.documentEscapeListener) { this.documentEscapeListener = this.renderer.listen('document', 'keydown', (event) => { if(event.which == 27) { if(this.el.nativeElement.children[0].style.zIndex == DomHandler.zindex && this.visible) { this.close(event); } } }); } if(this.responsive) { this.zone.runOutsideAngular(() => { this.documentResponsiveListener = this.center.bind(this); window.addEventListener('resize', this.documentResponsiveListener); }); } } unbindGlobalListeners() { if(this.documentEscapeListener) { this.documentEscapeListener(); this.documentEscapeListener = null; } if(this.documentResponsiveListener) { window.removeEventListener('resize', this.documentResponsiveListener); this.documentResponsiveListener = null; } } ngOnDestroy() { this.disableModality(); if(this.documentResponsiveListener) { this.documentResponsiveListener(); } if(this.documentEscapeListener) { this.documentEscapeListener(); } if(this.appendTo && this.appendTo === 'body') { document.body.removeChild(this.el.nativeElement); } this.subscription.unsubscribe(); } accept() { if(this.confirmation.acceptEvent) { this.confirmation.acceptEvent.emit(); } this.hide(); this.confirmation = null; } reject() { if(this.confirmation.rejectEvent) { this.confirmation.rejectEvent.emit(); } this.hide(); this.confirmation = null; } } @NgModule({ imports: [CommonModule,ButtonModule], exports: [ConfirmDialog,ButtonModule,SharedModule], declarations: [ConfirmDialog] }) export class ConfirmDialogModule { }