Explorar o código

Working on adding extra Repeating Containers

Richard Knight %!s(int64=6) %!d(string=hai) anos
pai
achega
ef26a649d0

+ 12 - 0
src/app/dynaform/dynaform.component.html

@@ -35,11 +35,23 @@
 							(click)="focusContainer(meta.name, i)">
 							{{ getRCLabel(meta.name, i) }}
 						</a>
+						<a *ngIf="meta.showAddControl"
+							class="btn btn-sm btn-outline-success"
+							(click)="addRCMember(meta.name)">
+							+ Add New
+						</a>
 					</div>
 				</div>
 				<div *ngFor="let container of meta.meta; let i = index" class="dyna-rc-container" [ngClass]="{ 'dyna-rc-display-all': meta.display === 'ALL' }">
 					<ng-container *ngTemplateOutlet="dynaform; context: getRCTemplateContext(meta.name, i)"></ng-container>
 				</div>
+				<div *ngIf="meta.showAddControl && meta.display === 'ALL'" class="row">
+					<div class="col-sm-12">
+						<a class="btn btn-sm btn-outline-success" (click)="addRCMember(meta.name)">
+							+ Add New
+						</a>
+					</div>
+				</div>
 			</ng-container>
 		</ng-template>
 

+ 17 - 5
src/app/dynaform/dynaform.component.ts

@@ -1,7 +1,7 @@
 import { Component, Input, Output, EventEmitter, TemplateRef, Optional, OnInit, ChangeDetectionStrategy } from '@angular/core';
 import { FormControl, FormGroup, FormArray, FormGroupName, AbstractControl, ControlContainer } from '@angular/forms';
 import { SuperForm } from 'angular-super-validator';
