Skip to content

Commit

Permalink
fix(datepicker): multiple dialog open if the user holds down enter key (
Browse files Browse the repository at this point in the history
#12238)

Fixes the case where the user might be holding down the enter key for a datepicker in touch mode, which could cause it to open multiple dialogs at the same time.
  • Loading branch information
crisbeto authored and jelbourn committed Aug 23, 2018
1 parent 1b19b93 commit 8e63656
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
26 changes: 24 additions & 2 deletions src/lib/datepicker/datepicker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
dispatchMouseEvent,
} from '@angular/cdk/testing';
import {Component, FactoryProvider, Type, ValueProvider, ViewChild} from '@angular/core';
import {ComponentFixture, fakeAsync, flush, inject, TestBed} from '@angular/core/testing';
import {ComponentFixture, fakeAsync, flush, inject, TestBed, tick} from '@angular/core/testing';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {
DEC,
Expand Down Expand Up @@ -102,7 +102,7 @@ describe('MatDatepicker', () => {
expect(document.querySelector('.cdk-overlay-pane.mat-datepicker-popup')).not.toBeNull();
});

it('open touch should open dialog', () => {
it('touch should open dialog', () => {
testComponent.touch = true;
fixture.detectChanges();

Expand All @@ -115,6 +115,28 @@ describe('MatDatepicker', () => {
.not.toBeNull();
});

it('should not be able to open more than one dialog', fakeAsync(() => {
testComponent.touch = true;
fixture.detectChanges();

expect(document.querySelectorAll('.mat-datepicker-dialog').length).toBe(0);

testComponent.datepicker.open();
fixture.detectChanges();
tick(500);
fixture.detectChanges();

dispatchKeyboardEvent(document.querySelector('.mat-calendar-body')!, 'keydown', ENTER);
fixture.detectChanges();
tick(100);

testComponent.datepicker.open();
tick(500);
fixture.detectChanges();

expect(document.querySelectorAll('.mat-datepicker-dialog').length).toBe(1);
}));

it('should open datepicker if opened input is set to true', fakeAsync(() => {
testComponent.opened = true;
fixture.detectChanges();
Expand Down
8 changes: 8 additions & 0 deletions src/lib/datepicker/datepicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,14 @@ export class MatDatepicker<D> implements OnDestroy, CanColor {

/** Open the calendar as a dialog. */
private _openAsDialog(): void {
// Usually this would be handled by `open` which ensures that we can only have one overlay
// open at a time, however since we reset the variables in async handlers some overlays
// may slip through if the user opens and closes multiple times in quick succession (e.g.
// by holding down the enter key).
if (this._dialogRef) {
this._dialogRef.close();
}

this._dialogRef = this._dialog.open<MatDatepickerContent<D>>(MatDatepickerContent, {
direction: this._dir ? this._dir.value : 'ltr',
viewContainerRef: this._viewContainerRef,
Expand Down

0 comments on commit 8e63656

Please sign in to comment.