# ng-dynamic-forms **Repository Path**: 2103625/ng-dynamic-forms ## Basic Information - **Project Name**: ng-dynamic-forms - **Description**: Rapid form development library for Angular - **Primary Language**: TypeScript - **License**: ISC - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2017-11-17 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Logo NG Dynamic Forms # NG Dynamic Forms [![npm version](https://badge.fury.io/js/%40ng-dynamic-forms%2Fcore.svg)](https://badge.fury.io/js/%40ng-dynamic-forms%2Fcore) [![Build Status](https://travis-ci.org/udos86/ng-dynamic-forms.svg?branch=master)](https://travis-ci.org/udos86/ng-dynamic-forms) [![Coverage Status](https://coveralls.io/repos/github/udos86/ng-dynamic-forms/badge.svg)](https://coveralls.io/github/udos86/ng-dynamic-forms) [![DeepScan Grade](https://deepscan.io/api/projects/562/branches/912/badge/grade.svg)](https://deepscan.io/dashboard/#view=project&pid=562&bid=912) [![Downloads](http://img.shields.io/npm/dm/@ng-dynamic-forms/core.svg)](https://npmjs.org/package/@ng-dynamic-forms/core) *** :bangbang:09-14-2017: **@ng2-dynamic-forms has been renamed to @ng-dynamic-forms**:bangbang: *** NG Dynamic Forms is a **rapid form development library** based on the official Angular [**dynamic forms guide**](https://angular.io/docs/ts/latest/cookbook/dynamic-form.html). It **fully automates form UI creation** by introducing a set of maintainable **form control models** and **dynamic form control components** **Out of the box support** is provided for all popular UI libraries including **[Bootstrap](http://getbootstrap.com)**, **[Foundation](http://foundation.zurb.com/)**, **[Ionic](http://ionicframework.com/)**, **[Kendo](http://www.telerik.com/kendo-angular-ui)**, **[Material](https://material.angular.io/)**, **[NG Bootstrap](https://ng-bootstrap.github.io/#/home)** and **[PrimeNG](http://www.primefaces.org/primeng/#/)**. [**Explore it**](http://ng2-dynamic-forms.udos86.de/sample/index.aot.html) live in action! ## Table of Contents - [Getting Started](#getting-started) - [Running the Example](#running-the-example) - [Basic Usage](#basic-usage) - [UI Modules](#ui-modules) - [Form Groups](#form-groups) - [Form Arrays](#form-arrays) - [Form Layouts](#form-layouts) - [Form Control Events](#form-control-events) - [Custom Templates](#custom-templates) - [Custom Validators](#custom-validators) - [Validation Messaging](#validation-messaging) - [JSON Export / Import](#json-export--import) - [Updating Form Models](#updating-form-models) - [Disabling / Enabling Form Controls](#disabling--enabling-form-controls) - [Text Masks](#text-masks) - [Related Form Controls](#related-form-controls) - [Autocompletion](#autocompletion) - [AOT Compilation](#aot-compilation) - [FAQ](#faq) - [Appendix](#appendix) ## Getting Started **1. Install the core package**: ``` npm install @ng-dynamic-forms/core -S ``` **2. Choose your [UI library](#ui-modules)** and **install the appropriate package**: ``` npm install @ng-dynamic-forms/ui-bootstrap -S ``` **3.** When using **SystemJS**, update your configuration to **import the corresponding UMD bundles**: ```ts System.config({ paths: { "npm:": "node_modules/" }, map: { // ...all the rest (Angular, RxJS, etc.) "@ng-dynamic-forms/core": "npm:@ng-dynamic-forms/core/bundles/core.umd.js", "@ng-dynamic-forms/ui-bootstrap": "npm:@ng-dynamic-forms/ui-bootstrap/bundles/ui-bootstrap.umd.js", } }); ``` ## Running the Sample **1. Clone the Git repository**: ``` git clone https://github.com/udos86/ng-dynamic-forms.git ``` **2. Install the npm dependencies**: ``` npm install ``` **3. Build the library**: ``` npm run build:packages ``` **4. Transpile the sample code**: ``` npm run watch:sample ``` **5. Run the application**: ``` npm start ``` ## Basic Usage **1. Import** `DynamicFormsCoreModule` **via** `forRoot()` **and a UI module**: ```ts import { DynamicFormsCoreModule } from "@ng-dynamic-forms/core"; import { DynamicFormsBootstrapUIModule } from "@ng-dynamic-forms/ui-bootstrap"; // ... @NgModule({ imports: [ ReactiveFormsModule, DynamicFormsCoreModule.forRoot(), DynamicFormsBootstrapUIModule, // ... ] }) export class AppModule {} ``` **2. Define your form model**: ```ts import { DynamicFormControlModel, DynamicCheckboxModel, DynamicInputModel, DynamicRadioGroupModel } from "@ng-dynamic-forms/core"; export const MY_FORM_MODEL: DynamicFormControlModel[] = [ new DynamicInputModel({ id: "sampleInput", label: "Sample Input", maxLength: 42, placeholder: "Sample input" }), new DynamicRadioGroupModel({ id: "sampleRadioGroup", label: "Sample Radio Group", options: [ { label: "Option 1", value: "option-1", }, { label: "Option 2", value: "option-2" }, { label: "Option 3", value: "option-3" } ], value: "option-3" }), new DynamicCheckboxModel({ id: "sampleCheckbox", label: "I do agree" }) ]; ``` **3. Create a** `FormGroup` **via** `DynamicFormService`: ```ts import { MY_FORM_MODEL } from "./my-dynamic-form.model"; import { DynamicFormControlModel, DynamicFormService } from "@ng-dynamic-forms/core"; export class MyDynamicFormComponent implements OnInit { formModel: DynamicFormControlModel[] = MY_FORM_MODEL; formGroup: FormGroup; constructor(private formService: DynamicFormService) {} ngOnInit() { this.formGroup = this.formService.createFormGroup(this.formModel); } } ``` **4. Add a** `DynamicFormComponent` **to your template and bind its** `[group]` **and** `[model]` **property**: ```ts
``` ## UI Modules NG Dynamic Forms is built to provide **solid yet unobtrusive** support for a variety of common UI libraries: * **[Basic](https://github.com/udos86/ng-dynamic-forms/tree/master/packages/ui-basic)** * **[Bootstrap](https://github.com/udos86/ng-dynamic-forms/tree/master/packages/ui-bootstrap)** * **[Foundation](https://github.com/udos86/ng-dynamic-forms/tree/master/packages/ui-foundation)** * **[Ionic](https://github.com/udos86/ng-dynamic-forms/tree/master/packages/ui-ionic)** * **[Kendo UI](https://github.com/udos86/ng-dynamic-forms/tree/master/packages/ui-kendo)** * **[Material](https://github.com/udos86/ng-dynamic-forms/tree/master/packages/ui-material)** * **[NG Bootstrap](https://github.com/udos86/ng-dynamic-forms/tree/master/packages/ui-ng-bootstrap)** * **[PrimeNG](https://github.com/udos86/ng-dynamic-forms/tree/master/packages/ui-primeng)** You can instantly plug in your favorite form controls by **installing the appropriate package and its peer dependencies**: ``` npm install @ng-dynamic-forms/ui- -S ``` **Now just import the UI module**: ```ts @NgModule({ imports: [ ReactiveFormsModule, DynamicFormsCoreModule.forRoot(), DynamicFormsBootstrapUIModule // ... ] }) export class AppModule {} ``` For creating the form markup all UI modules come with a `DynamicFormComponent` that **can easily be added** to your component template: ```ts
``` Alternatively you can **directly make use of a specific** `DynamicFormControlComponent` to gain more control over rendering: ```ts
``` Due to technical restrictions or external dependencies still being in development the support of major form controls varies among UI packages. **See the following compatibility table**: | | ui-basic | ui-bootstrap | ui-foundation | ui-ionic | ui-kendo | ui-material | ui-ng-bootstrap | ui-primeng | |---------------- |:--------: |:------------: |:-------------: |:--------: |:--------: |:-----------: |:---------------: |:----------: | | Checkbox | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Checkbox Group | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Datepicker | * | * | * | ✓ | ✓ | * | ✓ | ✓ | | Editor | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | | File Upload | ** | ** | ** | ✗ | ✓ | ** | ** | ** | | Input | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Radio Group | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Rating | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | | Select | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Slider | *** | *** | *** | ✓ | ✓ | ✓ | *** | ✓ | | Switch | ✗ | ✗ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ | | Textarea | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Timepicker | * | * | * | ✓ | ✓ | * | ✓ | ✓ | **\*)** datetime controls can be achieved using a `DynamicInputModel` with `inputType: "date"` or `inputType: "time"` **\*\*)** file upload controls can be achieved using a `DynamicInputModel` with `inputType: "file"` **\*\*\*)** slider controls can be achieved using a `DynamicInputModel` with `inputType: "range"` ## Form Groups In order to improve clarity it's often considered good practice to group forms into several logical `fieldset` sections. Thus NG Dynamic Forms supports nesting of form groups out of the box! **1. Declare a** `DynamicFormGroupModel` within your form model and **add it's models to the** `group` **array**: ```ts export const MY_FORM_MODEL: DynamicFormControlModel[] = [ new DynamicFormGroupModel({ id: "fullName", legend: "Name", group: [ new DynamicInputModel({ id: "firstName", label: "First Name" }), new DynamicInputModel({ id: "lastName", label: "Last Name" }) ] }), new DynamicFormGroupModel({ id: "address", legend: "Address", group: [ new DynamicInputModel({ id: "street", label: "street" }), new DynamicInputModel({ id: "zipCode", label: "Zip Code" }) ] }) ]; ``` **2. Create a** `FormGroup` **and add a** `DynamicFormComponent`: ```ts ngOnInit() { this.formGroup = this.formService.createFormGroup(this.formModel); } ``` ```ts
``` **3. To manipulate an existing** `DynamicFormGroupModel` **you can simply use** `DynamicFormService`: * `addFormGroupControl(...)` * `insertFormGroupControl(...)` * `moveFormGroupControl(...)` * `removeFormGroupControl(...)` ## Form Arrays Sometimes forms need to allow the user to dynamically add multiple items of the same kind to it, e.g. addresses, products and so on. Particularly for this reason Angular provides so called [**Form Arrays**](https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2). Fortunately, NG Dynamic Forms is capable of managing such nested form structures! **1. Add a** `DynamicFormArrayModel` **to your form model**: ```ts export const MY_FORM_MODEL: DynamicFormControlModel[] = [ new DynamicFormArrayModel({ id: "myFormArray" }) ]; ``` **2. Add the** `groupFactory` **property** to the `DynamicFormArrayModel` **and assign a function** to it which **returns the structure** of a single form array item: ```ts new DynamicFormArrayModel({ id: "myFormArray", initialCount: 5, groupFactory: () => { return [ new DynamicInputModel({ id: "myInput", label: "My Input" }) ]; } }) ``` **3. Create a** `FormGroup` **via** `DynamicFormService` **and bind it to your component template**: ```ts this.formGroup = this.formService.createFormGroup(this.formModel); ``` ```ts
``` **4. You can now easily modify your form array with** `DynamicFormService`: ```ts ngOnInit() { this.formArrayControl = this.formGroup.get("myFormArray") as FormArray; this.formArrayModel = this.formService.findById("myFormArray", this.formModel) as DynamicFormArrayModel; } addItem() { this.formService.addFormArrayGroup(this.formArrayControl, this.formArrayModel); } clear() { this.formService.clearFormArray(this.formArrayControl, this.formArrayModel); } ``` Alright, works like a charm! But what if we want to append an additional remove ` ``` Whenever a `` is applied to a `DynamicFormArrayModel`, `NgTemplateOutletContext` **is internally bound to the associated** `DynamicFormArrayGroupModel`. That means **you can access the group object and it's properties by either declaring a local default template variable** or individual local template variables. > see chapter on [Custom Templates](#custom-templates) ```ts
``` This is extremely useful when you'd like to implement a remove or insert function: ```ts removeItem(context: DynamicFormArrayModel, index: number) { this.formService.removeFormArrayGroup(index, this.formArrayControl, context); } insertItem(context: DynamicFormArrayModel, index: number) { this.formService.insertFormArrayGroup(index, this.formArrayControl, context); } ``` Using `DynamicFormService` again, **you can even change the order of the groups** in a form array dynamically: ```ts this.formService.moveFormArrayGroup(index, -1, this.formArrayControl, context); ``` ## Form Layouts When using a NG Dynamic Forms UI package, e.g. `ui-bootstrap`, **all essential** form classes of the underlying CSS library (like `form-group` or `form-control`) are automatically put in place for you in the template of the corresponding `DynamicFormControlComponent`. Apart from that, NG Dynamic Forms does not make any further presumptions about optional CSS classes and leaves advanced layouting all up to you. That's **solid** yet **unobtrusive**. So let's say we want to implement a beautifully aligned Bootstrap [horizonal form](http://getbootstrap.com/css/#forms-horizontal)... At first we have to append the mandatory Bootstrap CSS class `form-horizontal` to the `
` element in our template: ```ts
``` Now we need to position the `