Skip to content

Commit c34360d

Browse files
UoE/fix: prevent multi-value form fields from losing input and 'Add more'
UoE/fix: prevent multi-value form fields from losing input and 'Add more'
2 parents 05b2c8c + 8b2467f commit c34360d

2 files changed

Lines changed: 74 additions & 3 deletions

File tree

src/app/shared/form/form.component.spec.ts

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,18 +449,76 @@ describe('FormComponent test suite', () => {
449449
}));
450450

451451
it('should dispatch FormChangeAction when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => {
452-
formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 0);
452+
// Add a second item first so we can actually remove one (the last item is never removed, only cleared)
453+
formComp.insertItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
454+
(store.dispatch as jasmine.Spy).calls.reset();
455+
456+
formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
453457

454458
expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testFormArray', service.getValueFromModel(formComp.formModel)));
455459
}));
456460

457461
it('should emit removeArrayItem Event when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => {
462+
// Add a second item first so we can actually remove one
463+
formComp.insertItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
458464
spyOn(formComp.removeArrayItem, 'emit');
459465

460-
formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 0);
466+
formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
461467

462468
expect(formComp.removeArrayItem.emit).toHaveBeenCalled();
463469
}));
470+
471+
it('should not remove the last item from the array, but clear its value instead', inject([FormBuilderService], (service: FormBuilderService) => {
472+
const arrayModel = formComp.formModel[0] as DynamicFormArrayModel;
473+
474+
// Verify there is exactly 1 item in the array
475+
expect(arrayModel.groups.length).toBe(1);
476+
477+
// Attempt to remove the last (and only) item
478+
formComp.removeItem(new Event('click'), arrayModel, 0);
479+
480+
// The array should still have 1 item (not removed, just cleared)
481+
expect(arrayModel.groups.length).toBe(1);
482+
}));
483+
484+
it('should clear the value of the last item when trying to remove it', inject([FormBuilderService], (service: FormBuilderService) => {
485+
const arrayModel = formComp.formModel[0] as DynamicFormArrayModel;
486+
const formArrayControl = formComp.formGroup.get(service.getPath(arrayModel));
487+
488+
// Set a value on the input
489+
const inputControl = formArrayControl.get([0, 'bootstrapArrayGroupInput']);
490+
inputControl.setValue('test value');
491+
expect(inputControl.value).toBe('test value');
492+
493+
// Attempt to remove the last item - should clear value instead
494+
formComp.removeItem(new Event('click'), arrayModel, 0);
495+
496+
// Value should be cleared
497+
expect(inputControl.value).toBeNull();
498+
// But the array should still have 1 group
499+
expect(arrayModel.groups.length).toBe(1);
500+
}));
501+
502+
it('should allow removing items when there are multiple items in the array', inject([FormBuilderService], (service: FormBuilderService) => {
503+
const arrayModel = formComp.formModel[0] as DynamicFormArrayModel;
504+
505+
// Add more items
506+
formComp.insertItem(new Event('click'), arrayModel, 1);
507+
formComp.insertItem(new Event('click'), arrayModel, 2);
508+
expect(arrayModel.groups.length).toBe(3);
509+
510+
// Remove one item - should actually remove it
511+
formComp.removeItem(new Event('click'), arrayModel, 2);
512+
expect(arrayModel.groups.length).toBe(2);
513+
514+
// Remove another
515+
formComp.removeItem(new Event('click'), arrayModel, 1);
516+
expect(arrayModel.groups.length).toBe(1);
517+
518+
// Try to remove the last one - should NOT remove it
519+
formComp.removeItem(new Event('click'), arrayModel, 0);
520+
expect(arrayModel.groups.length).toBe(1);
521+
}));
464522
});
465523
});
466524

src/app/shared/form/form.component.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
DynamicFormsCoreModule,
2929
} from '@ng-dynamic-forms/core';
3030
import { TranslateModule } from '@ngx-translate/core';
31+
import cloneDeep from 'lodash/cloneDeep';
3132
import findIndex from 'lodash/findIndex';
3233
import {
3334
Observable,
@@ -47,6 +48,7 @@ import {
4748
isNull,
4849
} from '../empty.util';
4950
import { DsDynamicFormComponent } from './builder/ds-dynamic-form-ui/ds-dynamic-form.component';
51+
import { DynamicConcatModel } from './builder/ds-dynamic-form-ui/models/ds-dynamic-concat.model';
5052
import { FormBuilderService } from './builder/form-builder.service';
5153
import { FormFieldMetadataValueObject } from './builder/models/form-field-metadata-value.model';
5254
import {
@@ -366,7 +368,18 @@ export class FormComponent implements OnDestroy, OnInit {
366368
// In case of qualdrop value remove event must be dispatched before removing the control from array
367369
this.removeArrayItem.emit(event);
368370
}
369-
this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext);
371+
if (index === 0 && formArrayControl.length === 1) {
372+
// Don't remove the last item, just clear its value to prevent the array from becoming empty
373+
event.model = cloneDeep(event.model);
374+
const fieldId = event.model.id;
375+
if (event.model instanceof DynamicConcatModel) {
376+
formArrayControl.at(0).get(fieldId).reset();
377+
} else {
378+
formArrayControl.at(0).get(fieldId).setValue(null);
379+
}
380+
} else {
381+
this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext);
382+
}
370383
this.formService.changeForm(this.formId, this.formModel);
371384
if (!this.formBuilderService.isQualdropGroup(event.model as DynamicFormControlModel)) {
372385
// dispatch remove event for any field type except for qualdrop value

0 commit comments

Comments
 (0)