A dynamic form generator using Typescript Decorators.
More info in Dynamic Forms.
The default components use Angular Material. Add with ng add @angular/material
. Install the library ng add @guihss/ngx-dynamic-forms
.
Annotate the class you want to generate the form.
export class User {
@FormInput({ label: "Name", type: "text" })
name = 'Bob';
@FormInput({ label: "Password", type: "password"})
password;
@FormInput({ label: "Email", type: "email"})
email;
}
Create an observable instance.
export class AppComponent {
title = 'dynamic-forms-showcase';
user: Observable<User> = of<User>(new User());
}
Add the dynamic-forms component to your page.
<mat-card>
<h1> Example form </h1>
<dynamic-form
formStyleClass="dynamic-form"
[objectObservable]="user"
></dynamic-form>
</mat-card>
And see the result :D
The inputs are rendered in the defined order and uses any values in the field as default.
You can access the data inserted in the form with.
class AppComponent {
/* ... */
@ViewChild(DynamicFormsComponent) dynamicForm: DynamicFormsComponent;
ngAfterViewInit(): void {
let formResult = this.dynamicForm.getResult();
}
}
The result is a json with field names equals to the annotated field. Filled with the form values.
let formResult = {
name: 'Bob',
password: 'verysecurepassword',
email: ''
}
With dynamic forms you can use your own components.
ng generate component custom-input
Implement the ConfigurableInput interface.
export class CustomInputComponent implements ConfigurableInput {
formControl = new FormControl();
applyArguments(args: any): any {
/* here you can use the args passed in the annotation
to configure your input. */
}
getFormControl(): any {
return this.formControl;
}
}
Use the @CustomInput
annotation in your model.
export class User {
/* ... */
@CustomInput(CustomInputComponent, {label: "Custom Input", args: {}})
myCustomInput;
}
You can nest inputs with dynamic forms.
export class NestedObject {
@FormInput({ label: "street", type: "text" })
street;
@FormInput({ label: "city", type: "text" })
city;
}
export class User {
/* ... */
@NestedInput('Address', /* search depth */ 1)
address = new NestedObject();
}
Result:
The form data are nested too.
let formResult = {
name: 'Bob',
password: 'verysecurepassword',
email: '',
myCustomInput: '',
address: {
street: '',
city: ''
}
}
The code has a showcase to help you in development if you want to improve the library.
Run with ng serve
.