Bläddra i källkod

Fixing a few issues with Repeating Fields

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

+ 37 - 0
src/app/_mock/testfields.v16.ts

@@ -0,0 +1,37 @@
+// ---------------------------------------------------------------------------------------------------------------------
+// TESTS: Repeating Single Fields (i.e. fields not part of a repeating container group)
+// ---------------------------------------------------------------------------------------------------------------------
+
+import { Validators as V } from '@angular/forms';
+
+const model = {};
+
+const meta = {
+	email: {
+		label: 'Email Configuration',
+		source: '/',
+		meta: {
+			emailTo: { label: 'To', validators: [ V.required, V.email ] },
+			emailCc: { 
+				minRepeat: 1,
+				maxRepeat: 5,
+				initialRepeat: 1,
+				showAddControl: true,
+				showDeleteControl: true,
+				validators: V.email
+			},
+			emailBcc: { 
+				minRepeat: 1,
+				maxRepeat: 5,
+				initialRepeat: 1,
+				showAddControl: true,
+				showDeleteControl: true,
+				validators: V.email
+			},
+			subject: { validators: V.required },
+			message: { type: 'textarea' }
+		}
+	}
+};
+
+export { model, meta };

+ 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 15).<br>
+			Load different tests by appending a query param to the URL <b>?test=N</b> (where N is a number between 1 and 16).<br>
 			NOTE: Model set to update on change, but this can be set to blur or submit for less re-rendering.
 			</p>
 			<br>

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

@@ -17,8 +17,9 @@ import * as test12 from './_mock/testfields.v12';
 import * as test13 from './_mock/testfields.v13';
 import * as test14 from './_mock/testfields.v14';
 import * as test15 from './_mock/testfields.v15';
+import * as test16 from './_mock/testfields.v16';
 
-const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13, test14, test15 ];
+const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13, test14, test15, test16 ];
 
 const defatltTest = 1;
 

+ 51 - 53
src/app/dynaform/dynaform.component.html

@@ -15,75 +15,73 @@
 		</ng-container>
 
 		<ng-template #recursiveDynaform>
-
-			<div *ngIf="isRepeatingField(meta)" class="dyna-rf-container">
-				<div *ngFor="let field of meta.meta; let i = index" class="dyna-rc-container">
-					<button *ngIf="meta.showDeleteControl"
-						class="btn btn-sm btn-icon btn-outline-danger dyna-rc-btn-delete"
-						[disabled]="!deleteAllowed(meta.name)"
-						(click)="deleteRepeatingMember(meta.name, i)">
-						<clr-icon shape="trash"></clr-icon>
-					</button>
-					<ng-container *ngTemplateOutlet="dynafield; context: getRepeatingTemplateContext(meta.name, i)"></ng-container>
-				</div>
-				<div *ngIf="meta.showAddControl" class="clr-row">
-					<div class="clr-col-sm-12">
+			<ng-container [ngSwitch]="meta.type">
+
+				<div *ngSwitchCase="'RepeatingField'" class="dyna-rf-container">
+					<div *ngFor="let field of meta.meta; let i = index" class="dyna-rf-field">
+						<button *ngIf="meta.showDeleteControl"
+							class="btn btn-sm btn-icon btn-outline-danger dyna-rep-btn-delete"
+							[disabled]="!deleteAllowed(meta.name)"
+							(click)="deleteRepeatingMember(meta.name, i)">
+							<clr-icon shape="trash"></clr-icon>
+						</button>
+						<ng-container *ngTemplateOutlet="dynafield; context: getRepeatingTemplateContext(meta.name, i)"></ng-container>
+					</div>
+					<div *ngIf="meta.showAddControl">
 						<button
-							class="btn btn-sm btn-success dyna-rc-btn-add"
+							class="btn btn-sm btn-icon btn-outline-success dyna-rep-btn-add"
 							[disabled]="!addAllowed(meta.name)"
 							(click)="addRepeatingFieldMember(meta.name)">
-							<clr-icon shape="plus-circle" class="is-solid"></clr-icon> Add Another
+							<clr-icon shape="plus"></clr-icon>
 						</button>
 					</div>
 				</div>
-			</div>
-
-			<ng-container *ngIf="isRepeatingContainer(meta); else container">
-				<div *ngIf="meta.display === 'SINGLE'" class="clr-row dyna-rc-selector">
-					<div class="clr-col-sm-2 text-right dyna-rc-focus-block">
-						<b>FOCUS &gt;</b>
+	
+				<ng-container *ngSwitchCase="'RepeatingContainer'">
+					<div *ngIf="meta.display === 'SINGLE'" class="clr-row dyna-rc-selector">
+						<div class="clr-col-sm-2 text-right dyna-rc-focus-block">
+							<b>FOCUS &gt;</b>
+						</div>
+						<div class="clr-col-sm-10">
+							<button *ngFor="let container of meta.meta; let i = index"
+								class="btn btn-sm dyna-rc-btn-focus"
+								[ngClass]="container.focussed ? 'btn-primary' : ''"
+								(click)="focusContainer(meta.name, i)">
+								{{ getRepeatingContainerLabel(meta.name, i) }}
+							</button>
+							<button *ngIf="meta.showAddControl"
+								class="btn btn-sm btn-icon btn-outline-success dyna-rep-btn-add"
+								[disabled]="!addAllowed(meta.name)"
+								(click)="addRepeatingContainerMember(meta.name)">
+								<clr-icon shape="plus"></clr-icon>
+							</button>
+						</div>
 					</div>
