Skip to content

Commit

Permalink
fix(modal): don't stop propagation of click events from content
Browse files Browse the repository at this point in the history
Fixes #1011

Closes #1013
  • Loading branch information
pkozlowski-opensource committed Nov 8, 2016
1 parent cd890e4 commit 6a2c074
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
9 changes: 9 additions & 0 deletions src/modal/modal-window.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ describe('ngb-modal-dialog', () => {
fixture.nativeElement.querySelector('.modal-dialog').click();
});

it('should not dismiss on modal content click when there is active backdrop', (done) => {
fixture.detectChanges();
fixture.componentInstance.dismissEvent.subscribe(
() => { done.fail(new Error('Should not trigger dismiss event')); });

fixture.nativeElement.querySelector('.modal-content').click();
setTimeout(done, 200);
});

it('should ignore backdrop clicks when there is no backdrop', (done) => {
fixture.componentInstance.backdrop = false;
fixture.detectChanges();
Expand Down
21 changes: 10 additions & 11 deletions src/modal/modal-window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
Renderer,
OnInit,
AfterViewInit,
OnDestroy
OnDestroy,
ViewChild,
} from '@angular/core';

import {ModalDismissReasons} from './modal-dismiss-reasons';
Expand All @@ -20,18 +21,20 @@ import {ModalDismissReasons} from './modal-dismiss-reasons';
'tabindex': '-1',
'style': 'display: block;',
'(keyup.esc)': 'escKey($event)',
'(click)': 'backdropClick()'
'(click)': 'backdropClick($event)'
},
template: `
<div [class]="'modal-dialog' + (size ? ' modal-' + size : '')" role="document">
<div class="modal-content" (click)="stopPropagation($event)"><ng-content></ng-content></div>
<div class="modal-content" #modalContent><ng-content></ng-content></div>
</div>
`
})
export class NgbModalWindow implements OnInit,
AfterViewInit, OnDestroy {
private _elWithFocus: Element; // element that is focused prior to modal opening

@ViewChild('modalContent') contentEl: ElementRef;

@Input() backdrop: boolean | string = true;
@Input() keyboard = true;
@Input() size: string;
Expand All @@ -41,8 +44,8 @@ export class NgbModalWindow implements OnInit,

constructor(private _elRef: ElementRef, private _renderer: Renderer) {}

backdropClick(): void {
if (this.backdrop === true) {
backdropClick($event): void {
if (this.backdrop === true && !this.contentEl.nativeElement.contains($event.target)) {
this.dismiss(ModalDismissReasons.BACKDROP_CLICK);
}
}
Expand All @@ -55,21 +58,19 @@ export class NgbModalWindow implements OnInit,

dismiss(reason): void { this.dismissEvent.emit(reason); }

stopPropagation($event: MouseEvent): void { $event.stopPropagation(); }

ngOnInit() {
this._elWithFocus = document.activeElement;
this._renderer.setElementClass(document.body, 'modal-open', true);
}

ngAfterViewInit() {
if (!this._isNodeChildOfAnother(this._elRef.nativeElement, document.activeElement)) {
if (!this._elRef.nativeElement.contains(document.activeElement)) {
this._renderer.invokeElementMethod(this._elRef.nativeElement, 'focus', []);
}
}

ngOnDestroy() {
if (this._elWithFocus && this._isNodeChildOfAnother(document.body, this._elWithFocus)) {
if (this._elWithFocus && document.body.contains(this._elWithFocus)) {
this._renderer.invokeElementMethod(this._elWithFocus, 'focus', []);
} else {
this._renderer.invokeElementMethod(document.body, 'focus', []);
Expand All @@ -78,6 +79,4 @@ export class NgbModalWindow implements OnInit,
this._elWithFocus = null;
this._renderer.setElementClass(document.body, 'modal-open', false);
}

private _isNodeChildOfAnother(parentNode, potentialChildNode) { return parentNode.contains(potentialChildNode); }
}

0 comments on commit 6a2c074

Please sign in to comment.