Skip to content

Commit

Permalink
feat(dialog): add disableClose option
Browse files Browse the repository at this point in the history
Adds a config option that allows users to disable closing a dialog via a backdrop click or pressing escape.

Fixes angular#1419.
  • Loading branch information
crisbeto committed Nov 2, 2016
1 parent 96d196a commit 13ebd1b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 14 deletions.
6 changes: 4 additions & 2 deletions src/lib/dialog/dialog-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
22 changes: 12 additions & 10 deletions src/lib/dialog/dialog-container.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
Component,
ComponentRef,
ViewChild,
ViewEncapsulation,
NgZone,
OnDestroy
Component,
ComponentRef,
ViewChild,
ViewEncapsulation,
NgZone,
OnDestroy,
ElementRef
} from '@angular/core';
import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core';
import {MdDialogConfig} from './dialog-config';
Expand All @@ -25,7 +26,7 @@ import 'rxjs/add/operator/first';
host: {
'class': 'md-dialog-container',
'[attr.role]': 'dialogConfig?.role',
'(keydown.escape)': 'handleEscapeKey()',
'(keydown.escape)': 'handleEscapeKey()'
},
encapsulation: ViewEncapsulation.None,
})
Expand All @@ -45,7 +46,7 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
/** Reference to the open dialog. */
dialogRef: MdDialogRef<any>;

constructor(private _ngZone: NgZone) {
constructor(private _ngZone: NgZone, public elementRef: ElementRef) {
super();
}

Expand Down Expand Up @@ -74,8 +75,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() {
Expand Down
34 changes: 34 additions & 0 deletions src/lib/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <HTMLElement> 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.
Expand Down
6 changes: 4 additions & 2 deletions src/lib/dialog/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ export class MdDialog {
// to modify and close it.
let dialogRef = <MdDialogRef<T>> 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;
Expand Down

0 comments on commit 13ebd1b

Please sign in to comment.