5
votes

I have a from that adds different fields (I am adding new controls because just hiding them from the template using *ngIf does not exclude them from the form and therefore results in invalid form) based on the selected option from a select option. I am adding new controls to the available form using addControl method of a form in Angular2. The controls are being added correctly, but I don't know why the values of those added controls are not being updated after user inputs. Here is the way I am adding new controls to the form:

signUpForm: ControlGroup;

constructor(private fb: FormBuilder) { }

ngOnInit(): void {
    this.signUpForm = this.fb.group({
        firstName: ["", Validators.required],
        lastName: ["", Validators.required],
        group: ["", Validators.required]
    });
}

modifyControls(selectedGroup): number {
    if (selectedGroup == 1) {
        if (this.signUpForm.contains("studentID")) {
            this.signUpForm.removeControl("studentID");
        }
        this.signUpForm.addControl("teacherCode", new Control("", Validators.required));//need some custome validations
        this.signUpForm.addControl("teacherID", new Control("", Validators.required));
        return 1;
    }
    else if (selectedGroup == 2) {
        if (this.signUpForm.contains("teacherCode")) {
            this.signUpForm.removeControl("teacherCode");
            this.signUpForm.removeControl("teacherID");
        }
        this.signUpForm.addControl("studentID", new Control("", Validators.required));
        return 2;
    }
}

It looks like that angular does not recognized those new fields. I think it is something related to AbstractControl but the documentation lacks on that. Here is the snapshot of the problem, that the dynamically added controls are not being picked up by angular. enter image description here

To show the problem I have created a simple example in the following plunker (please go to version 2 to replicate this problem).

https://plnkr.co/edit/RI4JL4Pnf2LrJ3TsxsSt?p=preview

What am i doing wrong and how make it work with the current setup? What are other options for achieving the same behavior?

Thank you for your help

Workaround:

modifyControls(selectedGroup) {
    if (selectedGroup == 1) {
        this.signUpForm.controls['teacherCode'].validator = Validators.required;
        this.signUpForm.controls['teacherCode'].updateValueAndValidity();
        this.signUpForm.controls['teacherID'].validator = Validators.required;
        this.signUpForm.controls['teacherID'].updateValueAndValidity(); 
        this.signUpForm.controls['studentID'].validator = null;
        this.signUpForm.controls['studentID'].updateValueAndValidity();
    }
    else if (selectedGroup == 2) {
        this.signUpForm.controls['teacherCode'].validator = null;
        this.signUpForm.controls['teacherCode'].updateValueAndValidity();
        this.signUpForm.controls['teacherID'].validator = null;
        this.signUpForm.controls['teacherID'].updateValueAndValidity();
        this.signUpForm.controls['studentID'].validator = Validators.required;
        this.signUpForm.controls['studentID'].updateValueAndValidity(); 

    }
}
1
I found a workaround to my case by adding validators and updating them on the flight, but because I still have not found the reason that my original code was not working I am not closing the question as solved. - Afi

1 Answers

1
votes

For example to do the required validation only when teacherCode.value has a value:

    this.signUpForm.addControl("teacherCode", new Control("", 
        (c:Control) => { 
          if(this.signUpForm.controls['teacherID'].value) {
            return Validators.required(c);
          }
        })
    );