Skip to content

Commit

Permalink
fix(datepicker): not marking as dirty when invalid value is typed in (#…
Browse files Browse the repository at this point in the history
…19730)

Currently we only mark the datepicker's `ControlValueAccessor` as dirty if the value changed as a result of the user typing something in. The problem is that typing in an invalid value is parsed to `null` which is the same as the default value, causing it not to be marked as dirty. One small complication here that I've added a test for is that we shouldn't be dispatching change events when typing in invalid values.

Fixes #19726.
  • Loading branch information
crisbeto authored and jelbourn committed Jun 29, 2020
1 parent 0a22e0f commit 590fdd2
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/material/datepicker/datepicker-input-base.ts
Expand Up @@ -307,8 +307,16 @@ export abstract class MatDatepickerInputBase<S, D = ExtractDateTypeFromSelection
this._cvaOnChange(date);
this._valueChange.emit(date);
this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));
} else if (lastValueWasValid !== this._lastValueValid) {
this._validatorOnChange();
} else {
// Call the CVA change handler for invalid values
// since this is what marks the control as dirty.
if (value && !this.value) {
this._cvaOnChange(date);
}

if (lastValueWasValid !== this._lastValueValid) {
this._validatorOnChange();
}
}
}

Expand Down
26 changes: 26 additions & 0 deletions src/material/datepicker/datepicker.spec.ts
Expand Up @@ -763,6 +763,18 @@ describe('MatDatepicker', () => {
expect(inputEl.classList).toContain('ng-dirty');
}));

it('should mark input dirty after invalid value is typed in', () => {
let inputEl = fixture.debugElement.query(By.css('input'))!.nativeElement;

expect(inputEl.classList).toContain('ng-pristine');

inputEl.value = 'hello there';
dispatchFakeEvent(inputEl, 'input');
fixture.detectChanges();

expect(inputEl.classList).toContain('ng-dirty');
});

it('should not mark dirty after model change', fakeAsync(() => {
let inputEl = fixture.debugElement.query(By.css('input'))!.nativeElement;

Expand Down Expand Up @@ -1504,6 +1516,20 @@ describe('MatDatepicker', () => {
expect(valueDuringChangeEvent).toBe('1/1/2020');
});

it('should not fire dateInput when typing an invalid value', () => {
expect(testComponent.onDateInput).not.toHaveBeenCalled();

inputEl.value = 'a';
dispatchFakeEvent(inputEl, 'input');
fixture.detectChanges();
expect(testComponent.onDateInput).not.toHaveBeenCalled();

inputEl.value = 'b';
dispatchFakeEvent(inputEl, 'input');
fixture.detectChanges();
expect(testComponent.onDateInput).not.toHaveBeenCalled();
});

});

describe('with ISO 8601 strings as input', () => {
Expand Down

0 comments on commit 590fdd2

Please sign in to comment.