ngneat / error-tailor

🦄 Making sure your tailor-made error solution is seamless!

Home Page:https://netbasal.com/make-your-angular-forms-error-messages-magically-appear-1e32350b7fa5

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Messages don't show up after markAsTouched

stephengeorgewest-navitaire opened this issue · comments

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Messages don't show up after formGroup.markAllAsTouched(); or formGroup.controls[control].markAsTouched();. Though, angular material highlights the invalid fields.

Expected behavior

Messages should show up after markAsTouched.

Minimal reproduction of the problem with instructions

https://stackblitz.com/edit/error-tailor-mark-as-touched

What is the motivation / use case for changing the behavior?

Highlighting invalid fields after validation requirements have changed, and the user revisits the form to correct previously valid but now invalid sections.

Environment


Angular version: 13.3.5


Browser:
- [ x ] Chrome (desktop) version 100.0.4896.127
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ x ] Firefox version 99.0.1
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 16.13.2
- Platform:  Windows

Others:

I'm still looking into the source to see if I can submit a decent PR. As a workaround I put lots of #errorTailor="errorTailor" in the template with

@ViewChildren("errorTailor") private _errorTailor!: QueryList<ControlErrorsDirective>;

public ngAfterViewInit(): void {
    this._errorTailor.forEach(e => e.showError());
}
public ngOnChanges(changes: SimpleChanges) {
     this._setupForm();
     this.formGroup?.markAllAsTouched();
}

I looked into passing the control's touched status into the error control component, but none of the observables on form controls emit touched changes. Perhaps it could be added to the formcontrol -> status, but that is an upstream change.

I also looked into always populating the control-error component hidden by default and just using the .ng-touched class that is already put on the inputs, to show it, But the .ng-touched are siblings to the control-error, so that needs a view-encasulation setting .
image

image

Downside is that the custom classes passed in probably expect the control-error component to exist later.
image
image

What's the use case of calling touch without submit?

We don't want to submit the form on initialization, I'm pretty sure we can't (well, maybe through formgroup.parent.parent). I'm only working on one formgroup (well an array of formgroups but all under one formControl), which has the "show validation errors on startup" requirement. The other controls on the main form section always have the same validation, and is managed by another team. The form as a whole doesn't care what we put on our section. We don't even have access to the form submit function, we get access to the submitted data after form submit via actions in the redux store, which only happens if the whole form is valid. We can then submit the data from our section of the form to our servers, while they send the outer data to their servers.

I guess if we had access to the whole form, we could do a form submit after initialization, and ignore the first submit in the submit function.

@NetanelBasal This feature is interesting for us too. We do not allow submitting the form by default. In our case If the user selects a radio button, which changes the validators and so we want to display the error instant (fields are markes as touched). So it would be greate to consider such a feature.

I don't mind seeing a PR.

I successfully tested a couple of possible solutions to listen for when a control becomes touched. One involves checking the touched property in ngDoCheck() (if properly set up shouldn't be a performance burden), the other one is setting up a MutationObserver and rely on the presence of the ng-touched class on the control.

@NetanelBasal Any thoughts? If you're still interested, I can give it a try and open a PR. Let me know!

@NetanelBasal To make sure I don't miss anything, in the documentation for controlErrorsOn what do you mean by this?

each individual property in the object is optional, so it's possible to override only 1 setting

I didn't wrote it, but it means that you can even override one property. It's a redundant sentence probably.