MdDynamicForms is a form automation library to create forms in a declarative way. It's fast and easy to use and comes with built-in components to get started right away. You get the form as model and as template created from one configuration.
The idea is based off of the official Angular guide
To see a live-demo with different sample-forms click here (if the app is in sleeping mode then refresh after a few seconds)
1. Install the core package
npm i md-dynamic-forms-core
2. Install a UI-Library of your choice
npm i md-dynamic-forms-<lib-name>
3. Import the modules
import {MdDynamicFormsCoreModule} from 'md-dynamic-forms-core';
import {MdDynamicFormsMaterialModule} from 'md-dynamic-forms-material';
@NgModule({
imports: [
MdDynamicFormsCoreModule,
MdDynamicFormsMaterialModule
]
})
export class AppModule { }
4. Create your Model
export const YOUR_MODEL = new FieldGroup({
name: 'nameOfYourForm',
children: [
new FieldInput({
name: 'nameOfYourControl',
label: 'LabelOfControl'
})
]
});
5. Import into component and use
export class FormWrapperComponent implements OnInit {
config: FieldGroup = YOUR_MODEL;
form: FormGroup;
initialValue = null;
constructor() { }
ngOnInit(): void {
}
submit(formValue: any) {
// Do your submit logic
}
}
<md-dynamic-forms-core [config]="config"
[value]="initialValue"
(submit)="submit($event)"
(formChange)="form = $event">
</md-dynamic-forms-core>
md-dynamic-forms-core | ngx-bootstrap | material | clarity | |
---|---|---|---|---|
Checkbox | ✔️ | ❌ | ✔️ | 🔜 |
Colorpicker | ❌ | ❌ | ❌ | ❌ |
Currency | ❌ | ❌ | ❌ | ❌ |
Datepicker | ✔️ | ❌ | ✔️ | 🔜 |
Editor | ❌ | ❌ | ❌ | ❌ |
File Upload | ✔️ | ❌ | ❌ | ❌ |
Input | ✔️ | ❌ | ✔️ | 🔜 |
MultiInput | ✔️ | ❌ | ❌ | ❌ |
Radio Group | ✔️ | ❌ | ✔️ | 🔜 |
Rating | ❌ | ❌ | ❌ | ❌ |
Select | ✔️ | ❌ | ✔️ | 🔜 |
Slider | ✔️ | ❌ | ✔️ | 🔜 |
Switch | ✔️ | ❌ | ✔️ | 🔜 |
Textarea | ✔️ | ❌ | ✔️ | ❌ |
Timepicker | ❌ | ❌ | ❌ | ❌ |
Toggle | ✔️ | ❌ | ✔️ | 🔜 |
DecisionToggle | ❌ | ❌ | ❌ | ❌ |
md-dynamic-forms-core | ngx-bootstrap | material | clarity | |
---|---|---|---|---|
BaseGroup | ✔️ | ❌ | ✔️ | 🔜 |
LayoutGroup | ✔️ | ❌ | ❌ | ❌ |
CombineGroup | ❌ | ❌ | ❌ | ❌ |
md-dynamic-forms-core | ngx-bootstrap | material | clarity | |
---|---|---|---|---|
List | ✔️ | ❌ | ❌ | ❌ |
Table | ✔️ | ❌ | ✔️ | 🔜 |
GroupedTable | ❌ | ❌ | ❌ | ❌ |
CheckboxGroup | ❌ | ❌ | ❌ | ❌ |
MultiToggle | ❌ | ❌ | ❌ | ❌ |
- ✔️ implemented
- ❌ not implemented
- 🔜 work in progress
- 🔄 adjustment coming
So controls are single-elements that represent a value in the form. You can create different types of controls by using differnt field-classes
FieldInput
new FieldInput({
name: 'firstname',
label: 'Firstname',
hint: 'enter your firstname', // optional
inputType: 'text', // optional
maxLength: 255, // optional
validations: [], // optional,
asyncValidations: [], // optional
readonly: false, // optional
id: 'firstname' // optional
})
FieldTextarea
new FieldTextarea({
name: 'description',
label: 'Description',
hint: '', // optional
maxLength: 2000, // optional
validations: [], // optional
asyncValidations: [], // optional
readonly: false, // optional
id: 'description' // optional
})
FieldSelect
new FieldSelect({
name: 'product',
label: 'Product',
options: () => of([{value: '1234-4121', label: 'Laptop'}]),
hint: 'Choose your product', // optional
validations: [], // optional
asyncValidations: [], // optional
readonly: false, // optional
id: 'product' // optional
});
FieldDatepicker
new FieldDatepicker({
name: 'birthdate',
label: 'Date of birth',
hint: 'Choose your birthdate', // optional
validations: [], // optional
asyncValidations: [], // optional
readonly: false, // optional
id: 'birthdate' // optional
});
FieldCheckbox
new FieldCheckbox({
name: 'expressShipping',
label: 'Express-Shipping?',
hint: '', // optional
validations: [], // optional
asyncValidations: [], // optional
readonly: false, // optional
id: 'expressShipping' // optional
});
FieldRadio
new FieldRadio({
name: 'paymentMethod',
label: 'Payment-Method',
options: () => of([]),
hint: 'Choose your payment', // optional
validations: [], // optional
asyncValidations: [], // optional
readonly: false, // optional
id: 'payment_method' // optional
});
FieldToggle
new FieldToggle({
name: 'paymentMethod',
label: 'Payment-Method',
options: () => of([]),
hint: 'Choose your payment', // optional
validations: [], // optional
asyncValidations: [], // optional
readonly: false, // optional
id: 'payment_method' // optional
});
FieldSwitch
new FieldSwitch({
name: 'lightSwitch',
label: 'Light-Switch',
hint: '', // optional
validations: [], // optional
asyncValidations: [], // optional
readonly: false, // optional
id: 'light_switch' // optional
});
FieldSlider
new FieldSlider({
name: 'volume',
label: 'Volume',
min: 0,
max: 100,
step: 1,
withThumbLabel: true,
hint: '', // optional
validations: [], // optional
asyncValidations: [], // optional
readonly: false, // optional
id: 'volume' // optional
});
So groups contain multiple controls, groups or arrays to have them all together. Currently there is only one Group implmented but there are more to come.
FieldGroup
new FieldGroup({
name: 'adress',
children: [], // more groups or fields
validations: [], // optional
asyncValidations: [], // optional
id: 'adress', // optional
readonly: false // optional
});
Arrays are configuring lists so you can display or edit multiple Values of a type of group or control
FieldTable
new FieldTable({
name: 'adress',
listItem: new FieldGroup({}), // more groups or fields
config: {width: 100, countActive: false},
columns: [{name: '', heading: '', width: 0, sortable: false}],
validations: [], // optional
asyncValidations: [], // optional
id: 'adress', // optional
readonly: false // optional
});
You can configure multiple validations per field and also asynchronous validations to validate through a backend. One validation-configuration consists of the following fields
interface Validator {
name: string;
validator: ValidatorFn;
message: string;
}
interface AsyncValidator {
name: string;
validator: AsyncValidatorFn;
message: string;
}
with that you can create validations for your formular to provide better quality and user-experience. here is a example
new FieldSelect({
name: 'product',
options: () => of(PRODUCTS),
label: 'Item',
validations: [
{name: 'required', message: 'Field is required', validator: Validators.required}
]
})