Просмотр исходного кода

Beginninbg work on repeating groups

Richard Knight лет назад: 6
Родитель
Сommit
9410d2f2ad

+ 40 - 0
src/app/_mock/testfields.v12.ts

@@ -0,0 +1,40 @@
+// TESTS: Repeating Groups Of Fields ( 1 -> N arrays of containers for multiple fields )
+
+const model = {
+	container: [
+		{
+			a: 1,
+			b: 2,
+			c: 3,
+			d: 4
+		},
+		{
+			a: 5,
+			b: 6,
+			c: 7,
+			d: 8
+		}
+	]
+};
+
+const meta = {
+	container: {
+		label: 'Repating Group',
+		seed: { class: 'short-field' },
+		minRepeat: 1,
+		maxRepeat: 5,
+		initialRepeat: 2,
+		showAddControl: true,
+		showDeleteControl: true,
+		meta: [
+			{
+				a: {},
+				b: {},
+				c: {},
+				d: {},
+			}
+		]
+	}
+};
+
+export { model, meta };

+ 8 - 3
src/app/app.component.ts

@@ -13,10 +13,11 @@ import * as test8 from './_mock/testfields.v8';
 import * as test9 from './_mock/testfields.v9';
 import * as test10 from './_mock/testfields.v10';
 import * as test11 from './_mock/testfields.v11';
+import * as test12 from './_mock/testfields.v12';
 
-const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11 ];
+const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12 ];
 
-const defatltTest = 10;
+const defatltTest = 12;
 
 @Component({
 	selector: 'app-root',
@@ -49,7 +50,8 @@ export class AppComponent implements OnInit, OnChanges {
 		console.log('Model', model);
 		console.log('Meta', meta);
 
-		/*
+		console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
+
 		// Test autoMeta
 		const auto = this.dynaform.autoMeta(model);
 		console.log(auto);
@@ -58,6 +60,9 @@ export class AppComponent implements OnInit, OnChanges {
 		const m2 = this.dynaform.combineModelWithMeta(model, meta);
 		console.log(m2);
 
+		console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
+
+		/*
 		// Test building Field-Specific-Meta
 		const fsm = this.dynaform.buildFieldSpecificMeta(m2);
 		console.log(fsm);

+ 9 - 0
src/app/dynaform/models/field.model.ts

@@ -266,6 +266,15 @@ class Container {
 	}
 }
 
+class RepeatingContainer extends Container {
+	minRepeat: number = 1;
+	maxRepeat: number = 5;
+	initialRepeat?: number;
+	showAddControl:  boolean = true;
+	showDeleteControl: boolean = true;
+	meta: StringMap[];
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 // Button Group
 

+ 44 - 11
src/app/dynaform/services/_formdata-utils.ts

@@ -24,16 +24,6 @@ import { FormBuilder, FormGroup, FormArray, FormControl, AbstractControlOptions
 import { reduce, cloneDeep } from 'lodash/fp';
 import * as fmdModels from '../models/field.model';
 
-// REMINDER: Import this directly from @angular/forms when we upgrade to Angular 6
-// While we're still on Angular 5 just declare it
-/*
-interface AbstractControlOptions {
-	validators?: ValidatorFn | ValidatorFn[] | null;
-	asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null;
-	updateOn?: 'change' | 'blur' | 'submit';
-}
-*/
-
 
 // ---------------------------------------------------------------------------------------------------------------------
 // AutoMeta: Generate Automatic Metadata from a model
@@ -61,19 +51,56 @@ const autoMeta = model => Object.entries(model)
 
 
 // ---------------------------------------------------------------------------------------------------------------------
-// Combine automatically generated metadata with overrides
+// Combine automatically generated metadata with overrides (extraMeta)
 // ---------------------------------------------------------------------------------------------------------------------
 
 // containerSeed = Metadata from container which seeds all contained fields
 
+
+
+
+
 const combineMetaForField = (metaF, containerSeed, extraMetaF) => ({ ...metaF, ...containerSeed, ...extraMetaF });
 const combineExtraMeta = (metaG, extraMeta, createFromExtra = false, containerSeed = {}) => {
 	const combinedMeta = {};
 	Object.entries(extraMeta).forEach(([key, val]) => {
 		if (typeof metaG[key] === 'object' || createFromExtra) { // If the key exists (in the model) OR we're creating from metadata
 			const isCon = isContainer(val);
+			const isRepeating = isRepeatingContainer(val);
 			const metaFoG = metaG[key] || {};
 			const seed = isCon ? {} : containerSeed; // Container's don't seed themselves, only their children
+			
+			// ---------------------------------------
+
+			// OK, so we need to... expand repeating containers here
+			if (isRepeating) {
+				const repeatInAutoMeta = Array.isArray(metaG[key].meta) ? metaG[key].meta.length : 0;
+				const repeatInExtraMeta = val['initialRepeat'] || val['minRepeat'];
+				const repeat = Math.max(repeatInAutoMeta, repeatInExtraMeta);
+
+				// Extend array from model (if any) to length repeat, apdding with empty values
+				const repeatingGroup = repeatInAutoMeta ? 
+					[ ...metaG[key].meta, ...Array(repeat - repeatInAutoMeta).fill(metaG[key].meta[0]) ] // RETHING DEFAULT HERE - its first val from data repeated
+					:
+					arrayMemberAutoName(repeat).fill(val['meta'][0]);
+
+				if (Array.isArray(metaG[key])) {
+					combinedMeta[key] = combineExtraMeta(metaG[key], val['meta'][0], createFromExtra, val['seed']);
+				}
+
+
+			}
+
+
+
+
+
+
+
+
+			// ---------------------------------------
+			// Maybe else?
+			
 			const extra = isCon ?
 				{
 					...val,
@@ -424,6 +451,12 @@ const isGroup = (metaFoG): boolean => !!metaFoG.meta;
 // Helper function to distinguish container group (a group of child fields)
 const isContainer = (metaFoG): boolean => isGroup(metaFoG) && (!metaFoG.type || metaFoG.type.toLowerCase() === 'container');
 
+// Is Repeating Container
+// Helper function to distinguish a repeating container group (a group of child fields that can be repeated 1...N times)
+const isRepeatingContainer = (metaFoG): boolean => isContainer(metaFoG)
+	&& Array.isArray(metaFoG.meta)
+	&& !!(metaFoG.minRepeat || metaFoG.maxRepeat || metaFoG.initialRepeat);
+
 // Add Missing Names
 // Helper function to add any missing 'name' properties to Fields and Groups using property's key, recursively
 const addNameIfMissing = (metaFoG, key) => metaFoG.name ? metaFoG : addProp(metaFoG, 'name', key);