From 3b6fa232379fe4f7ca48bf32ce4c6223853f0ca0 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Tue, 1 Nov 2016 19:30:23 +0100 Subject: [PATCH] feat(dialog): add disableClose option Adds a config option that allows users to disable closing a dialog via a backdrop click or pressing escape. Fixes #1419. --- src/lib/dialog/dialog-config.ts | 6 ++++-- src/lib/dialog/dialog-container.ts | 19 +++++++++-------- src/lib/dialog/dialog.spec.ts | 34 ++++++++++++++++++++++++++++++ src/lib/dialog/dialog.ts | 6 ++++-- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/lib/dialog/dialog-config.ts b/src/lib/dialog/dialog-config.ts index fa6d74fb6e26..83c41cb308b8 100644 --- a/src/lib/dialog/dialog-config.ts +++ b/src/lib/dialog/dialog-config.ts @@ -14,6 +14,8 @@ export class MdDialogConfig { /** The ARIA role of the dialog element. */ role: DialogRole = 'dialog'; - // TODO(jelbourn): add configuration for size, clickOutsideToClose, lifecycle hooks, - // ARIA labelling. + /** Whether the user can use escape or clicking outside to close a modal. */ + disableClose = false; + + // TODO(jelbourn): add configuration for size, lifecycle hooks, ARIA labelling. } diff --git a/src/lib/dialog/dialog-container.ts b/src/lib/dialog/dialog-container.ts index 5f920aa0d0ca..4ef914dd5803 100644 --- a/src/lib/dialog/dialog-container.ts +++ b/src/lib/dialog/dialog-container.ts @@ -1,10 +1,10 @@ import { - Component, - ComponentRef, - ViewChild, - ViewEncapsulation, - NgZone, - OnDestroy + Component, + ComponentRef, + ViewChild, + ViewEncapsulation, + NgZone, + OnDestroy } from '@angular/core'; import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core'; import {MdDialogConfig} from './dialog-config'; @@ -25,7 +25,7 @@ import 'rxjs/add/operator/first'; host: { 'class': 'md-dialog-container', '[attr.role]': 'dialogConfig?.role', - '(keydown.escape)': 'handleEscapeKey()', + '(keydown.escape)': 'handleEscapeKey()' }, encapsulation: ViewEncapsulation.None, }) @@ -74,8 +74,9 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy { /** Handles the user pressing the Escape key. */ handleEscapeKey() { - // TODO(jelbourn): add MdDialogConfig option to disable this behavior. - this.dialogRef.close(); + if (!this.dialogConfig.disableClose) { + this.dialogRef.close(); + } } ngOnDestroy() { diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts index 6ff5b8651ee8..1477cc0bff31 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -128,6 +128,40 @@ describe('MdDialog', () => { expect(overlayContainerElement.querySelector('md-dialog-container')).toBeFalsy(); }); + describe('disableClose option', () => { + it('should prevent closing via clicks on the backdrop', () => { + let config = new MdDialogConfig(); + config.viewContainerRef = testViewContainerRef; + config.disableClose = true; + + dialog.open(PizzaMsg, config); + + viewContainerFixture.detectChanges(); + + let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop'); + backdrop.click(); + + expect(overlayContainerElement.querySelector('md-dialog-container')).toBeTruthy(); + }); + + it('should prevent closing via the escape key', () => { + let config = new MdDialogConfig(); + config.viewContainerRef = testViewContainerRef; + config.disableClose = true; + + dialog.open(PizzaMsg, config); + + viewContainerFixture.detectChanges(); + + let dialogContainer: MdDialogContainer = viewContainerFixture.debugElement.query( + By.directive(MdDialogContainer)).componentInstance; + + dialogContainer.handleEscapeKey(); + + expect(overlayContainerElement.querySelector('md-dialog-container')).toBeTruthy(); + }); + }); + describe('focus management', () => { // When testing focus, all of the elements must be in the DOM. diff --git a/src/lib/dialog/dialog.ts b/src/lib/dialog/dialog.ts index 05384daecc78..c8539a7ecb83 100644 --- a/src/lib/dialog/dialog.ts +++ b/src/lib/dialog/dialog.ts @@ -87,8 +87,10 @@ export class MdDialog { // to modify and close it. let dialogRef = > new MdDialogRef(overlayRef); - // When the dialog backdrop is clicked, we want to close it. - overlayRef.backdropClick().first().subscribe(() => dialogRef.close()); + if (!dialogContainer.dialogConfig.disableClose) { + // When the dialog backdrop is clicked, we want to close it. + overlayRef.backdropClick().first().subscribe(() => dialogRef.close()); + } // Set the dialogRef to the container so that it can use the ref to close the dialog. dialogContainer.dialogRef = dialogRef;