Skip to content

Commit 7714374

Browse files
committed
fix(datepicker): reformat valid values on blur
Formats valid values, that were typed into the datepicker, when the user blur the input. Invalid values won't be changed. Fixes #10645.
1 parent a6ffd18 commit 7714374

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

src/lib/datepicker/datepicker-input.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class MatDatepickerInputEvent<D> {
8787
'[disabled]': 'disabled',
8888
'(input)': '_onInput($event.target.value)',
8989
'(change)': '_onChange()',
90-
'(blur)': '_onTouched()',
90+
'(blur)': '_onBlur()',
9191
'(keydown)': '_onKeydown($event)',
9292
},
9393
exportAs: 'matDatepickerInput',
@@ -123,10 +123,10 @@ export class MatDatepickerInput<D> implements AfterContentInit, ControlValueAcce
123123
value = this._dateAdapter.deserialize(value);
124124
this._lastValueValid = !value || this._dateAdapter.isValid(value);
125125
value = this._getValidDateOrNull(value);
126-
let oldDate = this.value;
126+
const oldDate = this.value;
127127
this._value = value;
128-
this._elementRef.nativeElement.value =
129-
value ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : '';
128+
this._formatValue(value);
129+
130130
if (!this._dateAdapter.sameDate(oldDate, value)) {
131131
this._valueChange.emit(value);
132132
}
@@ -343,6 +343,22 @@ export class MatDatepickerInput<D> implements AfterContentInit, ControlValueAcce
343343
return this._formField ? this._formField.color : undefined;
344344
}
345345

346+
/** Handles blur events on the input. */
347+
_onBlur() {
348+
// Reformat the input only if we have a valid value.
349+
if (this.value) {
350+
this._formatValue(this.value);
351+
}
352+
353+
this._onTouched();
354+
}
355+
356+
/** Formats a value and sets it on the input element. */
357+
private _formatValue(value: D | null) {
358+
this._elementRef.nativeElement.value =
359+
value ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : '';
360+
}
361+
346362
/**
347363
* @param obj The object to check.
348364
* @returns The given object if it is both a date instance and valid, otherwise null.

src/lib/datepicker/datepicker.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,32 @@ describe('MatDatepicker', () => {
663663
expect(inputEl.classList).toContain('ng-touched');
664664
});
665665

666+
it('should reformat the input value on blur', () => {
667+
const inputEl = fixture.debugElement.query(By.css('input')).nativeElement;
668+
669+
inputEl.value = '1 1 2001';
670+
dispatchFakeEvent(inputEl, 'input');
671+
fixture.detectChanges();
672+
673+
dispatchFakeEvent(inputEl, 'blur');
674+
fixture.detectChanges();
675+
676+
expect(inputEl.value).toBe('1/1/2001');
677+
});
678+
679+
it('should not reformat invalid dates on blur', () => {
680+
const inputEl = fixture.debugElement.query(By.css('input')).nativeElement;
681+
682+
inputEl.value = 'very-valid-date';
683+
dispatchFakeEvent(inputEl, 'input');
684+
fixture.detectChanges();
685+
686+
dispatchFakeEvent(inputEl, 'blur');
687+
fixture.detectChanges();
688+
689+
expect(inputEl.value).toBe('very-valid-date');
690+
});
691+
666692
it('should mark input touched on calendar selection', fakeAsync(() => {
667693
let inputEl = fixture.debugElement.query(By.css('input')).nativeElement;
668694

0 commit comments

Comments
 (0)