Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
118
rated 0 times [  125] [ 7]  / answers: 1 / hits: 15096  / 6 Years ago, wed, january 9, 2019, 12:00:00

I am trying to nest multiple reactive forms in my angular project and there forms are in different components.



For example I have a component that contains a form with two inputs one input for name and one input for description and a submit button. I call this component NameDescComponent



I am planning to use this component across multiple pages and forms. Here is the html for the component.



<form [formGroup]=nameDescForm (ngSubmit)=customEmit()>
<div fxLayout=row fxLayoutGap=10px fxFlex>
<mat-form-field>
<input matInput placeholder=Name formControlName=name>
</mat-form-field>
<mat-form-field fxFlex>
<input matInput placeholder=Description formControlName=description>
</mat-form-field>
</div>
<div fxLayout=column fxLayoutGap=10px>
<button type=submit mat-raised-button color=primary>
{{buttonText}}
</button>
<div>
</div>
</div>
</form>


And here is the abbreviated ts file



public nameDescForm: FormGroup;



@Input() public buttonText: string;
@Output() public save: EventEmitter<any> = new EventEmitter<any>();
@Output() public nameDescFormEmit: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();

constructor(fb: FormBuilder) {
this.nameDescForm = fb.group({
'name': ['', Validators.required],
'description': ['']
});
}

public ngOnInit() {
console.log(this.nameDescForm);
this.nameDescFormEmit.emit(this.nameDescForm);
}

public customEmit() {
this.save.emit();
}


Then in a page where I am using this component I also have another form with the NameDescComponent inside the form, like this



<form [formGroup]=parentForm (ngSubmit)=customEmit()>

<app-name-description (nameDescFormEmit)=getNameDescForm($event) buttonText=Save (save)=save()></app-name-description>

<input type=test formControlName=test>

</form>


Currently what I am doing is passing the nameDescFrom from its component to the ParentComponent with the Output and EventEmitter. This solution seems to work and when I update child I am able to access the values. But the downside is when I go to submit the form I have to check that the parentForm and then nameDescFrom are both valid and manage both forms separately.



I am wondering if there is a better way to approach this? When I can access the nameDescFrom from within the parent form?



Thanks


More From » angular

 Answers
46

To merge your form with nested forms and have a single validation process for all of them, you can use the formbuilder to create the whole model object structure in the root form component.
Then in its html template you will add the custom element of the sub-forms (ex: <nested-form>), which will render the sub-forms.



See example : https://stackblitz.com/edit/angular-m5fexe)



Useful angular doc links :





Code :



export class Form1Component  {
@Input() name: string;

public dummyForm: FormGroup;

constructor(
private _fb: FormBuilder,
) {
this.createForm();
}

createForm() {
this.dummyForm = this._fb.group({
username: ['username', Validators.required],
nestedForm: this._fb.group({
complement1: ['complement1', Validators.required],
complement2: ['complement2', Validators.required],
})
});
}

submit() {
if (this.dummyForm.valid) {
console.log('form AND subforms are valid', this.dummyForm.value);
} else {
console.warn('form AND/OR subforms are invalid', this.dummyForm.value);
}
}
}


Template for the Form1Component :



<form [formGroup]=dummyForm (ngSubmit)=submit()>    
<div>
<label for=username>Root Input</label>
<input type=text id=username formControlName=username/>
</div>
<nested-form [parentForm]=dummyForm></nested-form>
<button>Send</button>
</form>


Nested form code:



export class NestedFormComponent {
@Input()
public parentForm: FormGroup;
}


Nested form template :



<form [formGroup]=parentForm>
<div formGroupName=nestedForm>
<div>
<label for=complement1>Nested input 1</label>
<input type=text formControlName=complement1/>
</div>
<div>
<label for=complement1>Nested input 1</label>
<input type=text formControlName=complement2/>
</div>
</div>
</form>

[#52804] Friday, January 4, 2019, 6 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
lesli

Total Points: 348
Total Questions: 105
Total Answers: 119

Location: United States Minor Outlying Island
Member since Fri, Jan 6, 2023
1 Year ago
;