diff --git a/src/lib/dialog/dialog-config.ts b/src/lib/dialog/dialog-config.ts index 155f2a665bdf..14c972cf71f9 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..adf1ffb1a9b0 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'; @@ -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 133cab843674..a233d339763d 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -136,12 +136,47 @@ describe('MdDialog', () => { viewContainerFixture.detectChanges(); - let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop'); + let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop') as HTMLElement; backdrop.click(); 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') as HTMLElement; + 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; + + // Fake the user pressing the escape key by calling the handler directly. + 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 59c3dbdcbbdf..918a9c2b63c1 100644 --- a/src/lib/dialog/dialog.ts +++ b/src/lib/dialog/dialog.ts @@ -88,8 +88,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;