+
-
+
-
\ No newline at end of file
+
diff --git a/src/platform/dynamic-forms/dynamic-forms.component.ts b/src/platform/dynamic-forms/dynamic-forms.component.ts
index d096341a28..7a0b5f0c06 100644
--- a/src/platform/dynamic-forms/dynamic-forms.component.ts
+++ b/src/platform/dynamic-forms/dynamic-forms.component.ts
@@ -1,16 +1,20 @@
-import { Component, Input, ChangeDetectorRef } from '@angular/core';
+import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { FormGroup, FormBuilder, AbstractControl } from '@angular/forms';
import { TdDynamicFormsService, ITdDynamicElementConfig } from './services/dynamic-forms.service';
+import { timer } from 'rxjs/observable/timer';
+import { toPromise } from 'rxjs/operator/toPromise';
+
@Component({
selector: 'td-dynamic-forms',
templateUrl: './dynamic-forms.component.html',
+ changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TdDynamicFormsComponent {
+ private _renderedElements: ITdDynamicElementConfig[] = [];
private _elements: ITdDynamicElementConfig[];
-
dynamicForm: FormGroup;
/**
@@ -21,26 +25,14 @@ export class TdDynamicFormsComponent {
@Input('elements')
set elements(elements: ITdDynamicElementConfig[]){
if (elements) {
- if (this._elements) {
- this._elements.forEach((elem: ITdDynamicElementConfig) => {
- this.dynamicForm.removeControl(elem.name);
- });
- }
- let duplicates: string[] = [];
- elements.forEach((elem: ITdDynamicElementConfig) => {
- this._dynamicFormsService.validateDynamicElementName(elem.name);
- if (duplicates.indexOf(elem.name) > -1) {
- throw new Error(`Dynamic element name: "${elem.name}" is duplicated`);
- }
- duplicates.push(elem.name);
- this.dynamicForm.registerControl(elem.name, this._dynamicFormsService.createFormControl(elem));
- });
this._elements = elements;
- this._changeDetectorRef.detectChanges();
+ } else {
+ this._elements = [];
}
+ this._rerenderElements();
}
get elements(): ITdDynamicElementConfig[] {
- return this._elements;
+ return this._renderedElements;
}
/**
@@ -73,7 +65,7 @@ export class TdDynamicFormsComponent {
/**
* Getter property for [errors] of dynamic [FormGroup].
*/
- get errors(): {[name: string]: any} {
+ get errors(): { [name: string]: any } {
if (this.dynamicForm) {
let errors: {[name: string]: any} = {};
for (let name in this.dynamicForm.controls) {
@@ -99,4 +91,53 @@ export class TdDynamicFormsComponent {
private _changeDetectorRef: ChangeDetectorRef) {
this.dynamicForm = this._formBuilder.group({});
}
+
+ /**
+ * Refreshes the form and rerenders all validator/element modifications.
+ */
+ refresh(): void {
+ this._rerenderElements();
+ }
+
+ private _rerenderElements(): void {
+ this._clearRemovedElements();
+ this._renderedElements = [];
+ let duplicates: string[] = [];
+ this._elements.forEach((elem: ITdDynamicElementConfig) => {
+ this._dynamicFormsService.validateDynamicElementName(elem.name);
+ if (duplicates.indexOf(elem.name) > -1) {
+ throw new Error(`Dynamic element name: "${elem.name}" is duplicated`);
+ }
+ duplicates.push(elem.name);
+ if (!this.dynamicForm.get(elem.name)) {
+ this.dynamicForm.addControl(elem.name, this._dynamicFormsService.createFormControl(elem));
+ } else {
+ this.dynamicForm.get(elem.name).setValidators(this._dynamicFormsService.createValidators(elem));
+ }
+ // copy objects so they are only changes when calling this method
+ this._renderedElements.push(Object.assign({}, elem));
+ });
+ // call a change detection since the whole form might change
+ this._changeDetectorRef.detectChanges();
+ toPromise.call(timer()).then(() => {
+ // call a markForCheck so elements are rendered correctly in OnPush
+ this._changeDetectorRef.markForCheck();
+ });
+ }
+
+ private _clearRemovedElements(): void {
+ for (let i: number = 0; i < this._renderedElements.length; i++) {
+ for (let j: number = 0; j < this._elements.length; j++) {
+ // check if the name of the element is still there removed
+ if (this._renderedElements[i].name === this._elements[j].name) {
+ delete this._renderedElements[i];
+ break;
+ }
+ }
+ }
+ // remove elements that were removed from the array
+ this._renderedElements.forEach((elem: ITdDynamicElementConfig) => {
+ this.dynamicForm.removeControl(elem.name);
+ });
+ }
}
diff --git a/src/platform/dynamic-forms/services/dynamic-forms.service.ts b/src/platform/dynamic-forms/services/dynamic-forms.service.ts
index 3877ec5fab..f97026c003 100644
--- a/src/platform/dynamic-forms/services/dynamic-forms.service.ts
+++ b/src/platform/dynamic-forms/services/dynamic-forms.service.ts
@@ -36,6 +36,7 @@ export interface ITdDynamicElementConfig {
max?: any;
selections?: any[];
default?: any;
+ flex?: number;
}
export const DYNAMIC_ELEMENT_NAME_REGEX: RegExp = /^[a-zA-Z]+[a-zA-Z0-9-_]*$/;