瀏覽代碼

Deleting RC members now working - presentation needs a little work

Richard Knight 6 年之前
父節點
當前提交
78d5efa14a

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

@@ -0,0 +1,37 @@
+// TESTS: Repeating Groups Of Fields ( 1 -> N arrays of containers for multiple fields )
+
+const model = {
+	repeating: [
+		{
+			a: 1,
+			b: 2,
+		},
+		{
+			a: 3,
+			b: 4,
+		}
+	],
+	standard: 'YABBA DABBA DOOOOOO'
+};
+
+const meta = {
+	repeating: {
+		label: 'Repeating Group',
+		seed: { class: 'short-field' },
+		minRepeat: 1,
+		maxRepeat: 5,
+		initialRepeat: 3,
+		showAddControl: true,
+		showDeleteControl: true,
+		display: 'ALL', // ALL or SINGLE,
+		primaryField: 'a',
+		meta: [
+			{
+				a: { label: 'Field A' },
+				b: { label: 'Field B', type: 'select', options: [1, 2, 3, 4, 5] }
+			}
+		]
+	}
+};
+
+export { model, meta };

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

@@ -14,10 +14,11 @@ 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';
+import * as test13 from './_mock/testfields.v13';
 
-const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12 ];
+const testdata = [ test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12, test13 ];
 
-const defatltTest = 1;
+const defatltTest = 13;
 
 @Component({
 	selector: 'app-root',

+ 6 - 2
src/app/dynaform/dynaform.component.html

@@ -41,17 +41,21 @@
 						</a>
 						<a *ngIf="meta.showAddControl"
 							class="btn btn-sm btn-outline-success"
+							[ngClass]="{ 'btn-disabled': !addRCMemberAllowed(meta.name) }"
 							(click)="addRCMember(meta.name)">
 							+ Add New
 						</a>
 					</div>
 				</div>
 				<div *ngFor="let container of meta.meta; let i = index" class="dyna-rc-container" [ngClass]="{ 'dyna-rc-display-all': meta.display === 'ALL' }">
+					<div *ngIf="meta.showDeleteControl" class="text-right">
+						<a [ngClass]="{ 'btn-disabled': !deleteRCMemberAllowed(meta.name) }" (click)="deleteRCMember(meta.name, i)"><i class="fa fa-trash"></i></a>
+					</div>
 					<ng-container *ngTemplateOutlet="dynaform; context: getRCTemplateContext(meta.name, i)"></ng-container>
 				</div>
 				<div *ngIf="meta.showAddControl && meta.display === 'ALL'" class="row">
-					<div class="col-sm-12">
-						<a class="btn btn-sm btn-outline-success" (click)="addRCMember(meta.name)">
+					<div class="col-sm-12 text-right">
+						<a class="btn btn-sm btn-outline-success" [ngClass]="{ 'btn-disabled': !addRCMemberAllowed(meta.name) }" (click)="addRCMember(meta.name)">
 							+ Add New
 						</a>
 					</div>

+ 29 - 4
src/app/dynaform/dynaform.component.ts

@@ -3,6 +3,7 @@ import { FormBuilder, FormControl, FormGroup, FormArray, FormGroupName, Abstract
 import { SuperForm } from 'angular-super-validator';
 import { buildFormGroupFunctionFactory } from './services/_formdata-utils';
 import { cloneDeep } from 'lodash/fp';
+import { unwrapResolvedMetadata } from '@angular/compiler';
 
 export interface DynarowContext {
 	control: AbstractControl;
@@ -181,23 +182,47 @@ export class DynaformComponent implements OnInit {
 		
 	}
 
+	addRCMemberAllowed(repeatingContainerName: string): boolean {
+		const rcMeta = this.formMetaData[repeatingContainerName];
+		return typeof rcMeta.maxRepeat === 'number' && rcMeta.maxRepeat > rcMeta.meta.length;
+	}
+
 	// Maybe move the next two funtions to _formdata-utils.ts ?
 	addRCMember(repeatingContainerName: string): void {
-		// (1) Add metadata for new container member
+		// (1) Check that we vcan still add controls
+		if (!this.addRCMemberAllowed(repeatingContainerName)) {
+			return;
+		}
+		// (2) Add metadata for new container member
 		const rcMeta = this.formMetaData[repeatingContainerName];
 		const containerTemplate = cloneDeep(rcMeta.__containerTemplate);
 		const i = this.formMetaData[repeatingContainerName].meta.length;
 		containerTemplate.name = `group${i+1}`;
 		rcMeta.meta.push(containerTemplate);
-
-		// (2) Add FormGroup for new container member
+		// (3) Add FormGroup for new container member
 		const buildFormGroup = buildFormGroupFunctionFactory(new FormBuilder());
 		const newFormGroup = buildFormGroup(containerTemplate.meta);
 		(this.formGroup.get(repeatingContainerName) as FormArray).push(newFormGroup);
 	}
 
-	deleteRCMember(repeatingContainerName: string, index: number): void {
+	deleteRCMemberAllowed(repeatingContainerName: string): boolean {
+		const rcMeta = this.formMetaData[repeatingContainerName];
+		return typeof rcMeta.minRepeat === 'number' && rcMeta.minRepeat < rcMeta.meta.length;
+	}
 
+	deleteRCMember(repeatingContainerName: string, index: number): void {
+		// (1) Check that we can still delete controls
+		if (!this.deleteRCMemberAllowed(repeatingContainerName)) {
+			return;
+		}
+		// (2) Delete from the metadata, and rename the groups
+		const rcMeta = this.formMetaData[repeatingContainerName];
+		const metaArr = [ ...rcMeta.meta ];
+		const newMetaArr = [ ...metaArr.slice(0, index), ...metaArr.slice(index + 1) ]
+			.map((m, i) => { m.name = `group${i+1}`; return m; });
+		rcMeta.meta = newMetaArr;
+		// (3) Delete the corresponding FormGroup from the FormArray
+		(this.formGroup.get(repeatingContainerName) as FormArray).removeAt(index);
 	}
 
 	getValidationFailureMessage(control: FormControl, meta: StringMap<any>) {

+ 13 - 0
src/styles.scss

@@ -116,6 +116,19 @@ div.col-sm-8 {
 	display: none;
 }
 
+// ---------------------------------------------------------------------------------------------------------------------
+// General styles
+
+.btn-disabled {
+	color: #AAA !important;
+	background-color: #CCC !important;
+	border-color: #CCC !important;;
+	cursor: not-allowed !important;
+	&:hover {
+		background-color: #CCC !important;;
+	}
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 // Errors