Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I populate a ngModelGroup with content projection?

Tags:

angular

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?

like image 932
PedroHC Avatar asked Dec 19 '25 15:12

PedroHC


1 Answers

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

like image 110
Yong Shun Avatar answered Dec 21 '25 07:12

Yong Shun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!