Bläddra i källkod

Can now mutate checkbox groups

Richard Knight 4 år sedan
förälder
incheckning
b7b2dbefe9

+ 0 - 2
src/app/_mock/testfields.v17.ts

@@ -2,8 +2,6 @@
 // TESTS: Modification of Meta
 // ---------------------------------------------------------------------------------------------------------------------
 
-import { Validators as V } from '@angular/forms';
-
 const model = {};
 
 const meta = {

+ 38 - 8
src/app/_mock/testfields.v18.ts

@@ -1,17 +1,47 @@
 // ---------------------------------------------------------------------------------------------------------------------
-// TESTS: Modification of CheckBoxGroups
+// TESTS: Modification of Meta (deeply nested)
 // ---------------------------------------------------------------------------------------------------------------------
 
-import { Validators as V } from '@angular/forms';
-
 const model = {};
 
 const meta = {
-	columns: {
-		source: '/',
-		type: 'checkboxGroup',
-		meta: ['Ab', 'Cd', 'Ef', 'Ghi']
+	fieldOne: {},
+	container: {
+		meta: {
+			subcontainer: {
+				meta: {
+					testField: {
+						type: 'text',
+						placeholder: 'Does it work?'
+					}
+				}
+			}
+		}
 	}
 };
 
-export { model, meta };
+const meta2 = {
+	fieldOne: {
+		placeholder: 'WOO HOO!'
+	},
+	container: {
+		label: 'Container',
+		class: 'bordered',
+		meta: {
+			subcontainer: {
+				label: 'Sub-Container',
+				class: 'bordered',
+				meta: {
+					testField: {
+						type: 'textarea',
+						placeholder: 'YES! IT WORKS! REJOICE!',
+						class: 'multicolor'
+					}
+				}
+			}
+		}
+	}
+}
+
+export { model, meta, meta2 };
+

+ 25 - 0
src/app/_mock/testfields.v19.ts

@@ -0,0 +1,25 @@
+// ---------------------------------------------------------------------------------------------------------------------
+// TESTS: Modification of CheckboxGroup
+// ---------------------------------------------------------------------------------------------------------------------
+
+const model = {};
+
+const meta = {
+	testField: {
+		type: 'checkboxGroup',
+		showAllOrNone: 1,
+		meta: ['Ab', 'Cd', 'Ef', 'Ghi']
+	}
+};
+
+const meta2 = {
+	testField: {
+		type: 'checkboxGroup',
+		// meta: ['Jay', 'Khay', 'LLL', 'Mmmmm', 'Nopqr', 'Sssss...', 'Tea'], // Lengthening meta
+		meta: ['Uuuuu', 'Violet'], // Shortening meta
+		class: 'bordered'
+	}
+}
+
+export { model, meta, meta2 };
+

+ 1 - 1
src/app/app.component.html

@@ -4,7 +4,7 @@
 			<h1>NgDynaform: Clarity Edition</h1>
 			<p>
 			<b>Dynamic Form Layout Module</b><br>
-			Load different tests by appending a query param to the URL <b>?test=N</b> (where N is a number between 1 and 17).<br>
+			Load different tests by appending a query param to the URL <b>?test=N</b> (where N is a number between 1 and 19).<br>
 			NOTE: Model set to update on change, but this can be set to blur or submit for less re-rendering.
 			</p>
 			<br>

+ 9 - 2
src/app/app.component.ts

@@ -1,5 +1,5 @@
 import { Component, OnInit, OnChanges, ViewChild, TemplateRef } from '@angular/core';
-import { FormGroup } from '@angular/forms';
+import { FormGroup, FormArray, FormControl } from '@angular/forms';
 import { DynaformService } from './dynaform';
 
 import * as test1 from './_mock/testfields.v1';
@@ -19,8 +19,10 @@ import * as test14 from './_mock/testfields.v14';
 import * as test15 from './_mock/testfields.v15';
 import * as test16 from './_mock/testfields.v16';
 import * as test17 from './_mock/testfields.v17';
+import * as test18 from './_mock/testfields.v18';
+import * as test19 from './_mock/testfields.v19';
 
-const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13, test14, test15, test16, test17 ];
+const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13, test14, test15, test16, test17, test18, test19 ];
 
 const defatltTest = 1;
 
