Forráskód Böngészése

Attaching FormGroup components now working

Richard Knight 6 éve
szülő
commit
9fa70b81b9

+ 11 - 10
src/app/_mock/testfields.ts

@@ -98,6 +98,7 @@ const dropDownModifiedInput = new fmd.DropdownModifiedInputField({
 
 const checkbuttonGroup = new fmd.CheckbuttonGroup({
 	name: 'checkbuttonGroup',
+	firstEnablesRest: true,
 	meta: [{name: 'iMaskTheOthers'}, {name: 'groupMemberTwo'}, {name: 'groupMemberThree'}]
 });
 
@@ -119,16 +120,16 @@ const checkbuttonGroupSA = new fmd.CheckbuttonGroup({
 // ---------------------------------------------------------------------------------------------------------------------
 
 export const formMetaDataObj = {
-	// basicTextField,
-	// styledTextField,
-	// textareaField,
-	// passwordField,
-	// selectField,
-	// radioField,
-	// disabledTextField,
-	// radioFieldHorizontal,
-	// checkbutton,
-	// dropDownModifiedInput,
+	basicTextField,
+	styledTextField,
+	textareaField,
+	passwordField,
+	selectField,
+	radioField,
+	disabledTextField,
+	radioFieldHorizontal,
+	checkbutton,
+	dropDownModifiedInput,
 	checkbuttonGroup
 };
 

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

@@ -8,13 +8,13 @@
 				</p>
 			</div>
 		</div>
-		<!-- <app-dynaform formGroupName="dynaformtest" [meta]="formMetaDataObj" [template]="tref"></app-dynaform> -->
-		<div class="row">
+		<app-dynaform formGroupName="dynaformtest" [meta]="formMetaDataObj" [template]="tref"></app-dynaform>
+		<!-- <div class="row">
 			<div class="col-12 pt-4 pb-4" formGroupName="standAlone">
-				<!-- <app-checkbutton [formControl]="tempctl" [meta]="standAlone.checkbuttonSA"></app-checkbutton> -->
+				<app-checkbutton [formControl]="tempctl" [meta]="standAlone.checkbuttonSA"></app-checkbutton>
 				<app-checkbutton-group formGroupName="checkbuttonGroupSA" [control]="tempgrp" [meta]="standAlone.checkbuttonGroupSA" firstEnablesRest></app-checkbutton-group>
 			</div>
-		</div>
+		</div> -->
 		<div calss="row">
 			<div class="col-12 pt-4 pb-4">
 				<json-formatter [data]="form.value" open="3"></json-formatter>

+ 4 - 6
src/app/app.component.ts

@@ -19,8 +19,8 @@ export class AppComponent implements OnInit {
 	@ViewChild('testTemplate', { read: TemplateRef })
 	private tref: TemplateRef<any>;
 
-	tempctl;
-	tempgrp;
+	// tempctl;
+	// tempgrp;
 
 	constructor(
 		protected fb: FormBuilder
@@ -33,10 +33,8 @@ export class AppComponent implements OnInit {
 		};
 		this.form = buildFormGroup(fullFormMeta);
 		this.form.addControl('standAlone', buildFormGroup(standAlone));
-		this.tempctl = (<FormGroup>this.form.controls.standAlone).controls.checkbuttonSA;
-		this.tempgrp = (<FormGroup>this.form.controls.standAlone).controls.checkbuttonGroupSA;
-		console.log(standAlone);
-		console.log(this.tempgrp);
+		// this.tempctl = (<FormGroup>this.form.controls.standAlone).controls.checkbuttonSA;
+		// this.tempgrp = (<FormGroup>this.form.controls.standAlone).controls.checkbuttonGroupSA;
 	}
 }
 

+ 4 - 6
src/app/app.module.ts

@@ -1,11 +1,11 @@
 import { BrowserModule } from '@angular/platform-browser';
 import { NgModule } from '@angular/core';
 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
-// import { DynaformModule } from './dynaform/dynaform.module';
+import { DynaformModule } from './dynaform/dynaform.module';
 import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
 import { AppComponent } from './app.component';
-import { CheckbuttonGroupComponent } from './dynaform/components/group/checkbutton-group/checkbutton-group.component';
-import { CheckbuttonComponent } from './dynaform/components/custom/checkbutton/checkbutton.component';
+// import { CheckbuttonGroupComponent } from './dynaform/components/group/checkbutton-group/checkbutton-group.component';
+// import { CheckbuttonComponent } from './dynaform/components/custom/checkbutton/checkbutton.component';
 import { JsonFormatterDirective } from './directives/json-formatter.directive';
 
 @NgModule({
@@ -13,13 +13,11 @@ import { JsonFormatterDirective } from './directives/json-formatter.directive';
 		BrowserModule,
 		FormsModule,
 		ReactiveFormsModule,
-		// DynaformModule,
+		DynaformModule,
 		NgbModule.forRoot()
 	],
 	declarations: [
 		AppComponent,
-		CheckbuttonGroupComponent,
-		CheckbuttonComponent,
 		JsonFormatterDirective
 	],
 	providers: [],

+ 26 - 0
src/app/dynaform/components/_abstract/group-input.component.ts

@@ -0,0 +1,26 @@
+import { Input, OnInit } from '@angular/core';
+import { FormGroup } from '@angular/forms';
+
+export abstract class GroupInputComponent implements OnInit {
+
+	@Input()
+	control: FormGroup;
+
+	@Input()
+	meta;
+
+	formGroup: FormGroup;
+	childMeta: Array<StringMap>;
+	controlNames: Array<string>;
+
+	exposeMetaInTemplate: string[] = [];
+
+	ngOnInit() {
+		// 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]);
+		this.formGroup = this.control as FormGroup;
+		this.childMeta = Object.values(this.meta.meta); // Metadata array of all controls in group
+		this.controlNames = Object.keys(this.formGroup.controls);
+	}
+
+}

+ 1 - 5
src/app/dynaform/components/custom/checkbutton/checkbutton.component.ts

@@ -1,4 +1,4 @@
-import { Component, forwardRef, OnChanges, Input } from '@angular/core';
+import { Component, forwardRef, OnChanges } from '@angular/core';
 import { NG_VALUE_ACCESSOR } from '@angular/forms';
 import { CustomInputComponent } from './../../_abstract/custom-input.component';
 
@@ -16,9 +16,6 @@ import { CustomInputComponent } from './../../_abstract/custom-input.component';
 })
 export class CheckbuttonComponent extends CustomInputComponent implements OnChanges {
 	
-	@Input()
-	test;
-	
 	exposeMetaInTemplate: string[] = ['label', 'value', 'isDisabled'];
 
 	isChecked: boolean;
@@ -27,7 +24,6 @@ export class CheckbuttonComponent extends CustomInputComponent implements OnChan
 	currentValue: string | boolean;
 
 	ngOnChanges() {
-		console.log('HERE');
 		this.isDisabled = this.meta.isDisabled;
 	}
 

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

@@ -1,4 +1,4 @@
-<div class="lmp-checkbutton-group btn-group btn-group-toggle" [formGroup]="cc.control">
+<div class="lmp-checkbutton-group btn-group btn-group-toggle" [formGroup]="formGroup">
 	<app-checkbutton *ngFor="let groupMember of controlNames; let i = index"
 		[formControlName]="groupMember"
 		[meta]="childMeta[i]"

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

@@ -1,43 +1,28 @@
-import { Component, Attribute, OnInit, Input } from '@angular/core';
-import { ControlContainer, FormGroup, FormControl } from '@angular/forms';
-import { CustomInputComponent } from './../../_abstract/custom-input.component';
+import { Component, Attribute, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
+import { GroupInputComponent } from './../../_abstract/group-input.component';
 
 @Component({
 	selector: 'app-checkbutton-group',
 	templateUrl: './checkbutton-group.component.html',
 	styleUrls: ['./checkbutton-group.component.scss']
 })
-export class CheckbuttonGroupComponent /* extends CustomInputComponent */ implements OnInit {
+export class CheckbuttonGroupComponent extends GroupInputComponent implements OnInit {
 
-	@Input()
-	control: FormGroup;
-
-	@Input()
-	meta;
-
-	formGroup: FormGroup;
 	firstControl: FormControl;
-	childMeta: Array<StringMap>;
-	controlNames: Array<string>;
 
 	constructor(
-		private cc: ControlContainer,
 		@Attribute('firstEnablesRest') private firstEnablesRest
 	) {
-		// super();
+		super();
 		this.firstEnablesRest = firstEnablesRest === ''; // True if 'firstEnablesRest' exists as component attribute
-		console.log('firstEnablesRest', this.firstEnablesRest);
 	}
 
 	ngOnInit() {
-		console.log('************************');
-		this.formGroup = this.control as FormGroup;
-		// this.formGroup = this.cc.control as FormGroup;
-		this.childMeta = Object.values(this.meta.meta); // Metadata array or all controls in group
-		console.log(Array.isArray(this.childMeta));
-		this.controlNames = Object.keys(this.formGroup.controls);
-		// this.controlNames = Object.keys(this.cc.control.value);
-		console.log(this.controlNames);
+		super.ngOnInit();
+		if (this.meta.firstEnablesRest) {
+			this.firstEnablesRest = this.meta.firstEnablesRest;
+		}
 		if (this.firstEnablesRest) {
 			this.firstControl = this.formGroup.controls[this.controlNames[0]] as FormControl;
 			this.childMeta[0].isDisabled = false;
@@ -46,7 +31,8 @@ export class CheckbuttonGroupComponent /* extends CustomInputComponent */ implem
 			// Observe value changes on first control
 			this.firstControl.valueChanges.subscribe(val => {
 				for (var i = 1; i < this.childMeta.length; i++) {
-					// NOTE: We rassign input to trigger change detection
+					// NOTE: We rassign the input (array member) to trigger change detection (otherwise it doesn't run)
+					// See https://juristr.com/blog/2016/04/angular2-change-detection/
 					this.childMeta[i] = { 
 						...this.childMeta[1],
 						isDisabled: !val

+ 2 - 24
src/app/dynaform/directives/dynafield.directive.ts

@@ -2,7 +2,7 @@ import {
 	Directive, ComponentFactoryResolver, ComponentRef, ViewContainerRef,
 	Input, Output, EventEmitter, OnInit, SkipSelf
 } from '@angular/core';
-import { Form, FormControl, ControlContainer, NgControl, ControlValueAccessor, ValidatorFn, AsyncValidatorFn, FormGroupName } from '@angular/forms';
+import { Form, FormControl, ControlContainer, NgControl, ControlValueAccessor, ValidatorFn, AsyncValidatorFn } from '@angular/forms';
 
 import * as formFieldComponents from './../components';
 
@@ -17,7 +17,7 @@ type FFCCustom = FFC & ControlValueAccessor;
 	// tslint:disable-next-line:directive-selector
 	selector: '[dynafield]'
 })
-export class DynafieldDirective extends NgControl implements OnInit /* OnChanges */ {
+export class DynafieldDirective extends NgControl implements OnInit {
 
 	@Input()
 	meta: StringMap;
@@ -56,7 +56,6 @@ export class DynafieldDirective extends NgControl implements OnInit /* OnChanges
 			);
 		}
 		try {
-			
 			const { name, class: cssClass, id: cssId, isDisabled } = this.meta;
 
 			// Create the component
@@ -89,33 +88,12 @@ export class DynafieldDirective extends NgControl implements OnInit /* OnChanges
 				this.valueAccessor = <FFCCustom>this.component.instance;
 				this._control = this.formDirective.addControl(this);
 			}
-
-			// Connect custom groups
-			if (this.meta.meta) {
-				console.log('GROUP');
-				// this.name = name;
-				console.log(this.formDirective);
-				const whagga = new FormGroupName(this.cc, [], []);
-				whagga.name = 'checkbuttonGroup';
-				this.formDirective.addFormGroup(whagga);
-				console.log(this.formDirective);
-			}
-
 		} catch (e) {
 			console.error('ERROR INSTANTIATING DYNAFORM FIELD COMPONENT');
 			console.log(e);
 		}
 	}
 
-	/*
-	ngOnChanges() {
-		if (this.component) {
-			this.component.instance.meta = this.meta;
-			this.component.instance.control = this.control;
-		}
-	}
-	*/
-
 	get path(): string[] {
 		return [...this.cc.path, this.name];
 	}

+ 2 - 2
src/app/dynaform/libs/index.ts

@@ -21,7 +21,7 @@ const fb = new FormBuilder();
 const addProp = (obj, key, val) => { obj[key] = val; return obj; };
 
 // Helper function to distinguish group from field
-const isGroup = metaFoG => metaFoG.meta && !metaFoG._field;
+const isGroup = metaFoG => metaFoG.meta;
 
 // Adds any missing 'name' properties to Fields and Groups using property's key, recursively
 const addNameIfMissing = (metaFoG, key) => metaFoG.name ? metaFoG : addProp(metaFoG, 'name', key);
@@ -38,7 +38,7 @@ const addMissingNames = metaG => Object.entries(metaG)
 
 // Build Form Control
 // TODO: Flesh out function to build validators
-const buildControlState = metaF => ({ value: metaF.value || '', disabled: metaF.isDisabled });
+const buildControlState = metaF => ({ value: metaF.value || metaF.default, disabled: metaF.isDisabled });
 const buildValidators = metaF => ({
 	validators: null,
 	asyncValidators: null,

+ 3 - 1
src/app/dynaform/models/index.ts

@@ -13,6 +13,7 @@ interface SimpleFieldMetaData {
 	type?: string; 								// The component type e.g. BasicInput, Checkbutton, Timepicker, etc
 	label?: string;								// The field label - defaults to unCamelCased name if not supplied
 	value?: any;								// The field value - defaults to empty string if not supplied
+	deafult?: any;								// Default value
 	placeholder?: string;						// Optional placeholder text
 	class?: string | Array<string>;				// CSS classes to apply
 	id?: string;								// CSS id to apply
@@ -51,6 +52,7 @@ class SimpleField {
 	origin?: string;
 	label?: string;
 	value;
+	default = '';
 	placeholder = '';
 	class?: string | Array<string>;
 	id?: string;
@@ -58,7 +60,6 @@ class SimpleField {
 	validators: Array<ValidatorFn> = [];
 	asyncValidators: Array<AsyncValidatorFn> = [];
 	valFailureMsgs: StringMap = {};
-	_field = true;
 
 	constructor(meta: SimpleFieldMetaData) {
 		Object.assign(this, meta);
@@ -126,6 +127,7 @@ class RadioField extends OptionsField {
 
 class CheckbuttonField extends SimpleField {
 	type = 'Checkbutton';
+	default: any = false;
 }
 
 class DropdownModifiedInputField extends SimpleField {