|
@@ -1,7 +1,8 @@
|
|
|
import { Component, Input, Output, EventEmitter, TemplateRef, Optional, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
|
|
-import { FormControl, FormGroup, FormArray, FormGroupName, AbstractControl, ControlContainer } from '@angular/forms';
|
|
|
+import { FormBuilder, FormControl, FormGroup, FormArray, FormGroupName, AbstractControl, ControlContainer } from '@angular/forms';
|
|
|
import { SuperForm } from 'angular-super-validator';
|
|
|
-import { unwrapResolvedMetadata } from '@angular/compiler';
|
|
|
+import { buildFormGroupFunctionFactory } from './services/_formdata-utils';
|
|
|
+import { cloneDeep } from 'lodash/fp';
|
|
|
|
|
|
export interface DynarowContext {
|
|
|
control: AbstractControl;
|
|
@@ -12,7 +13,7 @@ export interface DynarowContext {
|
|
|
selector: 'app-dynaform',
|
|
|
templateUrl: './dynaform.component.html',
|
|
|
styleUrls: ['./dynaform.component.scss'],
|
|
|
- changeDetection: ChangeDetectionStrategy.OnPush
|
|
|
+ changeDetection: ChangeDetectionStrategy.Default // or ChangeDetectionStrategy.OnPush - might be more efficient. Experiment later.
|
|
|
})
|
|
|
export class DynaformComponent implements OnInit {
|
|
|
|
|
@@ -151,7 +152,7 @@ export class DynaformComponent implements OnInit {
|
|
|
getRowClass(control: FormControl, meta: StringMap<any>): string {
|
|
|
const fieldTypeClass = meta.type ? meta.type.toLowerCase().replace('component', '') : '';
|
|
|
const fieldClass = Array.isArray(meta.class) ? meta.class.join(' ') : meta.class;
|
|
|
- const containerClass = fieldClass ? ` container-${fieldClass}` : '';
|
|
|
+ const containerClass = fieldClass ? (meta.type === 'Container' ? ` ${fieldClass}` : ` row-${fieldClass}`) : '';
|
|
|
const errorClass = control && control.touched && control.invalid ? ' dyna-error' : '';
|
|
|
return `row-${fieldTypeClass}${containerClass}${errorClass}`;
|
|
|
}
|
|
@@ -180,14 +181,48 @@ export class DynaformComponent implements OnInit {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ // RC = Repeating Container
|
|
|
+ addRCMemberAllowed(repeatingContainerName: string): boolean {
|
|
|
+ const rcMeta = this.formMetaData[repeatingContainerName];
|
|
|
+ return typeof rcMeta.maxRepeat === 'number' && rcMeta.maxRepeat > rcMeta.meta.length;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Maybe move the AddRC and deleteRC funtions to _formdata-utils.ts ?
|
|
|
addRCMember(repeatingContainerName: string): void {
|
|
|
+ // (1) Check that we can still add controls
|
|
|
+ if (!this.addRCMemberAllowed(repeatingContainerName)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // (2) Add metadata for new container member
|
|
|
const rcMeta = this.formMetaData[repeatingContainerName];
|
|
|
- rcMeta.meta.push(rcMeta.__defaultContainer);
|
|
|
- console.log(rcMeta);
|
|
|
+ const containerTemplate = cloneDeep(rcMeta.__containerTemplate);
|
|
|
+ const i = this.formMetaData[repeatingContainerName].meta.length;
|
|
|
+ containerTemplate.name = `group${i+1}`;
|
|
|
+ rcMeta.meta.push(containerTemplate);
|
|
|
+ // (3) Add FormGroup for new container member
|
|
|
+ const buildFormGroup = buildFormGroupFunctionFactory(new FormBuilder());
|
|
|
+ const newFormGroup = buildFormGroup(containerTemplate.meta);
|
|
|
+ (this.formGroup.get(repeatingContainerName) as FormArray).push(newFormGroup);
|
|
|
}
|
|
|
|
|
|
- deleteRCMember(repeatingContainerName: string, index: number): void {
|
|
|
+ deleteRCMemberAllowed(repeatingContainerName: string): boolean {
|
|
|
+ const rcMeta = this.formMetaData[repeatingContainerName];
|
|
|
+ return typeof rcMeta.minRepeat === 'number' && rcMeta.minRepeat < rcMeta.meta.length;
|
|
|
+ }
|
|
|
|
|
|
+ deleteRCMember(repeatingContainerName: string, index: number): void {
|
|
|
+ // (1) Check that we can still delete controls
|
|
|
+ if (!this.deleteRCMemberAllowed(repeatingContainerName)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // (2) Delete from the metadata, and rename the groups
|
|
|
+ const rcMeta = this.formMetaData[repeatingContainerName];
|
|
|
+ const metaArr = rcMeta.meta;
|
|
|
+ const newMetaArr = [ ...metaArr.slice(0, index), ...metaArr.slice(index + 1) ]
|
|
|
+ .map((m, i) => { m.name = `group${i+1}`; return m; });
|
|
|
+ rcMeta.meta = newMetaArr;
|
|
|
+ // (3) Delete the corresponding FormGroup from the FormArray
|
|
|
+ (this.formGroup.get(repeatingContainerName) as FormArray).removeAt(index);
|
|
|
}
|
|
|
|
|
|
getValidationFailureMessage(control: FormControl, meta: StringMap<any>) {
|