I\'m trying achieve a nested form with validation in Angular 2, I\'ve seen posts and followed the documentation but I\'m really struggling, hope you can point me in the right di
The main idea is that you have to treat the formGroup and formControls as variables, mainly javascript objects and arrays.
So I'll put some code in to make my point. The code below is somewhat like what you have. The form is constructed dynamically, just that it is split into sections, each section containing its share of fields and labels.
The HTML is backed up by typescript classes. Those are not here as they do not have much special. Just the FormSchemaUI, FormSectionUI and FormFieldUI are important.
Treat each piece of code as its own file.
Also please take note that formSchema: FormSchema is a JSON object that I receive from a service. Any properties of the UI classes that you do not see defined are inherited from their base Data clases. Those are not presented here. The hierarchy is: FormSchema contains multiple sections. A section contains multiple fields.
=============================================
=============================================
{{fieldUI.Label}}
=============================================
=============================================
=============================================
export class FormSchemaUI extends FormSchema {
SectionsUI: Array;
MainFormGroup: FormGroup;
static fromFormSchemaData(formSchema: FormSchema): FormSchemaUI {
let formSchemaUI = new FormSchemaUI(formSchema);
formSchemaUI.SectionsUI = new Array();
formSchemaUI.Sections.forEach(section => {
let formSectionUI = FormSectionUI.fromFormSectionData(section);
formSchemaUI.SectionsUI.push(formSectionUI);
});
formSchemaUI.MainFormGroup = FormSchemaUI.buildMainFormGroup(formSchemaUI);
return formSchemaUI;
}
static buildMainFormGroup(formSchemaUI: FormSchemaUI): FormGroup {
let obj = {};
formSchemaUI.SectionsUI.forEach(sectionUI => {
obj[sectionUI.SectionDisplayId] = sectionUI.SectionFormGroup;
});
let sectionFormGroup = new FormGroup(obj);
return sectionFormGroup;
}
}
=============================================
export class FormSectionUI extends FormSection {
constructor(formSection: FormSection) {
this.SectionDisplayId = 'section' + this.SectionId.toString();
}
SectionDisplayId: string;
FieldsUI: Array;
HiddenFieldsUI: Array;
SectionFormGroup: FormGroup;
MainFormGroup: FormGroup;
ParentFormSchemaUI: FormSchemaUI;
static fromFormSectionData(formSection: FormSection): FormSectionUI {
let formSectionUI = new FormSectionUI(formSection);
formSectionUI.FieldsUI = new Array();
formSectionUI.HiddenFieldsUI = new Array();
formSectionUI.Fields.forEach(field => {
let fieldUI = FormFieldUI.fromFormFieldData(field);
if (fieldUI.ColumnType != 'HIDDEN')
formSectionUI.FieldsUI.push(fieldUI);
else formSectionUI.HiddenFieldsUI.push(fieldUI);
});
formSectionUI.SectionFormGroup = FormSectionUI.buildFormSectionFormGroup(formSectionUI);
return formSectionUI;
}
static buildFormSectionFormGroup(formSectionUI: FormSectionUI): FormGroup {
let obj = {};
formSectionUI.FieldsUI.forEach(fieldUI => {
obj[fieldUI.FieldDisplayId] = fieldUI.FieldFormControl;
});
let sectionFormGroup = new FormGroup(obj);
return sectionFormGroup;
}
}
=============================================
export class FormFieldUI extends FormField {
constructor(formField: FormField) {
super();
this.FieldDisplayId = 'field' + this.FieldId.toString();
this.ListItems = new Array();
}
public FieldDisplayId: string;
public FieldFormControl: FormControl;
public ParentSectionFormGroup: FormGroup;
public MainFormGroup: FormGroup;
public ParentFormSectionUI: FormSectionUI;
public ValueChange: EventEmitter = new EventEmitter();
static buildFormControl(formFieldUI:FormFieldUI): FormControl {
let nullValidator = Validators.nullValidator;
let fieldKey: string = formFieldUI.FieldDisplayId;
let fieldValue: any;
switch (formFieldUI.ColumnType) {
default:
fieldValue = formFieldUI.Value;
break;
}
let isDisabled = !formFieldUI.IsEnabled;
let validatorsArray: ValidatorFn[] = new Array();
let asyncValidatorsArray: AsyncValidatorFn[] = new Array();
let formControl = new FormControl({ value: fieldValue, disabled: isDisabled }, validatorsArray, asyncValidatorsArray);
return formControl;
}
}