@@ -121,6 +123,11 @@ export class AppComponent implements OnInit, OnChanges {
 		const dynaformdata = this.dynaform.build({}, newMeta, true);
 		const { form, meta } = dynaformdata;
 		this.meta = meta;
+		// Traverse form adding and removing controls as neccesary
+		// Do it manually first
+		// const testFieldFA = this.form.get('testField') as FormArray;
+		// console.log(testFieldFA);
+		// testFieldFA.push(new FormControl());
 	}
 }
 

+ 24 - 5
src/app/dynaform/components/_abstract/group-input.component.ts

@@ -1,5 +1,7 @@
 import { Input, OnInit } from '@angular/core';
 import { FormGroup, FormArray } from '@angular/forms';
+import {buildFormControl } from './../../services/_formdata-utils';
+
 
 export abstract class GroupInputComponent implements OnInit {
 
@@ -8,11 +10,13 @@ export abstract class GroupInputComponent implements OnInit {
 
 	@Input()
 	set meta(meta: StringMap<any>) {
+		console.log('set meta');
 		this._meta = meta;
 		this.exposeForTemplate();
+		this.updateFormGroupAndMeta();
 	};
 
-	formGroup: FormGroup;
+	formGoA: FormGroup | FormArray;
 	childMetaArray: Array<StringMap<any>>;
 	controlNames: Array<string>;
 
@@ -21,13 +25,28 @@ export abstract class GroupInputComponent implements OnInit {
 	_meta: StringMap<any>
 
 	ngOnInit() {
-		// Get the FormGroup, and information about the controls inside it
-		this.formGroup = this.control as FormGroup;
+		this.updateFormGroupAndMeta();
+	}
+
+	updateFormGroupAndMeta(): void {
+		// Get the FormGroup or FormArray, and information about the controls inside it
+		this.formGoA = this.control as FormGroup | FormArray;
+		if (this.formGoA instanceof FormArray) {
+			const meta = this._meta.meta;
+			const formArrayLength = this.formGoA.length;
+			let delta = meta.length - formArrayLength;
+			while (delta > 0 && delta--) {
+				this.formGoA.push(buildFormControl(meta[formArrayLength + delta]));
+			}
+			if (delta < 0) {
+				this.formGoA.controls.length = meta.length;
+			}
+		}
 		this.childMetaArray = Object.values(this._meta.meta); // Metadata array of all controls in group
-		this.controlNames = Object.keys(this.formGroup.controls);
+		this.controlNames = Object.keys(this.formGoA.controls);
 	}
 
-	exposeForTemplate() {
+	exposeForTemplate(): void {
 		// Move meta variables up a level, for direct access in templates
 		this.exposeMetaInTemplate.map(p => this[p] = this._meta[p] !== undefined ? this._meta[p] : this[p]);
 	}

+ 1 - 1
src/app/dynaform/components/group/checkbox-group/clr-checkbox-group.component.html

@@ -1,5 +1,5 @@
 <div class="aba-checkbutton-group">
-	<app-checkbox *ngFor="let control of formGroup.controls; let i = index"
+	<app-checkbox *ngFor="let control of formGoA.controls; let i = index"
 		[control]="control"
 		[meta]="childMetaArray[i]"
 	>

+ 3 - 3
src/app/dynaform/components/group/checkbox-group/clr-checkbox-group.component.ts

@@ -31,7 +31,7 @@ export class ClrCheckboxGroupComponent extends GroupInputComponent implements On
 			this.showAllOrNone = this._meta.showAllOrNone;
 		}
 		if (this.firstEnablesRest) {
-			this.firstControl = this.formGroup.controls[this.controlNames[0]] as FormControl;
+			this.firstControl = this.formGoA.controls[this.controlNames[0]] as FormControl;
 			this.childMetaArray[0].disabled = false;
 			this.childMetaArray.slice(1).map(meta => { meta.disabled = !this.firstControl.value; return meta; });
 
@@ -50,13 +50,13 @@ export class ClrCheckboxGroupComponent extends GroupInputComponent implements On
 	}
 
 	selectAll(e: MouseEvent): false {
-		this.controlNames.forEach(c => this.formGroup.get(c).setValue(this._meta.meta[c].value));
+		this.controlNames.forEach(c => this.formGoA.get(c).setValue(this._meta.meta[c].value));
 		(e.target as HTMLLinkElement).blur();
 		return false;
 	}
 
 	selectNone(e: MouseEvent): false {
-		this.controlNames.forEach(c => this.formGroup.get(c).setValue(null));
+		this.controlNames.forEach(c => this.formGoA.get(c).setValue(null));
 		(e.target as HTMLLinkElement).blur();
 		return false;
 	}

+ 3 - 3
src/app/dynaform/components/group/checkbutton-group/checkbutton-group.component.ts

@@ -31,7 +31,7 @@ export class CheckbuttonGroupComponent extends GroupInputComponent implements On
 			this.showAllOrNone = this._meta.showAllOrNone;
 		}
 		if (this.firstEnablesRest) {
-			this.firstControl = this.formGroup.controls[this.controlNames[0]] as FormControl;
+			this.firstControl = this.formGoA.controls[this.controlNames[0]] as FormControl;
 			this.childMetaArray[0].disabled = false;
 			this.childMetaArray.slice(1).map(meta => { meta.disabled = !this.firstControl.value; return meta; });
 
@@ -50,13 +50,13 @@ export class CheckbuttonGroupComponent extends GroupInputComponent implements On
 	}
 
 	selectAll(e: MouseEvent): false {
-		this.controlNames.forEach(c => this.formGroup.get(c).setValue(this._meta.meta[c].value));
+		this.controlNames.forEach(c => this.formGoA.get(c).setValue(this._meta.meta[c].value));
 		(e.target as HTMLLinkElement).blur();
 		return false;
 	}
 
 	selectNone(e: MouseEvent): false {
-		this.controlNames.forEach(c => this.formGroup.get(c).setValue(null));
+		this.controlNames.forEach(c => this.formGoA.get(c).setValue(null));
 		(e.target as HTMLLinkElement).blur();
 		return false;
 	}

+ 5 - 8
src/app/dynaform/directives/dynafield.directive.ts

@@ -169,15 +169,16 @@ export class DynafieldDirective extends NgControl implements OnInit, OnChanges,
 					this.control.reset({ value: this.control.value, disabled: true });
 				}
 
-				// TODO: Change Update Strategy if necessary
-
+				// TODO: Change Update Strategy if necessary (e.g. when going from text to select)
 				instance.control = control;
-				instance.meta = meta;
+				// instance.meta = meta; // Done below...
+
+				// CHANGE AFTER CHECKED PROBLEM IF VALUE IS ALREADY SET
 			}
 
 			this.setCssId(cssId);
 			this.setCssClasses(type, cssClass);
