Skip to main content

Overview

Node classes represent different types of form fields in Mat Dynamic Form. Each node type corresponds to a specific UI control (input, dropdown, checkbox, etc.). Source: projects/mat-dynamic-form/src/lib/models/Node.ts

Base Classes

NodeBase

Abstract base class for all node types. Source: Node.ts:19

Properties

id
string
required
Unique identifier for the node (used as form control name)
placeholder
string
Placeholder text displayed in the input
type
NodeType
The node type: 'input' | 'checkbox' | 'dropdown' | 'button' | 'date' | 'radiogroup' | 'textarea' | 'file' | 'password' | 'number' | 'switch' | 'custom' | 'autocomplete' | 'datetime' | 'daterange' | 'timepicker'
action
Action | Action[]
Event action(s) to execute. See Action
singleLine
boolean
default:"false"
If true, label and input appear on same line
icon
string
Material icon name to display (e.g., ‘person’, ‘email’)
errorMessage
string
Custom error message when validation fails
disabled
boolean
Whether the control is disabled
validator
Validator | AbstractControlOptions
Synchronous validator function(s)
asyncValidator
AsyncValidatorFn
Asynchronous validator function
hint
string
Hint text displayed below the input
autoFocus
boolean
default:"false"
Whether this field should receive focus on load

Methods

getNativeElement
getNativeElement(): HTMLElement
Returns the native DOM element for this node. Source: Node.ts:59
returns
HTMLElement
The DOM element with this node’s ID

InputBaseNode

Base class for input-like nodes that accept user-entered values. Source: Node.ts:64

Additional Properties

value
any
The current/initial value of the input
readOnly
boolean
default:"false"
Whether the input is read-only

SelectableNode

Base class for nodes with selectable options (Dropdown, RadioGroup, AutoComplete). Source: Node.ts:87

Additional Properties

selectedValue
string
The initially selected option value
value
OptionChild[] | Promise<OptionChild[]> | Observable<OptionChild[]>
The options list. Can be an array, Promise, or Observable. See OptionChild

Methods

getOptions
getOptions(): OptionChild[]
Returns the resolved options array. Source: Node.ts:125
returns
OptionChild[]
Array of selectable options

Node Types

Input

Standard text input field. Source: Node.ts:169

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: string,
  maxCharCount?: number,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  readOnly?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[]
)

Additional Properties

maxCharCount
number
Maximum number of characters allowed
minCharCount
number
Minimum number of characters required

Methods

editable
editable(): void
Makes the input editable by setting readOnly to false. Source: Node.ts:179
readonly
readonly(): void
Makes the input read-only. Source: Node.ts:183

Example

import { Input } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const nameInput = new Input(
  'fullName',
  'Full Name',
  '',
  50,          // maxCharCount
  false,       // singleLine
  'person',    // icon
  'Name is required',
  false,       // disabled
  false,       // readOnly
  [Validators.required, Validators.minLength(2)]
);

InputPassword

Password input field with masked characters. Source: Node.ts:209

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: string,
  maxCharCount?: number,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  readOnly?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[]
)

Example

import { InputPassword } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const passwordInput = new InputPassword(
  'password',
  'Password',
  '',
  128,
  false,
  'lock',
  'Password must be at least 8 characters',
  false,
  false,
  [Validators.required, Validators.minLength(8)]
);

InputNumber

Numeric input field with number-specific validation. Source: Node.ts:224

Additional Properties

min
number
Minimum allowed value
max
number
Maximum allowed value
decimalCount
number
Number of decimal places allowed

Example

import { InputNumber } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const ageInput = new InputNumber(
  'age',
  'Age',
  null,
  3,
  false,
  'cake',
  'Age must be between 18 and 100',
  false,
  false,
  [Validators.required, Validators.min(18), Validators.max(100)]
);

ageInput.min = 18;
ageInput.max = 100;
ageInput.decimalCount = 0;

TextArea

Multi-line text input. Source: Node.ts:217

Example

import { TextArea } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const bioInput = new TextArea(
  'bio',
  'Biography',
  '',
  500,         // maxCharCount
  false,
  'description',
  'Please enter your bio',
  false,
  false,
  Validators.maxLength(500)
);

Checkbox

Boolean checkbox input. Source: Node.ts:151

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: boolean,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[]
)

