Action fields for form submission, multi-step navigation, and array manipulation.

All button types share the same adapter-specific props for styling (color, variant, size, etc.). The props listed under Adapter Props apply to every button type on this page.

submit

Renders a submit button that triggers form submission. Automatically disabled when the form is invalid.

{
  key: 'submit',
  type: 'submit',
  label: 'Create Account',
  props: {
    color: 'primary',     // adapter-specific
  }
}

Core Props:

  • label: Button text (also set via top-level label)
  • disabled: Whether the button is disabled

Adapter Props

Build a button component that injects EventBus and register it with submitButtonFieldMapper. See Building an Adapter for the full guide.

// my-submit.component.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormEvent } from '@ng-forge/dynamic-forms';
import { injectNgForgeAction, NgForgeActionHost } from '@ng-forge/dynamic-forms/integration';

@Component({
  selector: 'my-submit',
  hostDirectives: [NgForgeActionHost],
  template: `
    <button type="button" [disabled]="action.disabled()" (click)="action.dispatch()">
      {{ action.label() }}
    </button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class MySubmitComponent<TEvent extends FormEvent> {
  protected readonly action = injectNgForgeAction<TEvent>();
}

// my-submit.type.ts
import type { FieldTypeDefinition } from '@ng-forge/dynamic-forms';
import { submitButtonFieldMapper } from '@ng-forge/dynamic-forms/integration';

export const MySubmitType: FieldTypeDefinition = {
  name: 'submit',
  loadComponent: () => import('./my-submit.component'),
  mapper: submitButtonFieldMapper,
  valueHandling: 'exclude',
  renderReadyWhen: [],
};

button

Generic action button. Dispatches a form event when clicked — subscribe to the event on the form to handle the click.

import { FormResetEvent } from '@ng-forge/dynamic-forms';

{
  key: 'resetBtn',
  type: 'button',
  label: 'Reset',
  event: FormResetEvent,
  props: {
    type: 'button',   // HTML button type: 'button' | 'submit' | 'reset'
  }
}

Core Properties:

  • event: Form event constructor dispatched on click (e.g. FormResetEvent, FormClearEvent, or a custom FormEvent subclass) — required
  • label: Button text

Adapter Props

Build a button component that injects EventBus and register it with buttonFieldMapper. See Building an Adapter for the full guide.

// my-button.component.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormEvent } from '@ng-forge/dynamic-forms';
import { injectNgForgeAction, NgForgeActionHost } from '@ng-forge/dynamic-forms/integration';

@Component({
  selector: 'my-button',
  hostDirectives: [NgForgeActionHost],
  template: `
    <button type="button" [disabled]="action.disabled()" (click)="action.dispatch()">
      {{ action.label() }}
    </button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class MyButtonComponent<TEvent extends FormEvent> {
  protected readonly action = injectNgForgeAction<TEvent>();
}

// my-button.type.ts
import type { FieldTypeDefinition } from '@ng-forge/dynamic-forms';
import { buttonFieldMapper } from '@ng-forge/dynamic-forms/integration';

export const MyButtonType: FieldTypeDefinition = {
  name: 'button',
  loadComponent: () => import('./my-button.component'),
  mapper: buttonFieldMapper,
  valueHandling: 'exclude',
  renderReadyWhen: [],
};

next

Advances to the next page in a multi-step form. Only valid inside a page container. Validates the current page before advancing.

{
  key: 'nextBtn',
  type: 'next',
  label: 'Continue',
}

This field type only makes sense inside a Form Pages container. It is ignored at the root level.

Adapter Props

Build a button component that injects EventBus and register it with nextButtonFieldMapper. See Building an Adapter for the full guide.

// my-next.component.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormEvent } from '@ng-forge/dynamic-forms';
import { injectNgForgeAction, NgForgeActionHost } from '@ng-forge/dynamic-forms/integration';

@Component({
  selector: 'my-next',
  hostDirectives: [NgForgeActionHost],
  template: `
    <button type="button" [disabled]="action.disabled()" (click)="action.dispatch()">
      {{ action.label() }}
    </button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class MyNextComponent<TEvent extends FormEvent> {
  protected readonly action = injectNgForgeAction<TEvent>();
}

// my-next.type.ts
import type { FieldTypeDefinition } from '@ng-forge/dynamic-forms';
import { nextButtonFieldMapper } from '@ng-forge/dynamic-forms/integration';

export const MyNextType: FieldTypeDefinition = {
  name: 'next',
  loadComponent: () => import('./my-next.component'),
  mapper: nextButtonFieldMapper,
  valueHandling: 'exclude',
  renderReadyWhen: [],
};

previous

Navigates back to the previous page in a multi-step form. Only valid inside a page container. Does not trigger validation.

{
  key: 'prevBtn',
  type: 'previous',
  label: 'Back',
}

This field type only makes sense inside a Form Pages container. It is ignored at the root level.

Adapter Props

Build a button component that injects EventBus and register it with previousButtonFieldMapper. See Building an Adapter for the full guide.

// my-previous.component.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormEvent } from '@ng-forge/dynamic-forms';
import { injectNgForgeAction, NgForgeActionHost } from '@ng-forge/dynamic-forms/integration';

@Component({
  selector: 'my-previous',
  hostDirectives: [NgForgeActionHost],
  template: `
    <button type="button" [disabled]="action.disabled()" (click)="action.dispatch()">
      {{ action.label() }}
    </button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class MyPreviousComponent<TEvent extends FormEvent> {
  protected readonly action = injectNgForgeAction<TEvent>();
}

// my-previous.type.ts
import type { FieldTypeDefinition } from '@ng-forge/dynamic-forms';
import { previousButtonFieldMapper } from '@ng-forge/dynamic-forms/integration';

export const MyPreviousType: FieldTypeDefinition = {
  name: 'previous',
  loadComponent: () => import('./my-previous.component'),
  mapper: previousButtonFieldMapper,
  valueHandling: 'exclude',
  renderReadyWhen: [],
};

Array Buttons

Button types for declarative array manipulation. See Form Arrays (Complete) for full usage details and interactive examples.

addArrayItem

Appends a new item to the end of the target array.

{
  key: 'addContact',
  type: 'addArrayItem',
  label: 'Add Contact',
  arrayKey: 'contacts',
  template: [
    { key: 'name', type: 'input', label: 'Name' },
    { key: 'email', type: 'input', label: 'Email' },
  ],
}

Core Properties:

  • arrayKey: Key of the target array field (required if placed outside the array)
  • template: Field definition(s) for the new item — single FieldDef for primitive items, array of FieldDef for object items (required)

prependArrayItem

Inserts a new item at the beginning of the target array.

{
  key: 'prependContact',
  type: 'prependArrayItem',
  label: 'Add to Top',
  arrayKey: 'contacts',
  template: [
    { key: 'name', type: 'input', label: 'Name' },
  ],
}

Core Properties:

  • arrayKey: Key of the target array field (required if placed outside the array)
  • template: Field definition(s) for the new item (required)

insertArrayItem

Inserts a new item at a specific index in the target array.

{
  key: 'insertContact',
  type: 'insertArrayItem',
  label: 'Insert at Position 1',
  arrayKey: 'contacts',
  index: 1,
  template: [
    { key: 'name', type: 'input', label: 'Name' },
  ],
}

Core Properties:

  • arrayKey: Key of the target array field (required if placed outside the array)
  • template: Field definition(s) for the new item (required)
  • index: Position at which to insert the new item (required)

removeArrayItem

Removes the current item from the array. Typically placed inside each array item.

{
  key: 'remove',
  type: 'removeArrayItem',
  label: 'Remove',
  props: { color: 'warn' },
}

Core Properties:

  • arrayKey: Key of the target array field (optional when placed inside the array — automatically inferred)

popArrayItem

Removes the last item from the target array.

{
  key: 'removeLast',
  type: 'popArrayItem',
  label: 'Remove Last',
  arrayKey: 'contacts',
}

Core Properties:

  • arrayKey: Key of the target array field (required)

shiftArrayItem

Removes the first item from the target array.

{
  key: 'removeFirst',
  type: 'shiftArrayItem',
  label: 'Remove First',
  arrayKey: 'contacts',
}

Core Properties:

  • arrayKey: Key of the target array field (required)