Skip to content

Commit

Permalink
fix(input): take the control validators in consideration on blur #1144
Browse files Browse the repository at this point in the history
  • Loading branch information
DDavidkov committed Jun 26, 2018
1 parent db072e0 commit 13e6501
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 17 deletions.
71 changes: 68 additions & 3 deletions src/directives/input/input.directive.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, ViewChild } from "@angular/core";
import { async, TestBed } from "@angular/core/testing";
import { FormsModule } from "@angular/forms";
import { FormBuilder, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms";
import { By } from "@angular/platform-browser";
import { IgxInputGroupComponent, IgxInputGroupModule } from "../../input-group/input-group.component";
import { IgxInputDirective, IgxInputState } from "./input.directive";
Expand Down Expand Up @@ -28,11 +28,13 @@ describe("IgxInput", () => {
DisabledInputComponent,
RequiredInputComponent,
RequiredTwoWayDataBoundInputComponent,
DataBoundDisabledInputComponent
DataBoundDisabledInputComponent,
ReactiveFormComponent
],
imports: [
IgxInputGroupModule,
FormsModule
FormsModule,
ReactiveFormsModule
]
})
.compileComponents();
Expand Down Expand Up @@ -162,6 +164,20 @@ describe("IgxInput", () => {
const inputElement = fixture.debugElement.query(By.directive(IgxInputDirective)).nativeElement;
testRequiredValidation(inputElement, fixture);
});

it("Should work properly with reactive forms validation.", () => {
const fixture = TestBed.createComponent(ReactiveFormComponent);
fixture.detectChanges();

fixture.debugElement.componentInstance.markAsTouched();
fixture.detectChanges();

const invalidInputGroups = fixture.debugElement.nativeElement.querySelectorAll(`.igx-input-group--invalid`);
expect(invalidInputGroups.length).toBe(4);

const requiredInputGroups = fixture.debugElement.nativeElement.querySelectorAll(`.igx-input-group--required`);
expect(requiredInputGroups.length).toBe(4);
});
});

@Component({ template: `<igx-input-group #igxInputGroup>
Expand Down Expand Up @@ -239,6 +255,55 @@ class DataBoundDisabledInputComponent {
public isDisabled = false;
}

@Component({
template:
`<form class="wrapper" [formGroup]="form">
<section>
<igx-input-group>
<label igxLabel>single line</label>
<input type="text" formControlName="str" igxInput>
</igx-input-group>
<br>
<igx-input-group>
<label igxLabel>multi line</label>
<textarea type="text" formControlName="textarea" igxInput></textarea>
</igx-input-group>
<br>
<igx-input-group>
<label igxLabel>password</label>
<input type="password" formControlName="password" igxInput>
</igx-input-group>
</section>
<section>
<igx-input-group>
<label igxLabel>1000</label>
<input type="number" formControlName="num" igxInput igxMask="###">
</igx-input-group>
</section>
</form>`
})
class ReactiveFormComponent {
form = this.fb.group({
str: ["", Validators.required],
textarea: ["", Validators.required],
password: ["", Validators.required],
num: [null, Validators.required]
});

constructor(private fb: FormBuilder) { }

public markAsTouched() {
if (!this.form.valid) {
for (const key in this.form.controls) {
if (this.form.controls[key]) {
this.form.controls[key].markAsTouched();
this.form.controls[key].updateValueAndValidity();
}
}
}
}
}

function testRequiredValidation(inputElement, fixture) {
dispatchInputEvent("focus", inputElement, fixture);
inputElement.value = "test";
Expand Down
27 changes: 13 additions & 14 deletions src/directives/input/input.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
Optional,
Self
} from "@angular/core";
import { FormControlName, NgControl, NgModel } from "@angular/forms";
import { AbstractControl, FormControlName, NgControl, NgModel } from "@angular/forms";
import { Subscription } from "rxjs";
import { IgxInputGroupComponent } from "../../input-group/input-group.component";

Expand Down Expand Up @@ -77,8 +77,8 @@ export class IgxInputDirective implements AfterViewInit, OnDestroy {
public onBlur(event) {
this.inputGroup.isFocused = false;
this._valid = IgxInputState.INITIAL;
if (this.ngModel) {
if (!this.ngModel.valid) {
if (this.ngControl) {
if (!this.ngControl.valid) {
this._valid = IgxInputState.INVALID;
}
} else if (this._hasValidators() && !this.nativeElement.checkValidity()) {
Expand All @@ -96,16 +96,15 @@ export class IgxInputDirective implements AfterViewInit, OnDestroy {
}

ngAfterViewInit() {
if (this.nativeElement.hasAttribute("placeholder")) {
this.inputGroup.hasPlaceholder = true;
}

if (this.nativeElement.hasAttribute("required")) {
this.inputGroup.isRequired = true;
}

if (this.nativeElement.hasAttribute("disabled")) {
this.inputGroup.isDisabled = true;
this.inputGroup.hasPlaceholder = this.nativeElement.hasAttribute("placeholder");
this.inputGroup.isDisabled = this.nativeElement.hasAttribute("disabled");
this.inputGroup.isRequired = this.nativeElement.hasAttribute("required");

// Also check the control's validators for required
if (!this.inputGroup.isRequired && this.ngControl && this.ngControl.control.validator) {
// tslint:disable-next-line:no-object-literal-type-assertion
const validation = this.ngControl.control.validator({} as AbstractControl);
this.inputGroup.isRequired = validation && validation.required;
}

if ((this.nativeElement.value && this.nativeElement.value.length > 0) ||
Expand Down Expand Up @@ -167,7 +166,7 @@ export class IgxInputDirective implements AfterViewInit, OnDestroy {
}
}

return false;
return this.ngControl && !!this.ngControl.control.validator || !!this.ngControl.control.asyncValidator;
}

public get focused() {
Expand Down

0 comments on commit 13e6501

Please sign in to comment.