Additional Properties

value
boolean
Initial checked state

Example

import { Checkbox } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const termsCheckbox = new Checkbox(
  'terms',
  'I agree to the terms and conditions',
  false,
  false,
  'check_circle',
  'You must agree to the terms',
  false,
  Validators.requiredTrue
);

Switch

Toggle switch (alternative to checkbox). Source: Node.ts:160

Additional Properties

value
boolean
Initial toggle state

Example

import { Switch } from 'mat-dynamic-form';

const notificationSwitch = new Switch(
  'notifications',
  'Enable notifications',
  true,
  false,
  'notifications_active'
);
Single or multi-select dropdown. Source: Node.ts:243

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: OptionChild[] | Promise<OptionChild[]> | Observable<OptionChild[]>,
  selected?: string,
  multiple?: boolean,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[]
)

Additional Properties

multiple
boolean
default:"false"
Whether multiple options can be selected

Example

import { Dropdown, OptionChild } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const countryDropdown = new Dropdown(
  'country',
  'Country',
  [
    new OptionChild('United States', 'us'),
    new OptionChild('Canada', 'ca'),
    new OptionChild('Mexico', 'mx'),
    new OptionChild('United Kingdom', 'uk')
  ],
  'us',        // selected
  false,       // multiple
  false,
  'public',
  'Country is required',
  false,
  Validators.required
);

// Multi-select example
const languagesDropdown = new Dropdown(
  'languages',
  'Languages',
  [
    new OptionChild('English', 'en'),
    new OptionChild('Spanish', 'es'),
    new OptionChild('French', 'fr'),
    new OptionChild('German', 'de')
  ],
  null,
  true         // multiple selection enabled
);

RadioGroup

Radio button group for single selection. Source: Node.ts:235

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: OptionChild[] | Promise<OptionChild[]> | Observable<OptionChild[]>,
  selected?: string,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[]
)

Example

import { RadioGroup, OptionChild } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const genderRadio = new RadioGroup(
  'gender',
  'Gender',
  [
    new OptionChild('Male', 'male'),
    new OptionChild('Female', 'female'),
    new OptionChild('Other', 'other'),
    new OptionChild('Prefer not to say', 'not_specified')
  ],
  'not_specified',
  false,
  'person',
  'Please select your gender',
  false,
  Validators.required
);

AutoComplete

Autocomplete input with filtered suggestions. Source: Node.ts:253

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: OptionChild[] | Promise<OptionChild[]> | Observable<OptionChild[]>,
  selected?: string,
  multiple?: boolean,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[]
)

Additional Properties

multiple
boolean
default:"false"
Whether multiple options can be selected
filteredOptions
BehaviorSubject<OptionChild[]>
Observable that emits filtered options as user types

Example

import { AutoComplete, OptionChild } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const cityAutocomplete = new AutoComplete(
  'city',
  'City',
  [
    new OptionChild('New York', 'ny'),
    new OptionChild('Los Angeles', 'la'),
    new OptionChild('Chicago', 'chi'),
    new OptionChild('Houston', 'hou'),
    new OptionChild('Phoenix', 'phx')
  ],
  null,
  false,
  false,
  'location_city',
  'Please select a city',
  false,
  Validators.required
);

// Options are automatically filtered as user types

DatePicker

Date selection input. Source: Node.ts:270

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: Date,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[],
  minDate?: Date,
  maxDate?: Date
)

Additional Properties

minDate
Date
Minimum selectable date
maxDate
Date
Maximum selectable date

Example

import { DatePicker } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const today = new Date();
const maxDate = new Date();
maxDate.setFullYear(today.getFullYear() + 1);

const birthdayPicker = new DatePicker(
  'birthday',
  'Date of Birth',
  null,
  false,
  'cake',
  'Please select your birthday',
  false,
  Validators.required,
  null,
  null,
  new Date('1900-01-01'),  // minDate
  today                     // maxDate
);

DateTimePicker

Date and time selection input. Source: Node.ts:282

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: Date,
  dateFormat?: string,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[],
  minDate?: Date,
  maxDate?: Date,
  acceptLabel?: string,
  cancelLabel?: string,
  selectTimeLabel?: string,
  enterTimeLabel?: string,
  showClockPicker?: boolean,
  orientation?: 'portrait' | 'landscape'
)

