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-core2. 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}
  ]
})