Quellcode durchsuchen

Now generating FormArrays containing FormGroups, for repeating containers

Richard Knight vor 6 Jahren
Ursprung
Commit
9ebefee9c3
1 geänderte Dateien mit 36 neuen und 29 gelöschten Zeilen
  1. 36 29
      src/app/dynaform/services/_formdata-utils.ts

+ 36 - 29
src/app/dynaform/services/_formdata-utils.ts

@@ -14,10 +14,11 @@
  *
  * Variable names
  * --------------
- * metaF   = metadata for Field
- * metaG   = metadata for Group (possibly nested)
- * metaFoG = metadata for Field or Group
- * rcMem   = Repeating Container member
+ * metaF       = metadata for Field
+ * metaG       = metadata for Group (possibly nested)
+ * metaFoG     = metadata for Field or Group
+ * rcMem       = Repeating Container member
+ * metaFoRCMem = metadata for Field or Repeating Container member
  *
  */
 
@@ -78,24 +79,7 @@ const combineExtraMeta = (metaG, extraMeta, createFromExtra = false, containerSe
 			
 			// Have we got a repeating container?
 			if (isCon && isRepeating) {
-				const repeatInAutoMeta = Array.isArray(metaFoG.meta) ? metaFoG.meta.length : 0;
-				const repeatInExtraMeta = val['initialRepeat'] || val['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 = val['meta'] && val['meta'][0] ? Object.keys(val['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 array from model (if any) to length repeat
-				const repeatedGroup = repeatInAutoMeta ? 
-					[ ...metaFoG.meta, ...Array(repeat - repeatInAutoMeta).fill({ meta: baseObjWithAllKeys }) ] :
-					Array(repeat).fill({ meta: baseObjWithAllKeys });
-				const fullyNamedRepeatedGroup = repeatedGroup.map((rgMem, i) => rgMem.name ? rgMem : { name: `group${i + 1}`, ...rgMem });
-
-				metaFoG.meta = fullyNamedRepeatedGroup;
+				metaFoG.meta = generateRepeatedGroup(metaFoG, val, createFromExtra);
 				const extra = {
 					...omit(['meta', 'seed'], val),
 					meta: metaFoG.meta.map(
@@ -108,7 +92,6 @@ const combineExtraMeta = (metaG, extraMeta, createFromExtra = false, containerSe
 					)
 				};
 				combinedMeta[key] = combineMetaForField(metaFoG, {}, extra);
-				console.log('combinedMeta IS', combinedMeta[key]);
 			}
 			else
 			{
@@ -134,6 +117,28 @@ const combineExtraMeta = (metaG, extraMeta, createFromExtra = false, containerSe
 // Combine model with overrides (after automatically generating metadata from the model)
 const combineModelWithMeta = (model, extraMeta, createFromExtra = false) => combineExtraMeta(autoMeta(model), extraMeta, createFromExtra);
 
+// <--- Utilities supporting Repreating Containers --->
+
+const generateRepeatedGroup = (metaFoG, extraMeta, createFromExtra = false): 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
+	const repeatedGroup = repeatInAutoMeta ? 
+		[ ...metaFoG.meta, ...Array(repeat - repeatInAutoMeta).fill({ meta: baseObjWithAllKeys }) ] :
+		Array(repeat).fill({ meta: baseObjWithAllKeys });
+	const fullyNamedRepeatedGroup = repeatedGroup.map((rgMem, i) => rgMem.name ? rgMem : { name: `group${i + 1}`, ...rgMem });
+	return fullyNamedRepeatedGroup;
+}
 
 // ---------------------------------------------------------------------------------------------------------------------
 // Build Form-Field-Type-Specific Metadata (using the field models in dynaform/models)
@@ -149,9 +154,6 @@ const buildFieldClassName = (t = 'text') => {
 
 const buildModeledField = metaFoG => {
 	const type = isContainer(metaFoG) ? (isRepeatingContainer(metaFoG) ? 'repeatingContainer' : 'container') : metaFoG.type;
-	// console.log('-----------------');
-	// console.log(metaFoG);
-	// console.log(type);
 	const className = buildFieldClassName(type);
 	if (!fmdModels[className]) {
 		throw new Error(`No metadata model "${className}" for type "${type}"`);
@@ -168,7 +170,6 @@ const buildModeledFieldGroupMember = metaFoG => {
 	return modeledGroupMember;
 };
 
-// Build Form Group ********* CONTINUE WORK HERE
 const buildModeledFieldGroupReducerIteree = (res, metaFoG) => ({ ...res, [metaFoG.name]: buildModeledFieldGroupMember(metaFoG) });
 const _buildFieldSpecificMeta = metaG => Array.isArray(metaG) ?
 	metaG.map(rcMem => _buildFieldSpecificMeta(rcMem)) :
@@ -321,9 +322,15 @@ const buildFormGroupFunctionFactory = (fb: FormBuilder): (meta) => FormGroup =>
 	const buildFormControl = metaF => new FormControl(buildControlState(metaF), buildValidators(metaF));
 
 	// Build Form Array
-	const buildFormArray = (metaG): FormArray => fb.array(metaG.map(metaF => buildFormControl(metaF)));
+	const buildFormArray = (metaG): FormArray => {
+		return fb.array(
+			metaG.map(
+				metaFoRCMem => isRepeatingContainerMember(metaFoRCMem) ? _buildFormGroup(metaFoRCMem) : buildFormControl(metaFoRCMem)
+			)
+		);
+	};
 
-	// Build Form Group Member - builds a FormControl, FormArray, or another FormGroup which can contain any of these
+	// Build Form Group Member - builds a FormControl, FormArray or another FormGroup - which in turn can contain any of these
 	const buildFormGroupMember = metaFoG => isGroup(metaFoG) ?
 		(isArray(metaFoG.meta) ? buildFormArray(metaFoG.meta) : _buildFormGroup(metaFoG.meta)) :
 		buildFormControl(metaFoG);