Prebuilt Components Form Groups

Form Groups

Groups nest form fields under a single key in the form value. This creates logical grouping for form data, not visual grouping.

Interactive Demo

Loading example...

Click to view config! 🔧
{
  fields: [
    { key: 'name', type: 'input', label: 'Full Name', value: '', required: true },
    { key: 'email', type: 'input', label: 'Email', value: '', required: true, email: true },
    // Text field for group heading
    { key: 'addressTitle', type: 'text', label: 'Address', props: { elementType: 'h4' } },
    // Group field: nests fields under 'address' object
    { key: 'address', type: 'group',
      fields: [
        { key: 'street', type: 'input', label: 'Street Address', value: '', required: true },
        { key: 'city', type: 'input', label: 'City', value: '', required: true },
        { key: 'state', type: 'input', label: 'State', value: '', required: true },
        { key: 'zip', type: 'input', label: 'ZIP Code', value: '', required: true, pattern: /^\d{5}$/ }
      ]
    },
    // Result: { name: '', email: '', address: { street: '', city: '', state: '', zip: '' } }
    { type: 'submit', key: 'submit', label: 'Submit' },
  ],
}

Basic Group

{
  type: 'group',
  key: 'address',
  fields: [
    { key: 'street', type: 'input', label: 'Street', value: '' },
    { key: 'city', type: 'input', label: 'City', value: '' },
    { key: 'zip', type: 'input', label: 'ZIP', value: '' },
  ],
}

This creates a nested structure in the form value:

{
  address: {
    street: '',
    city: '',
    zip: ''
  }
}

Groups are for organizing form data, not UI. The visual presentation depends on your UI integration (Material, Bootstrap, etc.).

Complete Example

Here's a complete working example of a group field with validation:

import { Component } from '@angular/core';
import { DynamicForm } from '@ng-forge/dynamic-forms';

@Component({
  selector: 'app-user-profile-form',
  imports: [DynamicForm],
  template: `<form [dynamic-form]="formConfig"></form>`,
})
export class UserProfileFormComponent {
  formConfig = {
    fields: [
      {
        key: 'name',
        type: 'input',
        label: 'Full Name',
        value: '',
        required: true,
      },
      {
        key: 'address',
        type: 'group',
        fields: [
          {
            key: 'street',
            type: 'input',
            label: 'Street Address',
            value: '',
            required: true,
          },
          {
            key: 'city',
            type: 'input',
            label: 'City',
            value: '',
            required: true,
          },
          {
            key: 'state',
            type: 'input',
            label: 'State',
            value: '',
            required: true,
            maxLength: 2,
          },
          {
            key: 'zip',
            type: 'input',
            label: 'ZIP Code',
            value: '',
            required: true,
            pattern: /^d{5}$/,
          },
        ],
      },
    ],
  };
}

This produces a form value with nested structure:

{
  name: 'John Doe',
  address: {
    street: '123 Main St',
    city: 'Springfield',
    state: 'IL',
    zip: '62701'
  }
}

Nesting Restrictions

Group fields can be used within:

  • Pages (top-level container)
  • Rows (for horizontal layouts)
  • Array fields (for creating object arrays where each array item is an object)

Groups cannot be nested inside:

  • Other group fields (no nested groups)

Allowed Children

Groups can contain:

  • Leaf fields (input, select, checkbox, etc.)
  • Row fields (for horizontal layouts within the group)

See Type Safety & Inference for details on how groups affect type inference.