-import { createMeta } from '@angular/platform-browser/src/browser/meta';
+import { unwrapResolvedMetadata } from '@angular/compiler';
 
 export interface DynarowContext {
 	control: AbstractControl;
@@ -140,9 +140,9 @@ export class DynaformComponent implements OnInit {
 	}
 
 	getRCTemplateContext(repeatingContainerName: string, index: number): DynarowContext {
-		const repeatingContainerFormArray = this.formGroup.get(repeatingContainerName) as FormArray;
+		const rcFormArray = this.formGroup.get(repeatingContainerName) as FormArray;
 		const result = {
-			control: repeatingContainerFormArray.at(index),
+			control: rcFormArray.at(index),
 			meta: this.formMetaData[repeatingContainerName]['meta'][index]
 		};
 		return result;
@@ -163,8 +163,8 @@ export class DynaformComponent implements OnInit {
 		const primaryField = rcMeta.primaryField;
 		if (primaryField) {
 			// The primaryField has been specified, so return its value
-			const repeatingContainerFormArray = this.formGroup.get(repeatingContainerName) as FormArray;
-			const formGroup = repeatingContainerFormArray.at(index);
+			const rcFormArray = this.formGroup.get(repeatingContainerName) as FormArray;
+			const formGroup = rcFormArray.at(index);
 			return formGroup.get(primaryField).value || '…';
 		} else {
 			// Otherwise return the 'button' of the container (in the array of containers)
@@ -175,7 +175,19 @@ export class DynaformComponent implements OnInit {
 	focusContainer(repeatingContainerName: string, index: number): void {
 		// Show a particular container of a Repeating Container group (used when only one is shown at a time i.e display = 'SINGLE')
 		const rcMeta = this.formMetaData[repeatingContainerName];
+		const rcFormArray = this.formGroup.get(repeatingContainerName) as FormArray;
 		rcMeta.meta = rcMeta.meta.map( (container, i) => ({ ...container, focussed: i === index }) );
+		
+	}
+
+	addRCMember(repeatingContainerName: string): void {
+		const rcMeta = this.formMetaData[repeatingContainerName];
+		rcMeta.meta.push(rcMeta.__defaultContainer);
+		console.log(rcMeta);
+	}
+
+	deleteRCMember(repeatingContainerName: string, index: number): void {
+
 	}
 
 	getValidationFailureMessage(control: FormControl, meta: StringMap) {

+ 16 - 8
src/app/dynaform/services/_formdata-utils.ts

@@ -25,7 +25,6 @@
 import { FormBuilder, FormGroup, FormArray, FormControl, AbstractControlOptions } from '@angular/forms';
 import { cloneDeep, omit, reduce } from 'lodash/fp';
 import * as fmdModels from '../models/field.model';
-import { ComponentFactoryResolver } from '@angular/core/src/render3';
 
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -80,7 +79,8 @@ const combineExtraMeta = (metaG, extraMeta, createFromExtra = false, containerSe
 			if (isRepeating)
 			{
 				// We've got a Repeating Container
-				metaFoG.meta = generateRepeatedGroup(metaFoG, val, createFromExtra);
+				const baseObjWithAllKeys = getRCBaseObjectWithAllKeys(metaFoG, val, createFromExtra);
+				metaFoG.meta = generateRepeatedGroup(metaFoG, val, baseObjWithAllKeys);
 				const extra = {
 					...omit(['meta', 'seed'], val),
 					meta: metaFoG.meta.map(
@@ -93,6 +93,7 @@ const combineExtraMeta = (metaG, extraMeta, createFromExtra = false, containerSe
 					)
 				};
 				combinedMeta[key] = combineMetaForField(metaFoG, {}, extra);
+				combinedMeta[key].__defaultContainer = cloneDeep(extra.meta[0]); // Stash for adding extra containers to the repeating container
 			}
 			else
 			{
@@ -121,17 +122,12 @@ const combineModelWithMeta = (model, extraMeta, createFromExtra = false) => comb
 
 // <--- Utilities supporting Repreating Containers --->
 
-const generateRepeatedGroup = (metaFoG, extraMeta, createFromExtra = false): StringMap[] => {
+const generateRepeatedGroup = (metaFoG, extraMeta, baseObjWithAllKeys): StringMap[] => {
 	// Calculate the number of repeats
 	const repeatInAutoMeta = Array.isArray(metaFoG.meta) ? metaFoG.meta.length : 0;
 	const repeatInExtraMeta = extraMeta['initialRepeat'] || extraMeta['minRepeat'];
 	const repeat = Math.max(repeatInAutoMeta, repeatInExtraMeta);
 
-	// If creating from extra, make sure all group members have all keys in both model and meta (as this is a repeating group)
-	const keysFromModel = repeatInAutoMeta ? Object.keys(metaFoG.meta[0].meta) : [];
-	const keysFromExtraMeta = extraMeta['meta'] && extraMeta['meta'][0] ? Object.keys(extraMeta['meta'][0]) : [];
-	const keysToInclude = createFromExtra ? Array.from(new Set([...keysFromModel, ...keysFromExtraMeta])) : keysFromModel;
-	const baseObjWithAllKeys = autoMeta(keysToInclude.reduce((acc, key) => addProp(acc, key, ''), {}));
 	metaFoG.meta = metaFoG.meta.map( rcMem => ({ ...rcMem, meta: { ...baseObjWithAllKeys, ...rcMem.meta } }) ); // Add extra keys to model meta
 
 	// Extend repeated group from model (if any) to correct length, and add any missing names
@@ -142,6 +138,17 @@ const generateRepeatedGroup = (metaFoG, extraMeta, createFromExtra = false): Str
 	return fullyNamedRepeatedGroup;
 }
 
+// Get Repeating Container Base Object With All Keys
+const getRCBaseObjectWithAllKeys = (metaFoG, extraMeta, createFromExtra = false): StringMap => {
+	// If creating from extra, make sure all group members have all keys in both model and meta (as this is a repeating group)
+	const keysFromModel = isArray(metaFoG.meta) && metaFoG.meta.length ? Object.keys(metaFoG.meta[0].meta) : [];
+	const keysFromExtraMeta = extraMeta['meta'] && extraMeta['meta'][0] ? Object.keys(extraMeta['meta'][0]) : [];
+	const keysToInclude = createFromExtra ? Array.from(new Set([...keysFromModel, ...keysFromExtraMeta])) : keysFromModel;
+	const baseObjWithAllKeys = autoMeta(keysToInclude.reduce((acc, key) => addProp(acc, key, ''), {}));
+	return baseObjWithAllKeys;
+}
+
+
 // ---------------------------------------------------------------------------------------------------------------------
 // Build Form-Field-Type-Specific Metadata (using the field models in dynaform/models)
 // ---------------------------------------------------------------------------------------------------------------------
@@ -183,6 +190,7 @@ const buildModeledFieldGroupMember = metaFoG => {
 		modeledGroupMember.meta = _buildFieldSpecificMeta(modeledGroupMember.meta);
 	} else if (isRepeatingContainer(metaFoG)) {
 		modeledGroupMember.meta = modeledGroupMember.meta.map(rcMem => ({ ...rcMem, meta: _buildFieldSpecificMeta(rcMem.meta) }));
+		modeledGroupMember.__defaultContainer = _buildFieldSpecificMeta(modeledGroupMember.__defaultContainer);
 	}
 	return modeledGroupMember;
 };

+ 1 - 5
src/styles.scss

@@ -107,13 +107,9 @@ div.col-sm-8 {
 	}
 }
 
-.dyna-rc-container.dyna-rc-display-all {
+.dyna-rc-container.dyna-rc-display-all, .dyna-rc-control.dyna-rc-display-all {
 	margin-bottom: 7px;
 	border-bottom: 4px #CCC solid;
-	&:last-child {
-		margin-bottom: unset;
-		border-bottom: unset;
-	}
 }
 
 .dyna-hidden {