Richard Knight 6 gadi atpakaļ
vecāks
revīzija
301205521e

+ 9 - 5
src/app/_mock/testfields.v2.ts

@@ -105,13 +105,17 @@ const dropdownModifiedInput = {
 const checkbuttonGroup = {
 	type: 'CheckbuttonGroup',
 	firstEnablesRest: true,
-	meta: [{name: 'iMaskTheOthers'}, {name: 'groupMemberTwo'}, {name: 'groupMemberThree'}]
+	meta: { iMaskTheOthers: {}, groupMemberTwo: {}, groupMemberThree: {} }
 };
 
-const checkbuttonGroup2 = {
+const checkbuttonGroupArray = {
 	type: 'CheckbuttonGroup',
-	firstEnablesRest: true,
-	meta: [{name: 'One'}, {name: 'Two'}, {name: 'Three'}]
+	firstEnablesRest: false,
+	showAllOrNone: true,
+	meta: [
+		{name: 'One', value: 111}, {name: 'Two', value: 222}, {name: 'Three', value: 333}, {name: 'Four', value: 444},
+		{name: 'Five', value: 555}, {name: 'Six', value: 666}, {name: 'Seven', value: 777}, {name: 'Eight', value: 888}
+	]
 };
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -132,7 +136,7 @@ const container = {
 	type: 'Container',
 	meta: {
 		basicTextField,
-		checkbuttonGroup2,
+		checkbuttonGroupArray,
 	}
 };
 

+ 1 - 1
src/app/_mock/testfields.v7.ts

@@ -13,7 +13,7 @@ const testAsyncValidator = (fc: FormControl): Observable<ValidationErrors> => {
 		console.log('Async validator got', fc.value);
 		return { is42: fc.value === '42' };
 	});
-}
+};
 
 const model = {
 	nonValidatedField: '',

+ 15 - 0
src/app/_mock/testfields.v8.ts

@@ -0,0 +1,15 @@
+// TESTS: FormBuilder FormArray's and CheckButtomGroups (with Select All / Select Non option)
+
+const model = {
+	standardField: '',
+	cbFormArray: ['A', 'B', 'C', 'D', 'E']
+};
+
+// Create a CB array for each member of the model
+// But when to render as a FormArray and when as a FormGroup?
+const meta = {
+	standardField: { type: 'textarea' },
+	cbFormArray: { type: 'CheckbuttonGroup', showAllOrNone: 1 }
+};
+
+export { model, meta };

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

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

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

@@ -9,8 +9,11 @@ import * as test4 from './_mock/testfields.v4';
 import * as test5 from './_mock/testfields.v5';
 import * as test6 from './_mock/testfields.v6';
 import * as test7 from './_mock/testfields.v7';
+import * as test8 from './_mock/testfields.v8';
 
-const testdata = [ test1, test2, test3, test4, test5, test6, test7 ];
+const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8 ];
+
+const defatltTest = 8;
 
 @Component({
 	selector: 'app-root',
@@ -36,13 +39,29 @@ export class AppComponent implements OnInit, OnChanges {
 	ngOnInit() {
 
 		// Optionally supply the test to run in the query string e.g. ?test=3
-		const testcase = parseInt(new URLSearchParams(document.location.search).get('test'), 10) || 2;
+		const testcase = parseInt(new URLSearchParams(document.location.search).get('test'), 10) || defatltTest;
 		const { model, meta } = testdata[testcase - 1];
 
 		console.log('%c *** TEST DATA *** ', this.hCssRed);
 		console.log('Model', model);
 		console.log('Meta', meta);
 
+		// Test autoMeta
+		const auto = this.dynaform.autoMeta(model);
+		console.log(auto);
+
+		// Test combine
+		const m2 = this.dynaform.combineModelWithMeta(model, meta);
+		console.log(m2);
+
+		// Test building Field-Specific-Meta
+		const fsm = this.dynaform.buildFieldSpecificMeta(m2);
+		console.log(fsm);
+
+		// Test building the FormGroup
+		const fg = this.dynaform.buildFormGroup(fsm);
+		console.log(fg);
+
 		// Build the FormGroup and Modeled Metadata from the imported test data
 		const dynaformdata = this.dynaform.build(model, meta);
 		({ form: this.form, meta: this.meta } = dynaformdata);

+ 0 - 2
src/app/app.module.ts

@@ -5,8 +5,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 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 { JsonFormatterDirective } from './directives/json-formatter.directive';
 
 @NgModule({

+ 11 - 0
src/app/dynaform/index.ts.orig

@@ -0,0 +1,11 @@
+<<<<<<< HEAD
+export { DynaformComponent } from './dynaform.component';
+export { DynaformService } from './services/dynaform.service';
+export { ModelMapperService } from './services/model-mapper.service';
+export { standardModifiers, standardTransformer, arrayToMeta } from './utils';
+=======
+export { DynaformService } from './services/dynaform.service';
+export { ModelMapperService } from './services/model-mapper.service';
+export { standardModifiers, standardTransformer } from './utils';
+>>>>>>> a3dfe85e06beb3d977f49241b2360bb3e2f4a09d
+

+ 190 - 0
src/app/dynaform/testdata/testset.1.ts.orig

@@ -0,0 +1,190 @@
+import { Validators } from '@angular/forms';
+import { ValueTransformer } from './../interfaces';
+
+// ---------------------------------------------------------------------------------------------------------------------
+// Native
+
+const basicTextField = {
+	type: 'Text',
+	label: 'Field One',
+	placeholder: 'Type a value here'
+};
+
+const styledTextField = {
+	type: 'Text',
+	placeholder: 'With a DOM id and CSS classes applied',
+	class: ['red', 'bgPaleBlue'],
+	id: 'yoyo'
+};
+
+const textareaField = {
+	type: 'Textarea',
+	placeholder: 'Type your long-winded comments here'
+};
+
+const passwordField = {
+	type: 'Password',
+	placeholder: 'It\'s a secret'
+};
+
+const selectField = {
+	type: 'Select',
+	options: ['', 'Apples', 'Oranges', 'Pears', 'Gorgonzola']
+};
+
+const radioField = {
+	type: 'radio',
+	options: ['Tea', 'Coffee', 'Cocoa', 'Yerba Maté'],
+	validators: [ Validators.required ],
+};
+
+const disabledTextField = {
+	type: 'Text',
+	placeholder: 'You can\'t touch this',
+	isDisabled: true
+};
+
+const radioFieldHorizontal = {
+	type: 'radio',
+	options: ['Fish', 'Fowl', 'Neither'],
+	horizontal: true
+};
+
+
+// ---------------------------------------------------------------------------------------------------------------------
+// Custom
+
+const checkbutton = {
+	type: 'checkbutton',
+	value: '456'
+};
+
+const checkbutton2 = {
+	type: 'checkbutton',
+	value: 'Yowsa'
+};
+
+const modifiers = ['Matches', 'Starts With', 'Contains'];
+const transformerFunctions: ValueTransformer = {
+	inputFn: val => {
+		let modifier = 'Starts With';
+		if (/^%.*?%$/.test(val)) {
+			modifier = 'Contains';
+		} else if (/^[^%].*?[^%]$/.test(val)) {
+			modifier = 'Matches';
+		} else if (/^%.*/.test(val)) {
+			modifier = 'Starts With';
+		}
+		const transformedVal = val.replace(/%/g, '').trim();
+		return { modifier: modifier, value: transformedVal };
+	},
+	outputFn: (mod, val) => {
+		let transformedValue;
+		switch (mod) {
+			case 'Starts With':
+				transformedValue = `%${val}`;
+				break;
+			case 'Contains':
+				transformedValue = `%${val}%`;
+				break;
+			case 'Matches':
+			default:
+				transformedValue = val;
+				break;
+		}
+		return transformedValue;
+	}
+};
+const dropdownModifiedInput = {
+	type: 'dropdownModifiedInput',
+	value: 'lovely',
+	modifiers,
+	transform: transformerFunctions
+};
+
+const checkbuttonGroup = {
+	type: 'CheckbuttonGroup',
+	firstEnablesRest: true,
+<<<<<<< HEAD
+	meta: { iMaskTheOthers: {}, groupMemberTwo: {}, groupMemberThree: {} }
+};
+
+
+
+=======
+	meta: [{name: 'iMaskTheOthers'}, {name: 'groupMemberTwo'}, {name: 'groupMemberThree'}]
+};
+
+
+>>>>>>> a3dfe85e06beb3d977f49241b2360bb3e2f4a09d
+// ---------------------------------------------------------------------------------------------------------------------
+// Kendo
+
+const timepicker = {
+	type: 'timepicker'
+};
+
+const datepicker = {
+	type: 'datepicker'
+};
+
+// ---------------------------------------------------------------------------------------------------------------------
+// Container
+
+const basicTextField2 = {
+	type: 'Text',
+	label: 'Required Field',
+	validators: [ Validators.required, Validators.minLength(4) ],
+};
+
+<<<<<<< HEAD
+const checkbuttonGroupArray = {
+	type: 'CheckbuttonGroup',
+	firstEnablesRest: false,
+	showAllOrNone: true,
+	meta: [
+		{name: 'One', value: 111}, {name: 'Two', value: 222}, {name: 'Three', value: 333}, {name: 'Four', value: 444},
+		{name: 'Five', value: 555}, {name: 'Six', value: 666}, {name: 'Seven', value: 777}, {name: 'Eight', value: 888}
+	]
+=======
+const checkbuttonGroup2 = {
+	type: 'CheckbuttonGroup',
+	firstEnablesRest: true,
+	meta: [{name: 'One'}, {name: 'Two'}, {name: 'Three'}]
+>>>>>>> a3dfe85e06beb3d977f49241b2360bb3e2f4a09d
+};
+
+const container = {
+	type: 'Container',
+	meta: {
+		basicTextField2,
+<<<<<<< HEAD
+		checkbuttonGroupArray
+=======
+		checkbuttonGroup2,
+>>>>>>> a3dfe85e06beb3d977f49241b2360bb3e2f4a09d
+	}
+};
+
+// ---------------------------------------------------------------------------------------------------------------------
+
+const model = {};
+
+const meta = {
+	basicTextField,
+	styledTextField,
+	textareaField,
+	passwordField,
+	selectField,
+	radioField,
+	disabledTextField,
+	radioFieldHorizontal,
+	checkbutton,
+	dropdownModifiedInput,
+	checkbuttonGroup,
+	timepicker,
+	datepicker,
+	container
+};
+
+export { model, meta };

+ 46 - 0
src/app/dynaform/utils.ts.orig

@@ -0,0 +1,46 @@
+// Some standard utility functions for Dyynaform consumers
+
+import { ValueTransformer } from './interfaces';
+
+// Dropdown Modified Input - Starts With / Contains / Matches
+const standardModifiers = ['Starts with', 'Contains', 'Matches'];
+const standardTransformer: ValueTransformer = {
+	inputFn: val => {
+		let modifier = 'Starts with';
+		if (/^%.*?%$/.test(val)) {
+			modifier = 'Contains'
+		} else if (/^[^%].*?[^%]$/.test(val)) {
+			modifier = 'Matches'
+		} else if (/^%.*/.test(val)) {
+			modifier = 'Starts with';
+		}
+		const transformedVal = val.replace(/%/g, '').trim();
+		return { modifier: modifier, value: transformedVal };
+	},
+	outputFn: (mod, val) => {
+		let transformedValue;
+		switch(mod) {
+			case 'Starts with':
+				transformedValue = `%${val}`;
+				break;
+			case 'Contains':
+				transformedValue = `%${val}%`;
+				break;
+			case 'Matches':
+			default:
+				transformedValue = val;
+				break;
+		}
+		return transformedValue;
+	}
+};
+
+<<<<<<< HEAD
+
+// Utility function for casting an array to metadata (useful for components that render FormGroups)
+const arrayToMeta = array => array.map(val => ({ name: val, 'value' : val }));
+
+export { standardModifiers, standardTransformer, arrayToMeta };
+=======
+export { standardModifiers, standardTransformer };
+>>>>>>> a3dfe85e06beb3d977f49241b2360bb3e2f4a09d

+ 8 - 5
src/styles.scss

@@ -9,17 +9,20 @@ h1 {
 	margin-bottom: 1em;
 }
 
+
+.form-group {
+	margin-bottom: 4px;
+}
+
 div.col-sm-8 {
-	border-top: 3px white solid;
-	padding-top: 4px;
+	margin-bottom: 2px;
 }
 
-div.col-sm-4 {
+label.col-sm-4 {
 	background-color: lavenderblush;
-	border-top: 3px white solid;
 	border-left: 15px white solid;
 	padding-top: 4px;
-	margin-bottom: 3px;
+	margin-bottom: 2px;
 }
 
 div.col-sm-8 {