Toggle Multiple Fields On/Off in Formbuilder, clea

2020-03-07 07:15发布

问题:

We have a Formbuilder with multiple fields. Sometimes, requirements want to toggle certain fields. We can turn them off with If statements validators, and use NgIf in the html. Is there an easy way to toggle multiple fields on a 20 field form, and simplify the syntax?

Is it possible with Formbuilders, or do we have to transfer to form array? Syntax below seems repetitive, curious how it can be simplified,

Currently, have around 20 flag fields.

{
this.customerForm = this.formBuilder.group({
  'firstName': [null, [Validators.maxLength(50), PhoneNumberValidator]],
  'phoneNumber': [null, [Validators.maxLength(50), PhoneNumberValidator]],
  'streetName': [null, [Validators.maxLength(50), PhoneNumberValidator]],

  'emailAddress': [null, [Validators.maxLength(50), Validators.email]],
  'city': [null, [Validators.required, Validators.maxLength(200)]],
  'state': [null, [Validators.maxLength(200)]],
  'zip':[null,[Validators.maxLength(200)]]
});

}

ngOnInit() { 
// this syntax seems repetitive, how to simplify along with NgIf in html?

if (this.firstNameFlag == false) {
  this.customerForm.get('firstName').clearValidators();
  this.customerForm.get('firstName').updateValueAndValidity();
} 

if (this.phoneNumberFlag == false) {
  this.customerForm.get('phoneNumber').clearValidators();
  this.customerForm.get('phoneNumber').updateValueAndValidity();
}
if (this.streetNameFlag == false) {
  this.customerForm.get('streetName').clearValidators();
  this.customerForm.get('streetName').updateValueAndValidity();
}
etc

回答1:

Artportrait, I hate clear and set validators. A FormControl is invalid if is invalid and is enabled, so I think it's better disabled or not

For disabled a formControl we can use a directive -not is valid using [disabled]="variable"-, see this SO answer

For avoid 20 flag fields you can use a simple array. If your array is, e.g.

fields=['firstName','streetName','state','zip']

Yours controls in the form can be (see that you don't use *ngIf else display.none)

<ng-container [style.display]="fields.indexOf('firstName')<0?'none':''"> 
  first name : 
  <input formControlName='firstName'   
      [enabledControl]="fields.indexOf('firstName')>=0?'>
</ng-container>

Another aproach is really create a different formGroup each time. Using the same array we can has a function createForm

createForm(fields)
{
   const form=new FormGroup({});
   if (fields.indexOf('firstName')>=0)
     form.addControl('firstName',new FormControl('', [Validators.maxLength(50), PhoneNumberValidator]]
   if (fields.indexOf('phoneNumber')>=0)
     form.addControl('phoneNumber',new FormControl('', [Validators.maxLength(50), PhoneNumberValidator]]
   ....
   return form
}

And our inputs like

<ng-container *ngIf="fields.indexOf('firstName')>=0" 
  first name : 
  <input formControlName='firstName'>
</ng-container>

the other aproach is create dynamic forms as Plochie say, but is an aproach that add a complex to the app that we need evaluate (in the docs you has a way to do it)