Additional Properties

dateFormat
string
Date/time display format (e.g., ‘dd-MM-yyyy hh:mm a’)
acceptLabel
string
default:"'OK'"
Label for accept button
cancelLabel
string
default:"'Cancel'"
Label for cancel button
selectTimeLabel
string
default:"'Select Time'"
Label for time selection mode
enterTimeLabel
string
default:"'Enter Time'"
Label for time entry mode
showClockPicker
boolean
default:"false"
Whether to show visual clock picker
orientation
'portrait' | 'landscape'
default:"'portrait'"
Picker orientation

Example

import { DateTimePicker } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const appointmentPicker = new DateTimePicker(
  'appointment',
  'Appointment Date & Time',
  null,
  'dd/MM/yyyy hh:mm a',
  false,
  'event',
  'Please select appointment time',
  false,
  Validators.required,
  null,
  null,
  new Date(),           // minDate (today)
  null,
  null,
  'Confirm',            // acceptLabel
  'Cancel',             // cancelLabel
  'Select Time',
  'Enter Time',
  true,                 // showClockPicker
  'portrait'
);

TimePicker

Time-only selection input. Source: Node.ts:312

Example

import { TimePicker } from 'mat-dynamic-form';

const timePicker = new TimePicker(
  'meetingTime',
  'Meeting Time',
  null,
  'hh:mm a',
  false,
  'schedule',
  'Please select a time'
);

DateRangePicker

Date range selection (start and end dates). Source: Node.ts:319

Constructor

constructor(
  id: string,
  placeholder?: string,
  startDate?: string,
  endDate?: string,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[],
  minDate?: Date,
  maxDate?: Date
)

Additional Properties

startDate
string
Initial start date
endDate
string
Initial end date

Example

import { DateRangePicker } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const vacationPicker = new DateRangePicker(
  'vacation',
  'Vacation Dates',
  null,
  null,
  false,
  'date_range',
  'Please select vacation dates',
  false,
  Validators.required,
  null,
  null,
  new Date()            // minDate (today)
);

// Access selected range
// Form value will be: { start: Date, end: Date }

InputFile

File upload input. Source: Node.ts:188

Constructor

constructor(
  id: string,
  placeholder?: string,
  value?: any,
  accept?: string[],
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[]
)

Additional Properties

