Reactive forms: mark dirty all controls in form group

10,665

Solution 1

If you have a complicated form structure, you can segregate the code to mark FormGroup, FormArray or FormControl as dirty. See the example here : Mark Form as dirty

markDirty() {
this.markGroupDirty(this.form);
console.log('FORM:', this.form);}
markGroupDirty(formGroup: FormGroup) {
Object.keys(formGroup.controls).forEach(key => {
  switch (formGroup.get(key).constructor.name) {
    case "FormGroup":
      this.markGroupDirty(formGroup.get(key) as FormGroup);
      break;
    case "FormArray":
      this.markArrayDirty(formGroup.get(key) as FormArray);
      break;
    case "FormControl":
      this.markControlDirty(formGroup.get(key) as FormControl);
      break;
  }
});
}
markArrayDirty(formArray: FormArray) {
formArray.controls.forEach(control => {
  switch (control.constructor.name) {
    case "FormGroup":
      this.markGroupDirty(control as FormGroup);
      break;
    case "FormArray":
      this.markArrayDirty(control as FormArray);
      break;
    case "FormControl":
      this.markControlDirty(control as FormControl);
      break;
  }
 });
}
markControlDirty(formControl: FormControl) {
     formControl.markAsDirty();
}

Solution 2

Either mark the whole formGroup as dirty:

this.form.markAsDirty();

Or mark each field:

Object.keys(this.form.controls).forEach(key => { this.form.get(key).markAsDirty(); });

Solution 3

Best approach to do :

this will make every control dirty: this.form.markAsDirty();

Use this way (second option):

let controls = this.form.controls;

    controls.forEach(control => {
          this.form.get(control).markAsDirty();
        });

Solution 4

mark as dirty controls(only those with value) inside FormGroup

markDirtyAllControlsWithValue(form: FormGroup): void {
  const recursiveFunc = (formGroup: FormGroup) => {
    Object.keys(formGroup.controls).forEach(field => {
      const control = formGroup.get(field);
      if (control.value !== null && control.value !== undefined && control.value !== '') {
        control.markAsDirty();
      }
      if (control instanceof FormGroup) {
        recursiveFunc(control);
      }
    });
  };
  recursiveFunc(form);
}

Solution 5

A simplified version of Sachin Gupta's solution:

public static markAllControlsAsDirty(abstractControls: AbstractControl[]): void {
    abstractControls.forEach(abstractControl => {
      if (abstractControl instanceof FormControl) {
        (abstractControl as FormControl).markAsDirty({onlySelf: true});
      } else if (abstractControl instanceof FormGroup) {
        this.markAllControlsAsDirty(Object.values((abstractControl as FormGroup).controls));
      } else if (abstractControl instanceof FormArray) {
        this.markAllControlsAsDirty((abstractControl as FormArray).controls);
      }
    });
  }

And use it like this:

FormUtils.markAllControlsAsDirty(Object.values(this.form.controls));
Share:
10,665
hofshteyn
Author by

hofshteyn

Updated on July 22, 2022

Comments

  • hofshteyn
    hofshteyn almost 2 years

    I have Angular 6 app with form. Here is an examle

    export class ExampleComponent implements OnInit {
        form: FormGroup;
    
        constructor(private fb: FormBuilder) { }
    
        ngOnInit() {
            this.form = new FormGroup({
                first: new FormControl(),
                last: new FormControl()
            });
    
            this.markControlsAsDirty(this.form);
        }
    
        markControlsAsDirty(form: FormGroup) {
            this.form.get('first').markAsDirty();
            this.form.get('last').markAsDirty();
        }
    }
    

    I don't want to get a single control and mark every field. Can I mark all controls in form group as dirty?

    UPDATE I've been added stackblitz example to show that two previous answers were wrong

  • hofshteyn
    hofshteyn about 5 years
    1 option: controls still pristine but form is dirty 2 option: linter error "control does not exist on type Abstract control"
  • hofshteyn
    hofshteyn about 5 years
    controls still not dirty but form does
  • Roberto Zvjerković
    Roberto Zvjerković about 5 years
    1 option: controls still pristine but form is dirty That's literally what you asked for. 2 option: linter error "control does not exist on type Abstract control" Add if (control instanceof FormControl)
  • hofshteyn
    hofshteyn about 5 years
    I asked Can I mark all controls in form group as dirty?. Result is not that I expected
  • hofshteyn
    hofshteyn about 5 years
    I added example in stackblitz, you can see in questions update.
  • Roberto Zvjerković
    Roberto Zvjerković about 5 years
    Updated the answer.
  • argetlam5
    argetlam5 over 4 years
    Good solution, though I do want to point out that in a production build, the constructor name is going to change/be uglified. Better to do an if/else if block where you check if it's an instaceof of the class.