- β Key Features
- π¦ Installation
- π Example Usage
- π Usage
- π Using Aliases for Server-Provided JSON Configuration
- π Responsive Grid System (
colSize
Classes) - π Grid System Configuration
- π Defining Form Fields in an External File
- π Built-in Example Fields & Custom Component Support
- π Field Types and Examples
- πΉ Dynamic Form Rendering β Generate Angular forms dynamically from JSON configuration.
- πΉ Responsive Grid System β Automatically arranges form fields in a flexible grid layout.
- πΉ Supports Angular Reactive Forms β Easily integrates with
FormGroup
andFormControl
. - πΉ Server-Driven Forms Support β Fetch form configurations from an API and dynamically render fields.
- πΉ Alias-Based Component Mapping β Use string-based aliases for
controlType
instead of direct component references. - πΉ Custom Component Support β Extend the form factory with your own form field components.
- πΉ Built-in Example Components β Includes two test field components for quick setup and reference.
- πΉ Validation Handling β Supports Angularβs
Validators
for real-time form validation. - πΉ Field Grouping β Nest multiple fields inside a single column to create complex forms.
- πΉ Event Emitters β Listen to form changes, value updates, and submission events.
- πΉ Multi-Step Forms Support β Allows building wizard-style step-based forms.
- πΉ Lightweight & Optimized β Designed for performance, minimal dependencies, and easy integration.
To install ngx-dynamic-forms-factory, run the following command in your Angular project:
npm install ngx-dynamic-forms-factory
For a complete example of how to use ngx-dynamic-forms-factory in a real-world scenario, check out the example project:
π Example Usage
Before using the library, include the required styles in your angular.json
file under the styles
array:
"styles": [
"node_modules/ngx-dynamic-forms-factory/src/preflight.css",
"node_modules/ngx-dynamic-forms-factory/src/styles.css",
...
]
Import the necessary components and services in your Angular component:
// your-angular-component.compontnt.ts
import { FormFactoryComponent, FormFactoryService } from 'ngx-dynamic-forms-factory';
import jsonFormExample from './json-form-example';
@Component({
selector: 'app-root',
imports: [FormFactoryComponent, CommonModule],
template: `
<main>
<ngx-form-factory [form]="form" [formFields]="formFields()" />
</main>
<pre>
{{ form.getRawValue() | json }}
</pre
>
`,
})
export class AppComponent {
form!: FormGroup;
formFields = signal<any[]>([]);
formFactory = inject(FormFactoryService);
ngOnInit(): void {
this.form = this.formFactory.createForm(jsonFormExample);
this.formFields.set(jsonFormExample);
}
}
If you need to provide form JSON configuration from a server API, you can use aliases for controlType
instead of directly referencing component classes.
Instead of:
{
"controlType": InputFieldComponent
}
You can use:
{
"controlType": "input"
}
This allows you to dynamically map string-based aliases to your components.
To define aliases and their corresponding components, use provideFormFactoryConfig in your app configuration:
import { provideFormFactoryConfig } from 'ngx-dynamic-forms';
import { MyCustomInputComponent } from './components/my-custom-input.component';
export const appConfig = {
providers: [
provideFormFactoryConfig({
aliases: [{ component: MyCustomInputComponent, alias: 'input' }],
}),
],
};
With this setup, any field with "controlType": "input" will automatically be rendered using MyCustomInputComponent.
This approach is useful when working with server-driven forms, allowing you to configure forms dynamically without modifying frontend code.
The colSize
property controls how form fields are positioned in a responsive grid layout. It follows a 12-column grid system, like Tailwind CSS, but uses the prefix ui-
.
Each field can span between 1 and 12 columns in the grid.
Class | Effect |
---|---|
ui-col-span-1 |
The field spans 1 grid column. |
ui-col-span-2 |
The field spans 2 grid columns. |
ui-col-span-3 |
The field spans 3 grid columns. |
ui-col-span-4 |
The field spans 4 grid columns. |
ui-col-span-5 |
The field spans 5 grid columns. |
ui-col-span-6 |
The field spans 6 grid columns (half of the grid). |
ui-col-span-7 |
The field spans 7 grid columns. |
ui-col-span-8 |
The field spans 8 grid columns. |
ui-col-span-9 |
The field spans 9 grid columns. |
ui-col-span-10 |
The field spans 10 grid columns. |
ui-col-span-11 |
The field spans 11 grid columns. |
ui-col-span-12 |
The field takes the full width (12 columns). |
You can make the field adjust dynamically across different screen sizes by adding responsive prefixes:
Breakpoint | Prefix | Example |
---|---|---|
Small | sm: |
sm:ui-col-span-6 (6 columns on small screens) |
Medium | md: |
md:ui-col-span-4 (4 columns on medium screens) |
Large | lg: |
lg:ui-col-span-3 (3 columns on large screens) |
Extra Large | xl: |
xl:ui-col-span-2 (2 columns on extra-large screens) |
By default, this library uses a 12-column grid system to organize form fields in a responsive layout. The grid system applies to both main forms and nested field groups.
The default grid system uses 12 columns and applies spacing between elements:
grid: {
mainGridClassess: 'ui-grid ui-grid-cols-12 ui-gap-x-4 ui-gap-y-2',
nestedGridClassess: 'ui-grid ui-grid-cols-12 ui-gap-x-4 ui-gap-y-2',
}
π mainGridClassess
β Defines the grid layout for the entire form.
π¦ nestedGridClassess
β Defines the grid layout for nested field groups inside the form.
πΉ ui-grid-cols-X
β X-column grid system (X can be number from 1 to 12).
πΉ ui-gap-x-4
β Horizontal spacing between columns.
πΉ ui-gap-y-2
β Vertical spacing between rows.
If you do not want to use the libraryβs built-in grid system and prefer using Tailwind CSS, PrimeFlex, or another utility-based grid, you can override the default grid configuration.
Modify your app.config.ts to provide your custom grid classes:
import { provideFormFactoryConfig } from 'ngx-dynamic-forms-factory';
export const appConfig = {
providers: [
provideFormFactoryConfig({
grid: {
mainGridClassess: 'grid grid-cols-10 gap-2', // Custom Tailwind
nestedGridClassess: 'grid grid-cols-6 gap-x-4 gap-y-2',
},
}),
],
};
If you override the grid system, you do not need the libraryβs CSS styles anymore.
You can remove the default styles from angular.json
.
To keep the form configuration modular and reusable, define the form fields in an external file. The fields are created using the createField
function and exported as an array.
Create a file named json-form-example.ts
and add the following:
import { Validators } from '@angular/forms';
import { createField, InputField } from 'ngx-dynamic-forms-factory';
export default [
createField<InputField>({
colSize: 'ui-col-span-12 sm:ui-col-span-4',
controlType: InputField,
label: 'Name',
placeholder: 'Enter name',
type: 'text',
options: {
formControlName: 'name',
value: 'Test',
disabled: false,
validators: [Validators.minLength(3), Validators.required, Validators.maxLength(10)],
},
}),
];
This library provides two example field components intended for testing and demonstration purposes.
If you want to add your own custom components, you can check out the example implementation here: π Custom Components Example
This guide explains how to create and register custom form components to extend the functionality of ngx-dynamic-forms-factory
. Also you can see how to implement error handling and manual value updating without formControlName.
The createField
function is used to create form fields based on different interfaces. Below is a table of available field types and their descriptions.
Interface | Description |
---|---|
InputField |
EXAMPLE FIELD! Standard text input field with validation and placeholder. |
SelectField |
EXAMPLE FIELD! Dropdown select field with predefined options. |
UIElement |
Used to insert a custom UI component into the form. |
FieldGroup |
Groups multiple fields together in a single column in the grid layout. |
GenericField |
Base interface for extending and creating custom fields. |
import { Validators } from '@angular/forms';
import { createField, InputField } from 'ngx-dynamic-forms-factory';
[
createField<InputField>({
colSize: 'ui-col-span-12 sm:ui-col-span-4',
controlType: InputField,
label: 'Name',
placeholder: 'Enter name',
type: 'text',
options: {
formControlName: 'name',
value: '',
validators: [Validators.required, Validators.minLength(3)],
},
});
... // Other fields
]
import { createField, SelectField } from 'ngx-dynamic-forms-factory';
[
createField<SelectField>({
colSize: 'ui-col-span-12 sm:ui-col-span-4',
controlType: SelectField,
label: 'Country',
selectOptions: [
{ id: 'us', name: 'United States' },
{ id: 'ca', name: 'Canada' },
],
selectValue: 'id',
selectLabel: 'name',
options: {
formControlName: 'country',
value: '',
validators: [],
},
});
... // Other fields
]
import { createField, UIElement } from 'ngx-dynamic-forms-factory';
import { CustomTitleComponent } from './custom-title.component';
[
createField<UIElement>({
colSize: 'ui-col-span-12',
controlType: CustomTitleComponent,
data: { title: 'Personal Information' },
})
... // Other fields
]
import { createField, FieldGroup, InputField } from 'ngx-dynamic-forms-factory';
[
createField<FieldGroup>({
colSize: 'ui-col-span-12 sm:ui-col-span-4',
group: [
createField<InputField>({
colSize: 'ui-col-span-12',
controlType: InputField,
label: 'Email',
placeholder: '[email protected]',
type: 'email',
options: {
formControlName: 'email',
value: '',
validators: [Validators.email, Validators.required],
},
}),
... // Other fields
],
})
... // Other fields
]
import { createField, GenericField } from 'ngx-dynamic-forms-factory';
interface CustomToggleField extends GenericField {
myCustomOption: string;
}