From a62cdb66edc06a55f1a1ce48c488b057cc6eec83 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 10 May 2018 18:26:49 +0200 Subject: [PATCH] fix(datepicker): dateInput event being fired if the value hasn't changed (#10952) Fixes the `dateInput` event being fired even if the value hasn't changed. This can happen if the browser fires the `input` event while the value hasn't changed (e.g. if the user marks a character and "replaces" it with the same character). --- src/lib/datepicker/datepicker-input.ts | 11 +++++++---- src/lib/datepicker/datepicker.spec.ts | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/lib/datepicker/datepicker-input.ts b/src/lib/datepicker/datepicker-input.ts index 7784c6c9ce9..82cdbf1ba29 100644 --- a/src/lib/datepicker/datepicker-input.ts +++ b/src/lib/datepicker/datepicker-input.ts @@ -328,10 +328,13 @@ export class MatDatepickerInput implements AfterContentInit, ControlValueAcce let date = this._dateAdapter.parse(value, this._dateFormats.parse.dateInput); this._lastValueValid = !date || this._dateAdapter.isValid(date); date = this._getValidDateOrNull(date); - this._value = date; - this._cvaOnChange(date); - this._valueChange.emit(date); - this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement)); + + if (!this._dateAdapter.sameDate(date, this._value)) { + this._value = date; + this._cvaOnChange(date); + this._valueChange.emit(date); + this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement)); + } } _onChange() { diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts index eb984e927a3..c4297e6090b 100644 --- a/src/lib/datepicker/datepicker.spec.ts +++ b/src/lib/datepicker/datepicker.spec.ts @@ -627,6 +627,7 @@ describe('MatDatepicker', () => { expect(inputEl.classList).toContain('ng-pristine'); + inputEl.value = '2001-01-01'; dispatchFakeEvent(inputEl, 'input'); fixture.detectChanges(); @@ -1132,6 +1133,7 @@ describe('MatDatepicker', () => { expect(testComponent.onInput).not.toHaveBeenCalled(); expect(testComponent.onDateInput).not.toHaveBeenCalled(); + inputEl.value = '2001-01-01'; dispatchFakeEvent(inputEl, 'input'); fixture.detectChanges(); @@ -1179,6 +1181,22 @@ describe('MatDatepicker', () => { expect(testComponent.onDateInput).toHaveBeenCalled(); }) ); + + it('should not fire the dateInput event if the value has not changed', () => { + expect(testComponent.onDateInput).not.toHaveBeenCalled(); + + inputEl.value = '12/12/2012'; + dispatchFakeEvent(inputEl, 'input'); + fixture.detectChanges(); + + expect(testComponent.onDateInput).toHaveBeenCalledTimes(1); + + dispatchFakeEvent(inputEl, 'input'); + fixture.detectChanges(); + + expect(testComponent.onDateInput).toHaveBeenCalledTimes(1); + }); + }); describe('with ISO 8601 strings as input', () => {