Examples
This page shows an end-to-end example:
- Create two field model classes:
TextboxField,TextareaField - Create two field components:
TextboxComponent,TextareaComponent - Register them in
NvsDynamicFormModule.forRoot(...) - Render a form in a page and handle submit
The exact HTML/CSS is up to you — the important part is the contract: each field component should be able to render based on its field model, and connect to the underlying form control.
1) Create field model classes
Create a shared base if you want, but the simplest approach is to extend whatever base types your project uses.
In this example, field model classes extend FieldBase<T> from the library.
textbox.type.ts
import { TemplateRef } from '@angular/core';
import { FieldBase } from '@nvs-dynamic-form/ng-core';
export class TextboxField extends FieldBase<string> {
override readonly fieldType? = 'textbox';
icon?: TemplateRef<any>;
onIconClick?: (value?: string) => void;
type?: 'email' | 'number' | 'password' | 'tel' | 'text' | 'url';
placeholder?: string;
constructor(options: TextboxField) {
super(options, '');
this.type = options.type ?? 'text';
this.icon = options.icon;
this.placeholder = options.placeholder ?? '';
this.onIconClick = options.onIconClick;
}
}
textarea.type.ts
import { FieldBase } from '@nvs-dynamic-form/ng-core';
export class TextareaField extends FieldBase<string> {
override readonly fieldType? = 'textarea';
minRowSize?: number;
placeholder?: string;
maxRowSize?: number;
constructor(options: TextareaField) {
super(options, '');
this.minRowSize = options.minRowSize ?? 3;
this.maxRowSize = options.maxRowSize ?? 10;
this.placeholder = options.placeholder ?? '';
}
}
2) Create field components
These are standard Angular components that should:
- receive the field instance (your
TextboxField/TextareaField) - bind to the correct
FormControlin the form
Your project may use a shared base component for field rendering. If so, adapt the inputs accordingly.
Textbox component
textbox.component.ts
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { TextboxField } from './textbox.type';
@Component({
selector: 'app-textbox',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
template: `
<label class="field">
<span class="label">{{ field.label }}</span>
<input
class="input"
[type]="field.type ?? 'text'"
[placeholder]="field.placeholder ?? ''"
[formControl]="control"
/>
</label>
`,
})
export class TextboxComponent {
@Input({ required: true }) field!: TextboxField;
@Input({ required: true }) control!: FormControl;
}
Textarea component
textarea.component.ts
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { TextareaField } from './textarea.type';
@Component({
selector: 'app-textarea',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
template: `
<label class="field">
<span class="label">{{ field.label }}</span>
<textarea
class="textarea"
[rows]="field.minRowSize ?? 3"
[placeholder]="field.placeholder ?? ''"
[formControl]="control"
></textarea>
</label>
`,
})
export class TextareaComponent {
@Input({ required: true }) field!: TextareaField;
@Input({ required: true }) control!: FormControl;
}
3) Register fields in NvsDynamicFormModule
Register your field names and connect each name to its component + field model class.
app.config.ts
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { NvsDynamicFormModule } from '@nvs-dynamic-form/ng-core';
import { TextboxComponent } from './components/fields/textbox/textbox.component';
import { TextboxField } from './components/fields/textbox/textbox.type';
import { TextareaComponent } from './components/fields/textarea/textarea.component';
import { TextareaField } from './components/fields/textarea/textarea.type';
import { ButtonComponent } from './components/button/button.component';
export const appConfig: ApplicationConfig = {
providers: [
importProvidersFrom(
NvsDynamicFormModule.forRoot({
formFields: {
textbox: {
component: TextboxComponent,
class: TextboxField,
},
textarea: {
component: TextareaComponent,
class: TextareaField,
},
},
submitButton: {
component: ButtonComponent,
defaultOptions: {
label: 'Save',
isFullWidth: true,
position: 'center',
visible: true,
},
},
}),
),
],
};
4) Build a page that renders the dynamic form
Create a page (or component) that constructs the fields array and renders nvs-dynamic-form.
profile-form.page.ts
import { Component } from '@angular/core';
import { Validators } from '@angular/forms';
import { NvsDynamicFormModule } from '@nvs-dynamic-form/ng-core';
import { TextboxField } from '../components/fields/textbox/textbox.type';
import { TextareaField } from '../components/fields/textarea/textarea.type';
@Component({
standalone: true,
selector: 'app-profile-form-page',
imports: [NvsDynamicFormModule],
template: `
<h1>Profile</h1>
<nvs-dynamic-form
[fields]="fields"
submitButtonLabel="Save"
(onSubmit)="onSubmit($event)"
></nvs-dynamic-form>
`,
})
export class ProfileFormPage {
fields = [
new TextboxField({
label: 'First name',
key: 'firstName',
placeholder: 'Jane',
validators: [Validators.required],
screenSize: { desktop: 6, mobile: 12 },
}),
new TextboxField({
label: 'Last name',
key: 'lastName',
placeholder: 'Doe',
screenSize: { desktop: 6, mobile: 12 },
}),
new TextareaField({
label: 'About',
key: 'about',
placeholder: 'Tell us about yourself…',
minRowSize: 6,
screenSize: 12,
}),
];
onSubmit({ values, valid }: { values: any; valid: boolean }) {
if (!valid) return;
console.log(values);
}
}