abp icon indicating copy to clipboard operation
abp copied to clipboard

Dynamic form component

Open erdemcaygor opened this issue 2 months ago • 1 comments

Resolves https://github.com/abpframework/abp/issues/23891

TODO

  • [ ] Add nested form support
  • [ ] Select-type fields need support for dynamically loading options from an API (via Observables) instead of being limited to static values.

Config Interfaces


export interface FormFieldConfig {
  key: string;
  value?: any;
  type: 'text' | 'email' | 'number' | 'select' | 'checkbox' | 'date' | 'textarea';
  label: string;
  placeholder?: string;
  required?: boolean;
  disabled?: boolean;
  options?: { key: string; value: any }[];
  validators?: ValidatorConfig[];
  conditionalLogic?: ConditionalRule[];
  order?: number;
  gridSize?: number;
  component?: Type<ControlValueAccessor>;
}

export interface ValidatorConfig {
  type: 'required' | 'email' | 'minLength' | 'maxLength' | 'pattern' | 'custom' | 'min' | 'max' | 'requiredTrue';
  value?: any;
  message: string;
}

export interface ConditionalRule {
  dependsOn: string;
  condition: 'equals' | 'notEquals' | 'contains' | 'greaterThan' | 'lessThan';
  value: any;
  action: 'show' | 'hide' | 'enable' | 'disable';
}

Example Usage


  formFields: FormFieldConfig[] = [
    {
      key: 'firstName',
      type: 'text',
      label: 'First Name',
      placeholder: 'Enter first name',
      value: 'erdemc',
      required: true,
      validators: [
        { type: 'required', message: 'First name is required' },
        { type: 'minLength', value: 2, message: 'Minimum 2 characters required' }
      ],
      gridSize: 6,
      order: 1
    },
    {
      key: 'lastName',
      type: 'text',
      label: 'Last Name',
      placeholder: 'Enter last name',
      required: true,
      validators: [
        { type: 'required', message: 'Last name is required' }
      ],
      gridSize: 12,
      order: 2
    },
    {
      key: 'email',
      type: 'email',
      label: 'Email Address',
      placeholder: 'Enter email',
      required: true,
      validators: [
        { type: 'required', message: 'Email is required' },
        { type: 'email', message: 'Please enter a valid email' }
      ],
      order: 3
    },
    {
      key: 'userType',
      type: 'select',
      label: 'User Type',
      required: true,
      options: [
        { key: 'admin', value: 'Administrator' },
        { key: 'user', value: 'Regular User' },
        { key: 'guest', value: 'Guest User' }
      ],
      validators: [
        { type: 'required', message: 'Please select user type' }
      ],
      order: 4
    },
    {
      key: 'adminNotes',
      type: 'textarea',
      label: 'Admin Notes',
      placeholder: 'Enter admin-specific notes',
      conditionalLogic: [
        {
          dependsOn: 'userType',
          condition: 'equals',
          value: 'admin',
          action: 'show'
        }
      ],
      order: 5
    }
  ];

      <abp-dynamic-form [fields]="formFields">
      </abp-dynamic-form>

erdemcaygor avatar Oct 08 '25 13:10 erdemcaygor

Thanks for contributions. feature is very good but support for nested forms should be added.

fahrigedik avatar Oct 10 '25 12:10 fahrigedik