-					<div class="clr-col-sm-10">
-						<button *ngFor="let container of meta.meta; let i = index"
-							class="btn btn-sm dyna-rc-btn-focus"
-							[ngClass]="container.focussed ? 'btn-primary' : ''"
-							(click)="focusContainer(meta.name, i)">
-							{{ getRepeatingContainerLabel(meta.name, i) }}
-						</button>
-						<button *ngIf="meta.showAddControl"
-							class="btn btn-sm btn-success dyna-rc-btn-add"
-							[disabled]="!addAllowed(meta.name)"
-							(click)="addRepeatingContainerMember(meta.name)">
-							<clr-icon shape="plus-circle" class="is-solid"></clr-icon> Add New
+					<div *ngFor="let container of meta.meta; let i = index" class="dyna-rc-container" [ngClass]="{ 'dyna-rc-display-all': meta.display === 'ALL' }">
+						<button *ngIf="meta.showDeleteControl"
+							class="btn btn-sm btn-icon btn-outline-danger dyna-rep-btn-delete"
+							[ngClass]="{ 'dyna-hidden': !meta.meta[i].focussed }"
+							[disabled]="!deleteAllowed(meta.name)"
+							(click)="deleteRepeatingMember(meta.name, i)">
+							<clr-icon shape="trash"></clr-icon>
 						</button>
+						<ng-container *ngTemplateOutlet="dynaform; context: getRepeatingTemplateContext(meta.name, i)"></ng-container>
 					</div>
-				</div>
-				<div *ngFor="let container of meta.meta; let i = index" class="dyna-rc-container" [ngClass]="{ 'dyna-rc-display-all': meta.display === 'ALL' }">
-					<button *ngIf="meta.showDeleteControl"
-						class="btn btn-sm btn-icon btn-outline-danger dyna-rc-btn-delete"
-						[ngClass]="{ 'dyna-hidden': !meta.meta[i].focussed }"
-						[disabled]="!deleteAllowed(meta.name)"
-						(click)="deleteRepeatingMember(meta.name, i)">
-						<clr-icon shape="trash"></clr-icon>
-					</button>
-					<ng-container *ngTemplateOutlet="dynaform; context: getRepeatingTemplateContext(meta.name, i)"></ng-container>
-				</div>
-				<div *ngIf="meta.showAddControl && meta.display === 'ALL'" class="clr-row">
-					<div class="clr-col-sm-12">
+					<div *ngIf="meta.showAddControl && meta.display === 'ALL'">
 						<button
-							class="btn btn-sm btn-success dyna-rc-btn-add"
+							class="btn btn-sm btn-icon btn-outline-success dyna-rep-btn-add"
 							[disabled]="!addAllowed(meta.name)"
 							(click)="addRepeatingContainerMember(meta.name)">
-							<clr-icon shape="plus-circle" class="is-solid"></clr-icon> Add Another
+							<clr-icon shape="plus"></clr-icon>
 						</button>
 					</div>
-				</div>
-			</ng-container>
+				</ng-container>
 
-		</ng-template>
+				<ng-container *ngSwitchCase="'Container'">
+					<ng-container *ngTemplateOutlet="dynaform; context: { control: control, meta: meta }"></ng-container>
+				</ng-container>
 
-		<ng-template #container>
-			<ng-container *ngTemplateOutlet="dynaform; context: { control: control, meta: meta }"></ng-container>
+			</ng-container>
 		</ng-template>
 
 		<ng-template #fullWidth>

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

@@ -136,14 +136,6 @@ export class DynaformComponent implements OnInit, OnChanges {
 		return !meta.type.includes('Container') && meta.type !== 'RepeatingField';
 	}
 
-	isRepeatingField(meta: StringMap<any>): boolean {
-		return meta.type === 'RepeatingField';
-	}
-
-	isRepeatingContainer(meta: StringMap<any>): boolean {
-		return meta.type === 'RepeatingContainer';
-	}
-
 	getTemplateContext(controlName: string): DynarowContext {
 		return {
 			control: this.formGroup.get(controlName),

+ 1 - 1
src/app/dynaform/services/_formdata-utils.ts

@@ -729,7 +729,7 @@ const isRepeatingField = (metaRF): boolean => metaRF.type && metaRF.type.toLower
 			!hasMeta(metaRF)  	|| hasMeta (metaRF)
 								&& Array.isArray(metaRF.meta)
 								&& metaRF.meta[0]
-								&& isScalar(Object.values(metaRF.meta[0])[0])
+								&& isScalar(Object.values(metaRF.meta[0]).filter(p => typeof p !== 'function')[0])
 		)  
 	);
 

+ 30 - 2
src/styles.scss

@@ -187,7 +187,28 @@ input, textarea, select {
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
-// Repeating Comtainers (series of buttons alowwing user to focus a repeating container member)
+// Repeating Fields
+
+// dyna-rf = Dynaform Repeating Field
+
+.dyna-rf-container {
+	// outline: 1px lime solid;
+	label {
+		display: none;
+	}
+	> div:first-of-type {
+		label {
+			display: block;
+		}
+	}
+}
+
+// .dyna-rf-field {
+// 	outline: 1px pink solid;
+// }
+
+// ---------------------------------------------------------------------------------------------------------------------
+// Repeating Containers (series of buttons alowwing user to focus a repeating container member)
 
 // dyna-rc = Dynaform Repeating Container
 
@@ -211,9 +232,16 @@ input, textarea, select {
 		}
 	}
 }
+// ---------------------------------------------------------------------------------------------------------------------
+// Repeating Field and Container Buttons
+
+.dyna-rep-btn-add {
+	margin-left: 0;
+}
 
-.dyna-rc-btn-delete {
+.dyna-rep-btn-delete {
 	float: right;
+	margin-top: 0;
 	margin-right: 0;
 }