accept
string[]
Accepted file types (e.g., [‘.pdf’, ‘.jpg’, ‘image/*’])
filename
string
Name of the uploaded file
maxSize
number
Maximum file size in bytes
dragLabel
string
Custom label for drag-and-drop area
downloadHint
string
Hint text for download action
removeHint
string
Hint text for remove action
retryHint
string
Hint text for retry action
onStatusChange
(value: FileChange) => void
Callback when file upload status changes

Methods

executeStatusChange
executeStatusChange(value: FileChange): void
Triggers the status change callback. Source: Node.ts:204

Example

import { InputFile } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';

const resumeUpload = new InputFile(
  'resume',
  'Upload Resume',
  null,
  ['.pdf', '.doc', '.docx'],
  false,
  'upload_file',
  'Resume is required',
  false,
  Validators.required
);

resumeUpload.maxSize = 5 * 1024 * 1024; // 5MB
resumeUpload.dragLabel = 'Drag and drop your resume here';
resumeUpload.onStatusChange = (status) => {
  console.log('File upload status:', status);
};

Button

Action button (typically used for form submission or other actions). Source: Node.ts:334

Constructor

constructor(
  id: string,
  placeholder: string,
  action: Action,
  singleLine?: boolean,
  icon?: string,
  disabled?: boolean,
  validateForm?: boolean,
  validation?: (param: ActionEvent) => boolean
)

Additional Properties

validateForm
boolean
Whether to validate the form before executing the action
validation
(param: ActionEvent) => boolean
Custom validation function (returns true if valid)

Example

import { Button } from 'mat-dynamic-form';

const submitButton = new Button(
  'submit',
  'Submit',
  {
    type: 'click',
    style: 'primary',
    onEvent: ({ event, structure }) => {
      if (structure.isValid()) {
        const data = structure.getValue();
        console.log('Submitting:', data);
        // Submit to API
      }
    }
  },
  false,
  'send',
  false,
  true,           // validateForm
  ({ structure }) => {
    // Custom validation logic
    return structure.isValid() && structure.getValue().terms === true;
  }
);

const cancelButton = new Button(
  'cancel',
  'Cancel',
  {
    type: 'click',
    style: 'warn',
    onEvent: () => {
      window.history.back();
    }
  },
  false,
  'cancel'
);

CustomNode

Custom component node for embedding custom Angular components. Source: Node.ts:75

Constructor

constructor(
  id: string,
  component: Type<T>,
  properties?: { [key: string]: any },
  placeholder?: string,
  singleLine?: boolean,
  icon?: string,
  errorMessage?: string,
  disabled?: boolean,
  validator?: Validator,
  asyncValidator?: AsyncValidator,
  action?: Action | Action[]
)

Additional Properties

component
Type<T>
required
Angular component class to render
instance
T
Instance of the component (set after render)
properties
{ [key: string]: any }
Input properties to pass to the component

Example

import { CustomNode } from 'mat-dynamic-form';
import { MyCustomInputComponent } from './my-custom-input.component';

const customField = new CustomNode(
  'customField',
  MyCustomInputComponent,
  {
    label: 'Custom Field',
    options: ['Option 1', 'Option 2'],
    theme: 'dark'
  },
  'Enter custom value'
);

// After rendering, access component instance
// customField.instance.someMethod();

Type Aliases

Node

type Node = Input | Checkbox | RadioGroup | Dropdown | TextArea | 
            DatePicker | InputFile | InputNumber | InputPassword
Union type of all available node classes. Source: Node.ts:9

Validator

type Validator = ValidatorFn | ValidatorFn[] | null
Type for synchronous validators. Source: Node.ts:10

AsyncValidator

type AsyncValidator = AsyncValidatorFn | AsyncValidatorFn[] | null
Type for asynchronous validators. Source: Node.ts:11

Advanced Examples

Dynamic Options from API

import { Dropdown, OptionChild } from 'mat-dynamic-form';
import { of } from 'rxjs';
import { map } from 'rxjs/operators';

// Using Promise
const categoriesFromPromise = new Dropdown(
  'category',
  'Category',
  fetch('/api/categories')
    .then(res => res.json())
    .then(data => data.map(item => new OptionChild(item.name, item.id)))
);

// Using Observable
const categoriesFromObservable = new Dropdown(
  'category',
  'Category',
  this.http.get<any[]>('/api/categories').pipe(
    map(data => data.map(item => new OptionChild(item.name, item.id)))
  )
);

Conditional Fields with Actions

import { Dropdown, Input, OptionChild } from 'mat-dynamic-form';

const accountTypeDropdown = new Dropdown(
  'accountType',
  'Account Type',
  [
    new OptionChild('Personal', 'personal'),
    new OptionChild('Business', 'business')
  ],
  'personal',
  false,
  false,
  'account_circle',
  null,
  false,
  null,
  null,
  {
    type: 'valueChange',
    onEvent: ({ event, structure }) => {
      if (event === 'business') {
        // Add company field
        const companyField = new Input(
          'companyName',
          'Company Name',
          '',
          null,
          false,
          'business'
        );
        structure.createNodes(2, [companyField]);
      } else {
        // Remove company field if exists
        const companyNode = structure.getNodeById('companyName');
        if (companyNode) {
          structure.removeNodes([companyNode]);
        }
      }
    }
  }
);

Custom Async Validator

import { Input } from 'mat-dynamic-form';
import { AbstractControl, ValidationErrors } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { map, catchError, debounceTime, switchMap } from 'rxjs/operators';

function usernameAvailabilityValidator(http: HttpClient): AsyncValidatorFn {
  return (control: AbstractControl): Observable<ValidationErrors | null> => {
    if (!control.value) {
      return of(null);
    }
    
    return of(control.value).pipe(
      debounceTime(500),
      switchMap(username => 
        http.get<{ available: boolean }>(`/api/check-username/${username}`)
      ),
      map(result => result.available ? null : { usernameTaken: true }),
      catchError(() => of(null))
    );
  };
}

const usernameInput = new Input(
  'username',
  'Username',
  '',
  20,
  false,
  'person',
  'Username is already taken',
  false,
  false,
  Validators.required,
  usernameAvailabilityValidator(this.http)
);

Build docs developers (and LLMs) love