I have an angular reactive form with default Validation.required
and a CustomValidation
.
Inside the CustomValidation
I intended to check if the control is touched, but somehow this is not working.
import {
CustomValidation
} from './CustomValidator';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
customForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.customForm = this.fb.group({
customInput: [
'', [Validators.required, CustomValidation.customEmailValidation()],
],
});
}
}
// CustomValidation.ts
import {
AbstractControl,
ValidationErrors,
ValidatorFn
} from '@angular/forms';
export class CustomValidation {
static customEmailValidation(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (control.touched && control.value.length === 0) {
console.log(control);
return {
customError: {
hasError: true,
errorType: 'empty field', // this can be any name
errorLabel: 'test',
},
};
}
return null;
};
}
}
<form [formGroup]="customForm">
<input formControlName="customInput" />
<button [disabled]="this.customForm.invalid">Submit</button>
</form>
I am expecting that the console.log inside the static method customEmailValidation
will log the control object when the field will be touched. By touch I mean, I only click on the input.But that is not happening.
I also tried using updateOn
customInput: ['', {validators:[CustomValidation.customEmailValidation(),Validators.required],updateOn:"blur"}]
Please help me in understanding why it is not working.
CodePudding user response:
At first, before you touch it, form.touched is false. So thats the first value.
That value is being taken for the first time as form.touched
So you will get touched property as false.
If you intend to make it touched, just go with
this.form.markAsTouched()
and then do the logic.
CodePudding user response:
You are describing the onfocus
event, not the touched
state.
From the Angular docs:
touched: boolean Read-Only True if the control is marked as touched.
A control is marked touched once the user has triggered a blur event on it.
You are expecting this:
By touch I mean, I only click on the input.But that is not happening.
Also, the custom validator should be agnostic to the form input state. You can achieve what you want by binding to the onfocus
event. I don't understand why you would want to do this from a UX perspective, but hey.
Template
<form (focusin)="onFocusIn($event)" [formGroup]="customForm">
<input formControlName="customInput" />
<button [disabled]="this.customForm.invalid">Submit</button>
</form>
<span *ngIf="this.customForm.invalid && this.customForm.touched"
>VERY SERIOUS ERROR</span
>
Component
onFocusIn(event) {
this.customForm.markAsTouched();
console.log('focus');
}
Validator
static customEmailValidation(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (control.value.length === 0) {
console.log(control);
return {
// ...control.errors,
customError: {
hasError: true,
errorType: 'empty field', // this can be any name
errorLabel: 'test',
},
};
}
return null;
};
}
You can read more about custom form controls here from the Angular docs.