Reputation: 3978
I'm creating a complex template-driven form with Angular 2 which get's its structure of groups and fields from an API. The API sends a JSON object containing groups that can contain fields and / or sub-groups. Since the groups can have sub-groups, I think the simplest way to handle this is to have a custom control, FieldGroupComponent, which takes an input parameter "Group", and if the Group contains sub-groups, it will render those recursively, using a FieldGroupComponent.
The problem I'm having is that the ngForm doesn't recognize the input controls in the FieldGroupComponent as FormControls. The ngForm thinks it doesn't have any controls, and won't recognize that the fields are invalid.
The form page looks something like this:
<form ngForm (ngSubmit)="submitForm()">
<field-group *ngFor="let group of FormGroups" [group]="group"></field-group>
</form>
And the FieldGroupComponent:
@Component({
selector: "field-group",
templateUrl: "./field-group.component.html"
})
export class FieldGroupComponent {
@Input("group") group;
}
And the FieldGroupComponent template:
<fieldset>
<h1>{{group.Title}}</h1>
<div *ngFor="let field of group.Fields">
... render field ...
</div>
<div *ngFor="let subGroup of group.FieldGroups">
<field-group [group]="subGroup"></field-group>
</div>
</fieldset>
Upvotes: 2
Views: 645
Reputation: 9459
My form was dynamic so I extended SZH's solution ngAfterViewInit
so formControls are rebuild on every change. M
Might cause some perfomance penalties in some cases, but if you need it it keeps form controls updated:
public ngAfterViewInit(): void {
this._formControls.changes.subscribe(() => {
this._formControls.forEach((item: NgModel) => {
if (!this.form.controls[item.name]) {
this.form.addControl(item);
}
});
});
}
Upvotes: 0
Reputation: 3978
I ended up simply passing the NgForm into the FieldGroupComponent as an @Input, and manually adding the field controls to the form:
@Input("form") form: NgForm;
@ViewChildren(NgModel) private formControls: QueryList<NgModel>;
ngAfterViewInit(): void {
this.formControls.forEach((item: NgModel) => this.form.addControl(item));
}
Upvotes: 1