FormRenderComponent
, part of the FormBuilderModule
, dynamically renders forms based on configuration through form items. It supports various form field types such as input, textarea, dropdown, radios, and checkboxes.
- Dynamic creation of a form based on configuration.
- Form validation.
- Error handling.
- Run
npm i
to install dependencies. - Import
FormBuilderModule
into your feature module or standalone component where you intend to use it.
Run ng serve
for a dev server. Navigate to http://localhost:4200/
. The application will automatically reload if you change any of the source files.
<app-form-render (formSubmitted)="oFormSubmit($event)" [formConfig]="{ fields: formConfig }">
<!-- The button will be 'projected' within app-form-render component under the dynamically created form (it's required for form submission and validation process) -->
<div><button type="submit">Submit</button></div>
</app-form-render>
export class YourComponent {
// Depending on your system, retrieve the configuration via an API, JSON, or objects defined within the project structure.
formConfig = [
{
key: 'user',
label: 'Username',
type: 'input',
validation: [
{
type: 'required',
message: 'Username is required',
},
],
order: 1,
}
];
// $event includes only key-value pair object structure based on the form configuration.
// If we need form' instance for some reason, we need to extend the current implementation.
oFormSubmit($event){...}
}
AppComponent
currently has completed implementation of usage of app-form-render
.
If we don't want to create our own component to test the functionality , we can use it directly.
<h3>Login form</h3>
<ng-container *ngIf="loginFormConfig$ | async as loginFormConfig">
<app-form-render (formSubmitted)="onLoginFormSubmit($event)" [formConfig]="{ fields: loginFormConfig }">
<div><button type="submit" style="margin-top: 1rem">Submit</button></div>
</app-form-render>
</ng-container>
<hr />
<h3>User form</h3>
<ng-container *ngIf="userFormConfig$ | async as userFormConfig">
<app-form-render (formSubmitted)="onUserFormSubmit($event)" [formConfig]="{ fields: userFormConfig }">
<div><button type="submit" style="margin-top: 1rem">Submit</button></div>
</app-form-render>
</ng-container>
@Component({
selector: "app-root",
standalone: true,
imports: [CommonModule, RouterOutlet, FormBuilderModule],
templateUrl: "./app.component.html",
})
export class AppComponent {
loginFormConfig$ = this.formConfigsService.getLoginFormConfig();
userFormConfig$ = this.formConfigsService.getUserFormConfig();
constructor(private formConfigsService: FormConfigsService) {}
onLoginFormSubmit($event: any) {
const { user, pass } = $event;
console.log({ user, pass });
}
onUserFormSubmit($event: any) {
const { lname, fname, pro, gender, area, profile } = $event;
console.log({ lname, fname, pro, gender, area, profile });
}
}
export interface FormItem {
// This field represents the default value of the form item. It's optional.
value?: any;
// Unique identifier maps form item to the initialized form control.
key: string;
// Label of each field.
label: string;
// All supported form input types.
type: "input" | "textarea" | "dropdown" | "radio" | "checkbox";
// Represents validation rules with error message. It's optional.
validation?: { type: FormValidationType; message: string }[];
// Determines position of the field within the form.
order: number;
// Used for cases where we have multiple options such as dropdowns, radios, or checkboxes.
options?: { label: string; value: string; selected?: boolean }[];
}