From 0bede63d33127d5a9ac0370307486ff50e492e9d Mon Sep 17 00:00:00 2001 From: Dmytro Prokhorov <diprokon@gmail.com> Date: Thu, 5 May 2022 23:31:33 +0300 Subject: [PATCH] fix(material/datepicker): add ability to have numeric zero value in input (#24813) * fix(material/datepicker): add ability to have numeric zero value in input Shows valid formatted value for 'falsy' values (exp 0) Custom DateAdapter (exp TimestampDateAdapter) can have valid numeric 0 value (for timestamp it is 1/1/1970), but datepicker input doesn't show formatted value * fix(material/datepicker): add ability to have numeric zero value in input Add tests (cherry picked from commit 5f4d7e2ee70c4451ce3eaf6f6905db7d17d3a7ce) --- .../datepicker/datepicker-input-base.ts | 5 ++-- .../datepicker-input-harness-shared.spec.ts | 27 ++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/material/datepicker/datepicker-input-base.ts b/src/material/datepicker/datepicker-input-base.ts index e8065b7b1e71..ff4f8b910ad2 100644 --- a/src/material/datepicker/datepicker-input-base.ts +++ b/src/material/datepicker/datepicker-input-base.ts @@ -344,9 +344,8 @@ export abstract class MatDatepickerInputBase<S, D = ExtractDateTypeFromSelection /** Formats a value and sets it on the input element. */ protected _formatValue(value: D | null) { - this._elementRef.nativeElement.value = value - ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) - : ''; + this._elementRef.nativeElement.value = + value != null ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : ''; } /** Assigns a value to the model. */ diff --git a/src/material/datepicker/testing/datepicker-input-harness-shared.spec.ts b/src/material/datepicker/testing/datepicker-input-harness-shared.spec.ts index 4105cdd525c2..0513cb32cb34 100644 --- a/src/material/datepicker/testing/datepicker-input-harness-shared.spec.ts +++ b/src/material/datepicker/testing/datepicker-input-harness-shared.spec.ts @@ -1,7 +1,7 @@ import {HarnessLoader, parallel} from '@angular/cdk/testing'; import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed'; import {Component} from '@angular/core'; -import {MatNativeDateModule} from '@angular/material/core'; +import {DateAdapter, MatNativeDateModule} from '@angular/material/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {FormsModule} from '@angular/forms'; import {MatDatepickerModule} from '@angular/material/datepicker'; @@ -86,6 +86,31 @@ export function runDatepickerInputHarnessTests( expect(await input.getValue()).toBe('1/1/2020'); }); + it('should set the input value based on date adapter validation and formatting', async () => { + const adapter = fixture.debugElement.injector.get(DateAdapter); + const input = await loader.getHarness(datepickerInputHarness.with({selector: '#basic'})); + const validValues: any[] = [new Date(0), '', 0, false]; + const invalidValues: any[] = [null, undefined]; + spyOn(adapter, 'format').and.returnValue('FORMATTED_VALUE'); + spyOn(adapter, 'isValid').and.callFake(value => validValues.includes(value)); + spyOn(adapter, 'deserialize').and.callFake(value => + validValues.includes(value) ? value : null, + ); + spyOn(adapter, 'getValidDateOrNull').and.callFake(value => + adapter.isValid(value) ? value : null, + ); + + for (let value of validValues) { + fixture.componentInstance.date = value; + expect(await input.getValue()).toBe('FORMATTED_VALUE'); + } + + for (let value of invalidValues) { + fixture.componentInstance.date = value; + expect(await input.getValue()).toBe(''); + } + }); + it('should get the input placeholder', async () => { const inputs = await loader.getAllHarnesses(datepickerInputHarness); expect(