diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html index 7473f894fa..0ab69851a5 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html @@ -13,6 +13,11 @@ + +  
{{ message | translate: model.validators }} @@ -32,7 +37,7 @@
-
+
-
-
- - -
-
- -
-
- - - - - - -
-
-
-
- - -
-
+ + + +
+
+ + +
- + +
+
+ +
+
+
+ +
+ + + +
+
+
+
+ + +
+
+
+ +
diff --git a/src/app/shared/form/form.component.ts b/src/app/shared/form/form.component.ts index a4af407a55..f749f4391b 100644 --- a/src/app/shared/form/form.component.ts +++ b/src/app/shared/form/form.component.ts @@ -187,7 +187,6 @@ export class FormComponent implements OnDestroy, OnInit { if (field) { const model: DynamicFormControlModel = this.formBuilderService.findById(fieldId, formModel); this.formService.addErrorToField(field, model, error.message); - // this.formService.validateAllFormFields(formGroup); this.changeDetectorRef.detectChanges(); } @@ -300,55 +299,15 @@ export class FormComponent implements OnDestroy, OnInit { removeItem($event, arrayContext: DynamicFormArrayModel, index: number): void { const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray; - this.removeArrayItem.emit(this.getEvent($event, arrayContext, index - 1, 'remove')); + this.removeArrayItem.emit(this.getEvent($event, arrayContext, index, 'remove')); this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext); this.formService.changeForm(this.formId, this.formModel); } insertItem($event, arrayContext: DynamicFormArrayModel, index: number): void { const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray; - - // First emit the new value so it can be sent to the server - const value = formArrayControl.controls[0].value; - const event = this.getEvent($event, arrayContext, 0, 'add'); - this.addArrayItem.emit(event); - this.change.emit(event); - - // Next: update the UI so the user sees the changes - // without having to wait for the server's reply - - // add an empty new field at the bottom - this.formBuilderService.addFormArrayGroup(formArrayControl, arrayContext); - - // set that field to the new value - const model = arrayContext.groups[arrayContext.groups.length - 1].group[0] as any; - if (model.hasAuthority) { - model.value = Object.values(value)[0]; - const ctrl = formArrayControl.controls[formArrayControl.length - 1]; - const ctrlValue = ctrl.value; - const ctrlValueKey = Object.keys(ctrlValue)[0]; - ctrl.setValue({ - [ctrlValueKey]: model.value - }); - } else if (this.formBuilderService.isQualdropGroup(model)) { - const ctrl = formArrayControl.controls[formArrayControl.length - 1]; - const ctrlKey = Object.keys(ctrl.value).find((key: string) => isNotEmpty(key.match(QUALDROP_GROUP_REGEX))); - const valueKey = Object.keys(value).find((key: string) => isNotEmpty(key.match(QUALDROP_GROUP_REGEX))); - if (ctrlKey !== valueKey) { - Object.defineProperty(value, ctrlKey, Object.getOwnPropertyDescriptor(value, valueKey)); - delete value[valueKey]; - } - ctrl.setValue(value); - } else { - formArrayControl.controls[formArrayControl.length - 1].setValue(value); - } - - // Clear the topmost field by removing the filled out version and inserting a new, empty version. - // Doing it this way ensures an empty value of the correct type is added without a bunch of ifs here - this.formBuilderService.removeFormArrayGroup(0, formArrayControl, arrayContext); - this.formBuilderService.insertFormArrayGroup(0, formArrayControl, arrayContext); - - // Tell the formService that it should rerender. + this.formBuilderService.insertFormArrayGroup(index, formArrayControl, arrayContext); + this.addArrayItem.emit(this.getEvent($event, arrayContext, index, 'add')); this.formService.changeForm(this.formId, this.formModel); } diff --git a/src/app/submission/sections/form/section-form-operations.service.ts b/src/app/submission/sections/form/section-form-operations.service.ts index d019663d6c..1c372fb06f 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -9,15 +9,7 @@ import { DynamicFormControlModel } from '@ng-dynamic-forms/core'; -import { - hasNoValue, - hasValue, - isNotEmpty, - isNotNull, - isNotUndefined, - isNull, - isUndefined -} from '../../../shared/empty.util'; +import { hasValue, isNotEmpty, isNotNull, isNotUndefined, isNull, isUndefined } from '../../../shared/empty.util'; import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; import { FormFieldPreviousValueObject } from '../../../shared/form/builder/models/form-field-previous-value-object'; import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; @@ -30,6 +22,7 @@ import { DynamicQualdropModel } from '../../../shared/form/builder/ds-dynamic-fo import { DynamicRelationGroupModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { deepClone } from 'fast-json-patch'; +import { dateToString, isNgbDateStruct } from '../../../shared/date.util'; /** * The service handling all form section operations @@ -71,9 +64,6 @@ export class SectionFormOperationsService { case 'change': this.dispatchOperationsFromChangeEvent(pathCombiner, event, previousValue, hasStoredValue); break; - case 'add': - this.dispatchOperationsFromAddEvent(pathCombiner, event); - break; default: break; } @@ -245,6 +235,8 @@ export class SectionFormOperationsService { // Language without Authority (input, textArea) fieldValue = new FormFieldMetadataValueObject(value, language); } + } else if (isNgbDateStruct(value)) { + fieldValue = new FormFieldMetadataValueObject(dateToString(value)); } else if (value instanceof FormFieldLanguageValueObject || value instanceof VocabularyEntry || value instanceof VocabularyEntryDetail || isObject(value)) { fieldValue = value; @@ -295,7 +287,7 @@ export class SectionFormOperationsService { const value = this.getFieldValueFromChangeEvent(event); if (this.formBuilder.isQualdropGroup(event.model as DynamicFormControlModel)) { this.dispatchOperationsFromMap(this.getQualdropValueMap(event), pathCombiner, event, previousValue); - } else if (isNotEmpty(value)) { + } else if (isNotEmpty(value) && (value instanceof FormFieldMetadataValueObject && value.hasValue())) { this.operationsBuilder.remove(pathCombiner.getPath(path)); } } @@ -362,7 +354,7 @@ export class SectionFormOperationsService { } else if (this.formBuilder.isRelationGroup(event.model)) { // It's a relation model this.dispatchOperationsFromMap(this.getValueMap(value), pathCombiner, event, previousValue); - } else if (this.formBuilder.hasArrayGroupValue(event.model) && hasNoValue((event.model as any).relationshipConfig)) { + } else if (this.formBuilder.hasArrayGroupValue(event.model)) { // Model has as value an array, so dispatch an add operation with entire block of values this.operationsBuilder.add( pathCombiner.getPath(segmentedPath), @@ -398,13 +390,22 @@ export class SectionFormOperationsService { value); } previousValue.delete(); - } else if (value.hasValue() && (isUndefined(this.getArrayIndexFromEvent(event)) - || this.getArrayIndexFromEvent(event) === 0)) { + } else if (value.hasValue()) { + // Here model has no previous value but a new one + if (isUndefined(this.getArrayIndexFromEvent(event)) + || this.getArrayIndexFromEvent(event) === 0) { // Model is single field or is part of an array model but is the first item, // so dispatch an add operation that initialize the values of a specific metadata this.operationsBuilder.add( pathCombiner.getPath(segmentedPath), value, true); + } else { + // Model is part of an array model but is not the first item, + // so dispatch an add operation that add a value to an existent metadata + this.operationsBuilder.add( + pathCombiner.getPath(path), + value); + } } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 51a2c0bd35..05d3aa4e49 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1267,6 +1267,8 @@ "form.clear-help": "Click here to remove the selected value", + "form.discard": "Discard", + "form.edit": "Edit", "form.edit-help": "Click here to edit the selected value",