-			this.component.instance.meta = meta;
+			this.component.instance.meta = meta; // NOTE: Setting an imput like this does *NOT* trigger ngOnChanges
 		}
 	}
 
@@ -190,10 +191,6 @@ export class DynafieldDirective extends NgControl implements OnInit, OnChanges,
 		}
 	}
 
-	insertComponent() {
-		
-	}
-
 	// ---------------------------------------
 	// Override methods / getters in NgControl
 

+ 0 - 1
src/app/dynaform/dynaform.component.ts

@@ -78,7 +78,6 @@ export class DynaformComponent implements OnInit, OnChanges {
 	ngOnChanges() {
 		// Triggered when inputs change
 		console.log('%c *** DynaformChange *** ', this.conOlive);
-		console.log(this.formMetaData);
 		// Get the formGroup from the formGroupName if necessary
 		if (!this.formGroup && this.formGroupName) {
 			this.formGroup = this.cc.control as FormGroup; // Get theFormGroup from the injected ControlContainer

+ 11 - 1
src/styles.scss

@@ -77,7 +77,7 @@ div.clr-col-sm-8 {
 }
 
 .multicolor {
-	input, select {
+	input, select, textarea {
 		border-width: 1px;
 		border-style: solid;
 		border-top-color: green;
@@ -90,6 +90,16 @@ div.clr-col-sm-8 {
 	}
 }
 
+.bordered {
+	border-width: 5px;
+	border-style: solid;
+	border-top-color: green;
+	border-left-color: blueviolet;
+	border-right-color: teal;
+	border-bottom-color: magenta;
+	padding: 2em;
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 // FormGroup Heading Styles