ng-dynamic-forms icon indicating copy to clipboard operation
ng-dynamic-forms copied to clipboard

markAsTouched doesn't change input class?

Open rzych opened this issue 6 years ago • 7 comments

I'm submitting a


[ ] Bug / Regression
[ ] Feature Request / Proposal
[ x] Question

I'm using


NG Dynamic Forms Version: `X.Y.Z`

[ ] Basic UI
[ ] Bootstrap UI  
[ ] Foundation UI
[ ] Ionic UI
[ ] Kendo UI
[ ] Material  
[x ] NG Bootstrap
[ ] Prime NG

Description

Hey, I'm not sure if this is a bug. But when I lose focus on input I get nice error message and input border changes to red (input css changes - getting extra classes, is-invalid, etc). But when I'm trying to validate form on submit click - I get an error, but input border doesn't change (input css does't change).

Submit event is attached:

<form class="form-horizontal" [formGroup]="formGroup" (ngSubmit)="onSubmit()">

And:

onSubmit(){  
  Object.keys(this.formGroup.controls).forEach(field => {`
    const control = this.formGroup.get(field);
    control.markAsTouched({ onlySelf: true });
  });
}

When I click on submit button, I get an error message. I can see in console that the formControl changes touched attribute from false to true. But nothing happen with my html element / input css classes.

When I lose focus, I get an error message and my input css classes changes:

When input getting focus:

<input ng-reflect-ng-class="" ng-reflect-required="false" 
ng-reflect-text-mask-config="[object Object]" ng-reflect-name="firstName" 
autocomplete="on" class="form-control ng-untouched ng-pristine ng-invalid" 
id="firstName" name="firstName" placeholder="First Name" 
spellcheck="false" tabindex="0" type="text">

When input losing focus:

<input ng-reflect-ng-class="" ng-reflect-required="false" 
ng-reflect-text-mask-config="[object Object]" ng-reflect-name="firstName" 
autocomplete="on" class="form-control ng-pristine ng-invalid is-invalid ng-touched" 
id="firstName" name="firstName" placeholder="First Name" 
spellcheck="false" tabindex="0" type="text">

Am I doing something wrong?

Thanks

rzych avatar Jan 12 '19 22:01 rzych

Helllo @rzych ,

I don't see any problems with your definition. I think I had a similiar issue with the method you provided when using material-ui.

The solution was to make a pull request wich removed the change detection strategy OnPush from the form controls to let them actually react to such changes.

I don't know if this will actually help in you case.. maybe we need a feature to configure the ChangeDetection for the library user?

greetings

Karamuto avatar Jan 14 '19 09:01 Karamuto

We have the same issue for ui-primeng too. I am trying to fix it in my local version by removing the OnPush of ui-primeng controls. However, @Karamuto any idea on how much impact we will have on original performance issue that was fixed #808 by introducing OnPush.

vinothsubramanian avatar Feb 24 '19 04:02 vinothsubramanian

I can only guess that this can or cannot have bigger issues relating performance. I would guess that it only matters for really big forms ( 200+ controls ), which are no good in the first place. On the other side I am actually using it for forms with 50-100+ controls and can't see problems in production.

Sadly I currently don't know a way to configure the change detection with some kind of global variable.

Karamuto avatar Feb 24 '19 08:02 Karamuto

¿Any improvement with this issue? It is very uncomfortable not being able to display form errors.

Eseperio avatar May 10 '20 02:05 Eseperio

you can use markAsTouched & updateValueAndValidity functions same time.

This is my sample code and it works : this.tab1FormGroup.get(key).markAsTouched(); this.tab1FormGroup.get(key).updateValueAndValidity();

fatihsinanyaman avatar Jul 17 '20 10:07 fatihsinanyaman

I have the same issue, using the ui-basic module.

I have to trigger the validation in code. After calling this.form.markAllAsTouched() I make a call to detectChanges() according to the documentation: this.formService.detectChanges(this.formComponent);

I used the debugger and noticed that this method deep-traverses the components: QueryList<DynamicFormControlContainerComponent> from DynamicFormComponent and calls component.markForCheck() for each of them, but only if they are instance of DynamicFormGroupComponent or DynamicFormArrayComponent. See here.

I'm not sure if this is correct, but the components wrapping the controls don't seem to be marked to be checked by the change detection mechanism, hence the inputs remain untouched.

Any thoughts on how to fix this?

marculescu avatar Jan 20 '21 12:01 marculescu

Thanks for this! I was able to do something similar with primeng children.

@ViewChildren(DynamicPrimeNGFormControlContainerComponent) formComponents: QueryList<DynamicPrimeNGFormControlContainerComponent>

And then call markForCheck() which worked

I have the same issue, using the ui-basic module.

I have to trigger the validation in code. After calling this.form.markAllAsTouched() I make a call to detectChanges() according to the documentation: this.formService.detectChanges(this.formComponent);

I used the debugger and noticed that this method deep-traverses the components: QueryList<DynamicFormControlContainerComponent> from DynamicFormComponent and calls component.markForCheck() for each of them, but only if they are instance of DynamicFormGroupComponent or DynamicFormArrayComponent. See here.

I'm not sure if this is correct, but the components wrapping the controls don't seem to be marked to be checked by the change detection mechanism, hence the inputs remain untouched.

Any thoughts on how to fix this?

jeremylcarter avatar Jan 15 '23 02:01 jeremylcarter