From cb32ff270ee10e22c73159d51a30d54af1359d37 Mon Sep 17 00:00:00 2001 From: Ivan Donchev Date: Thu, 20 Oct 2022 13:54:18 +0300 Subject: [PATCH] fix(forms): remove touched enforcement This was a bug fix for old issue with input type=number that is not reproducible anymore. It causes extra valueChanged events on blur after upgrade to Angular v14. closes #337 Signed-off-by: Ivan Donchev --- .../src/forms/common/wrapped-control.spec.ts | 6 +-- .../src/forms/common/wrapped-control.ts | 7 --- .../angular/src/forms/input/input.spec.ts | 46 ++++++++++++++++++- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/projects/angular/src/forms/common/wrapped-control.spec.ts b/projects/angular/src/forms/common/wrapped-control.spec.ts index 076de8bbdf..b3f81ac1ae 100644 --- a/projects/angular/src/forms/common/wrapped-control.spec.ts +++ b/projects/angular/src/forms/common/wrapped-control.spec.ts @@ -352,14 +352,14 @@ export default function (): void { expect(this.input.getAttribute('aria-describedby')).toBe(null); }); - it('adds the aria-describedby for error messages', function (this: TestContext) { + it('adds the aria-describedby for error messages', fakeAsync(function (this: TestContext) { setupTest(this, WithControlAndError, TestControl3); this.input.focus(); this.input.blur(); this.fixture.detectChanges(); - + tick(); expect(this.input.getAttribute('aria-describedby')).toContain('-error'); - }); + })); it('does not set aria-describedby unless error helper is present', function () { setupTest(this, WithControl, TestControl3); diff --git a/projects/angular/src/forms/common/wrapped-control.ts b/projects/angular/src/forms/common/wrapped-control.ts index a536c0a1da..0cd098d386 100644 --- a/projects/angular/src/forms/common/wrapped-control.ts +++ b/projects/angular/src/forms/common/wrapped-control.ts @@ -103,13 +103,6 @@ export class WrappedFormControl implements OnInit, OnD @HostListener('blur') triggerValidation() { if (this.ifControlStateService) { - /** - * For some reason the on blur ngControl doesn't set the control to 'touched' - * This one is a workaround to provide the control to be 'touched' on blur and fix #4480. - */ - if (this.ngControl && !this.ngControl.touched) { - this.markAsTouched(); - } this.ifControlStateService.triggerStatusChange(); } } diff --git a/projects/angular/src/forms/input/input.spec.ts b/projects/angular/src/forms/input/input.spec.ts index 66efd488e2..77157fdd51 100644 --- a/projects/angular/src/forms/input/input.spec.ts +++ b/projects/angular/src/forms/input/input.spec.ts @@ -5,8 +5,11 @@ */ import { Component } from '@angular/core'; -import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { TestBed } from '@angular/core/testing'; +import { FormControl, FormGroup, FormsModule, NgControl, ReactiveFormsModule, Validators } from '@angular/forms'; +import { By } from '@angular/platform-browser'; +import { ClrCommonFormsModule } from '../common'; import { ControlStandaloneSpec, ReactiveSpec, TemplateDrivenSpec } from '../tests/control.spec'; import { ClrInput } from './input'; import { ClrInputContainer } from './input-container'; @@ -39,5 +42,46 @@ export default function (): void { ControlStandaloneSpec(StandaloneUseTest); TemplateDrivenSpec(ClrInputContainer, ClrInput, TemplateDrivenTest, 'clr-input'); ReactiveSpec(ClrInputContainer, ClrInput, ReactiveTest, 'clr-input'); + inputSpec('tempate-driven', ClrInputContainer, ClrInput, TemplateDrivenTest); + inputSpec('reactive', ClrInputContainer, ClrInput, ReactiveTest); + }); +} + +function inputSpec(description, testContainer, testControl, testComponent) { + describe('Input specific value change tests ' + description, () => { + let control, fixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [FormsModule, ClrCommonFormsModule, ReactiveFormsModule], + declarations: [testContainer, testControl, testComponent], + }); + fixture = TestBed.createComponent(testComponent); + control = fixture.debugElement.query(By.directive(testControl)); + fixture.detectChanges(); + }); + + it('should handle valueChanges calls', () => { + // control must be both invalid and blurred to register the validity + let valueChanges = 0; + control.injector.get(NgControl).control.valueChanges.subscribe(() => { + valueChanges++; + }); + + // make sure blur alone does not trigger valueChanges + control.nativeElement.dispatchEvent(new Event('focus')); + control.nativeElement.dispatchEvent(new Event('blur')); + fixture.detectChanges(); + expect(valueChanges).toBe(0); + + // now make sure input change triggers valueChanges + control.nativeElement.dispatchEvent(new Event('focus')); + control.nativeElement.value = 'abc'; + + control.nativeElement.dispatchEvent(new Event('input')); + control.nativeElement.dispatchEvent(new Event('blur')); + fixture.detectChanges(); + expect(valueChanges).toBe(1); + }); }); }