I'm trying to create a component that uses the ngModelGroup to group some inputs inside a ngForm. I noticed that when using the ngModelGroup directly inside the form it works as expected:
<form #form="ngForm">
<div ngModelGroup="personalInfo">
<input type="string" ngModel name="firstName">
<input type="string" ngModel name="lastName">
</div>
</form>
<pre>{{form.value | json}}</pre>
This creates the following form structure, as expected:
{
"personalInfo": {
"firstName": "",
"lastName": ""
}
}
However, I need to create a component where the inputs are projected inside it:
@Component({
selector: 'app-component-with-the-ngmodelgroup-inside',
template: `
<div #group="ngModelGroup" [ngModelGroup]="groupName">
<ng-content></ng-content>
</div>
`,
imports: [CommonModule, FormsModule],
standalone: true,
viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],
})
export class ComponentWithNgModelGroupComponent {
@Input() groupName: string = '';
}
Using the component, then, looks like this:
<form #form="ngForm">
<app-component-with-the-ngmodelgroup-inside groupName="perfonalInfo">
<input type="string" ngModel name="firstName">
<input type="string" ngModel name="lastName">
</app-component-with-the-ngmodelgroup-inside>
</form>
<pre>{{form.value | json}}</pre>
In this case the form.value structure is left like this:
{
"firstName": "",
"lastName": ""
"personalInfo": {},
}
How could I handle the projected content so that the form controls are correctly registered inside the ngModelGroup?
After some trial and error, would say that your current approach is not possible as both firstName and lastName fields will be created in the root form object instead of nested in the personalInfo object.
If you keen to achieve the expected result, you should remove both firstName and lastName fields from the root form view.
<form #form="ngForm">
<app-component-with-the-ngmodelgroup-inside groupName="personalInfo">
</app-component-with-the-ngmodelgroup-inside>
</form>
And move both fields within the ComponentWithNgModelGroupComponent.
@Component({
selector: 'app-component-with-the-ngmodelgroup-inside',
template: `
<div #group="ngModelGroup" [ngModelGroup]="groupName">
<input type="string" ngModel name="firstName" />
<input type="string" ngModel name="lastName" />
</div>
`,
imports: [CommonModule, FormsModule],
standalone: true,
viewProviders: [
{
provide: ControlContainer,
useExisting: NgForm,
},
],
})
export class ComponentWithNgModelGroupComponent {
@Input() groupName: string = '';
}
Demo @ StackBlitz
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With