BUG - First time validation doesn't show error until you tab out.
Example:
An input that only admits one digit (pattern[0-9])
First time:
you write "Hello" and there is no error shown until you tab out.
Second time:
you erase "hello" and write "9" then the error disappear immediately
Third time:
you erase "9" and write again "hello" then the error appears immediately with no need of tabbing out.
Field show error from the first time you write an incorrect value. There is no need of tabbing out once.
Field show error only after having tabbing out one time.
https://stackblitz.com/edit/material2-input-first-time-validation
Inform the user immediately of an wrong field value with no distinction if you tab out once or not.
Angular: ~4.4.3
Material: 2.0.0-beta.11
OS: Win10
TypeScript: ~2.4.0
Browsers: All browsers
Per the spec, the default error behavior is to wait until the invalid input has been touched. You can customize it to show when dirty if you wish.
Yes, you right, thank you 馃憤
@willshowell are you referring to this line: { provide: ErrorStateMatcher, useClass: ShowOnDirtyErrorStateMatcher }? As this is not working for me, I was wondering how one can use it.
Edit: i made it working using the following
Object.keys(elementForm.controls).map((controlName) => {
elementForm.get(controlName).markAsDirty({onlySelf: true});
});
But this does seem overkill to me, any better way of doing this without looping over all the form fields with map method?
@cmddavid what exactly are you trying to do?
This Stackblitz demonstrates showing errors when dirty instead of touched.
This Stackblitz (taken from the docs site) demonstrates showing errors when dirty OR touched.
@willshowell i made a form that gets pre populated by using patchValue. Problem was the form did get marked as INVALID, but the Material2 components didnt mark the individual fields as invalid. As a result the user couldn't see what field had an error. Only if you would touch an invalid field, it would become "red". So this has now been solved, but I was surprised fixing this required looping over all the fields. I thought something like:
elementForm.markAsDirty();
Should mark the complete form as dirty.
@cmddavid The docs for markAsDirty say,
This will also mark all direct ancestors as
dirtyto maintain the model.
So it looks like marking bubbles up to ancestors but does not affect child controls.
If you're not satisfied with looping over all the controls manually, a more elegant solution might be to use your own custom ErrorStateMatcher. As you may know, the default one only shows mat-errors when the control is touched AND invalid. You could provide one that shows errors any time the control is invalid at all!
@willshowell that sounds like a great idea. I'm using the form to validate a csv import file before sending it to the server(so one can correct mistakes as well). So thats why every little speed bump can help to make the experience better. As a csv file could easily result in thousands reactive forms, you can imagine the impact of having to loop over all those controls.
this is working perfectly for me:
on form submit:
if (!this.elementForm.valid) {
Object.keys(this.elementForm.controls).forEach(field => {
const control = this.elementForm.get(field);
control.markAsTouched({ onlySelf: true });
});
return;
}
this is working perfectly for me:
on form submit:
if (!this.elementForm.valid) {
Object.keys(this.elementForm.controls).forEach(field => {
const control = this.elementForm.get(field);
control.markAsTouched({ onlySelf: true });
});
return;
}
worked for me, thanks
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._