diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts index 55f98df8ac..9b3d9f8342 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts @@ -86,7 +86,14 @@ export const FORM_GROUP_TEST_GROUP = new FormGroup({ }); describe('DsDynamicGroupComponent test suite', () => { - + const config = { + form: { + validatorMap: { + required: 'required', + regex: 'pattern' + } + } + } as any; let testComp: TestComponent; let groupComp: DsDynamicGroupComponent; let testFixture: ComponentFixture; @@ -126,7 +133,7 @@ describe('DsDynamicGroupComponent test suite', () => { FormBuilderService, FormComponent, FormService, - {provide: GLOBAL_CONFIG, useValue: {} as GlobalConfig}, + {provide: GLOBAL_CONFIG, useValue: config}, {provide: Store, useValue: store}, ], schemas: [CUSTOM_ELEMENTS_SCHEMA] diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts index 92141a0077..6fe4686974 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts @@ -70,7 +70,12 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit { this.formCollapsed = Observable.of(true); } this.model.valueUpdates.subscribe((value: any[]) => { - this.formCollapsed = (isNotEmpty(value) && !(value.length === 1 && hasOnlyEmptyProperties(value[0]))) ? Observable.of(true) : Observable.of(false); + if ((isNotEmpty(value) && !(value.length === 1 && hasOnlyEmptyProperties(value[0])))) { + this.collapseForm(); + } else { + this.expandForm(); + } + // this.formCollapsed = (isNotEmpty(value) && !(value.length === 1 && hasOnlyEmptyProperties(value[0]))) ? Observable.of(true) : Observable.of(false); }); this.formId = this.formService.getUniqueId(this.model.id); @@ -213,7 +218,9 @@ export class DsDynamicGroupComponent implements OnDestroy, OnInit { } private resetForm() { - this.formService.resetForm(this.formRef.formGroup, this.formModel, this.formId); + if (this.formRef) { + this.formService.resetForm(this.formRef.formGroup, this.formModel, this.formId); + } } ngOnDestroy(): void { diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.html index 5522e0b43a..c01716b674 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.html @@ -9,7 +9,7 @@ class="border-0 form-control-plaintext tag-input flex-grow-1 mt-1 mb-1 chips-sort-ignore" type="text" [class.pl-3]="chips.hasItems()" - [placeholder]="model.label" + [placeholder]="model.placeholder" [readonly]="model.readOnly" [(ngModel)]="currentValue" (blur)="onBlur($event)" @@ -29,7 +29,7 @@ [inputFormatter]="formatter" [name]="model.name" [ngbTypeahead]="search" - [placeholder]="model.label" + [placeholder]="model.placeholder" [readonly]="model.readOnly" [resultTemplate]="rt" [type]="model.inputType" diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.html index 27f031c83d..2d5eca2f16 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.html @@ -10,7 +10,7 @@ [inputFormatter]="formatter" [name]="model.name" [ngbTypeahead]="search" - [placeholder]="model.label" + [placeholder]="model.placeholder" [readonly]="model.readOnly" [resultTemplate]="rt" [type]="model.inputType" diff --git a/src/app/shared/form/builder/parsers/concat-field-parser.ts b/src/app/shared/form/builder/parsers/concat-field-parser.ts index 14a722b776..802d866ad7 100644 --- a/src/app/shared/form/builder/parsers/concat-field-parser.ts +++ b/src/app/shared/form/builder/parsers/concat-field-parser.ts @@ -27,7 +27,7 @@ export class ConcatFieldParser extends FieldParser { this.secondPlaceholder = secondPlaceholder; } - public modelFactory(fieldValue: FormFieldMetadataValueObject | any): any { + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { let clsGroup: DynamicFormControlLayout; let clsInput: DynamicFormControlLayout; @@ -54,8 +54,8 @@ export class ConcatFieldParser extends FieldParser { concatGroup.group = []; concatGroup.separator = this.separator; - const input1ModelConfig: DynamicInputModelConfig = this.initModel(newId + CONCAT_FIRST_INPUT_SUFFIX, true, false, false); - const input2ModelConfig: DynamicInputModelConfig = this.initModel(newId + CONCAT_SECOND_INPUT_SUFFIX, true, true, false); + const input1ModelConfig: DynamicInputModelConfig = this.initModel(newId + CONCAT_FIRST_INPUT_SUFFIX, label, false, false); + const input2ModelConfig: DynamicInputModelConfig = this.initModel(newId + CONCAT_SECOND_INPUT_SUFFIX, label, true, false); if (this.configData.mandatory) { input1ModelConfig.required = true; diff --git a/src/app/shared/form/builder/parsers/date-field-parser.ts b/src/app/shared/form/builder/parsers/date-field-parser.ts index 842036db6c..ae83c5a032 100644 --- a/src/app/shared/form/builder/parsers/date-field-parser.ts +++ b/src/app/shared/form/builder/parsers/date-field-parser.ts @@ -7,9 +7,9 @@ import { FormFieldMetadataValueObject } from '../models/form-field-metadata-valu export class DateFieldParser extends FieldParser { - public modelFactory(fieldValue: FormFieldMetadataValueObject): any { + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { let malformedDate = false; - const inputDateModelConfig: DynamicDatePickerModelConfig = this.initModel(); + const inputDateModelConfig: DynamicDatePickerModelConfig = this.initModel(null, label); inputDateModelConfig.toggleIcon = 'fa fa-calendar'; this.setValues(inputDateModelConfig as any, fieldValue); diff --git a/src/app/shared/form/builder/parsers/dropdown-field-parser.ts b/src/app/shared/form/builder/parsers/dropdown-field-parser.ts index d36bedd7a5..279f78f721 100644 --- a/src/app/shared/form/builder/parsers/dropdown-field-parser.ts +++ b/src/app/shared/form/builder/parsers/dropdown-field-parser.ts @@ -9,8 +9,8 @@ import { FormFieldMetadataValueObject } from '../models/form-field-metadata-valu export class DropdownFieldParser extends FieldParser { - public modelFactory(fieldValue: FormFieldMetadataValueObject): any { - const dropdownModelConfig: DynamicScrollableDropdownModelConfig = this.initModel(); + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { + const dropdownModelConfig: DynamicScrollableDropdownModelConfig = this.initModel(null, label); let layout: DynamicFormControlLayout; if (isNotEmpty(this.configData.selectableMetadata[0].authority)) { diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index ce41e3e9a7..855ef8109b 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -20,7 +20,7 @@ export abstract class FieldParser { constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions) { } - public abstract modelFactory(fieldValue?: FormFieldMetadataValueObject): any; + public abstract modelFactory(fieldValue?: FormFieldMetadataValueObject, label?: boolean): any; public parse() { if (((this.getInitValueCount() > 1 && !this.configData.repeatable) || (this.configData.repeatable)) @@ -33,6 +33,7 @@ export abstract class FieldParser { const config = { id: uniqueId() + '_array', + label: this.configData.label, initialCount: this.getInitArrayIndex(), notRepeteable: !this.configData.repeatable, groupFactory: () => { @@ -50,7 +51,7 @@ export abstract class FieldParser { arrayCounter++; } } - model = this.modelFactory(fieldValue); + model = this.modelFactory(fieldValue, false); } setLayout(model, 'element', 'host', 'col'); if (model.hasLanguages) { @@ -184,9 +185,8 @@ export abstract class FieldParser { controlModel.readOnly = this.parserOptions.readOnly; controlModel.disabled = this.parserOptions.readOnly; - if (label) { - controlModel.label = (labelEmpty) ? ' ' : this.configData.label; - } + // Set label + this.setLabel(controlModel, label, labelEmpty); controlModel.placeholder = this.configData.label; @@ -216,7 +216,7 @@ export abstract class FieldParser { controlModel.errorMessages = Object.assign( {}, controlModel.errorMessages, - {pattern: 'form.error.validation.pattern', regex: 'form.error.validation.pattern'}); + {pattern: 'form.error.validation.pattern'}); } @@ -229,6 +229,12 @@ export abstract class FieldParser { {required: this.configData.mandatoryMessage}); } + protected setLabel(controlModel, label = true, labelEmpty = false) { + if (label) { + controlModel.label = (labelEmpty) ? ' ' : this.configData.label; + } + } + protected setOptions(controlModel) { // Checks if field has multiple values and sets options available if (isNotUndefined(this.configData.selectableMetadata) && this.configData.selectableMetadata.length > 1) { diff --git a/src/app/shared/form/builder/parsers/group-field-parser.ts b/src/app/shared/form/builder/parsers/group-field-parser.ts index 11bf425ae6..82f2668420 100644 --- a/src/app/shared/form/builder/parsers/group-field-parser.ts +++ b/src/app/shared/form/builder/parsers/group-field-parser.ts @@ -11,8 +11,8 @@ import { FormRowModel } from '../../../../core/shared/config/config-submission-f export class GroupFieldParser extends FieldParser { - public modelFactory(fieldValue: FormFieldMetadataValueObject) { - const modelConfiguration: DynamicGroupModelConfig = this.initModel(); + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean) { + const modelConfiguration: DynamicGroupModelConfig = this.initModel(null, label); modelConfiguration.scopeUUID = this.parserOptions.authorityUuid; modelConfiguration.submissionScope = this.parserOptions.submissionScope; diff --git a/src/app/shared/form/builder/parsers/list-field-parser.ts b/src/app/shared/form/builder/parsers/list-field-parser.ts index 7fa062ad79..273c9d1665 100644 --- a/src/app/shared/form/builder/parsers/list-field-parser.ts +++ b/src/app/shared/form/builder/parsers/list-field-parser.ts @@ -8,8 +8,8 @@ import { DynamicListRadioGroupModel } from '../ds-dynamic-form-ui/models/list/dy export class ListFieldParser extends FieldParser { searchOptions: IntegrationSearchOptions; - public modelFactory(fieldValue: FormFieldMetadataValueObject): any { - const listModelConfig = this.initModel(); + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { + const listModelConfig = this.initModel(null, label); listModelConfig.repeatable = this.configData.repeatable; if (this.configData.selectableMetadata[0].authority diff --git a/src/app/shared/form/builder/parsers/lookup-field-parser.ts b/src/app/shared/form/builder/parsers/lookup-field-parser.ts index 08c0eb5830..9e9c434c4f 100644 --- a/src/app/shared/form/builder/parsers/lookup-field-parser.ts +++ b/src/app/shared/form/builder/parsers/lookup-field-parser.ts @@ -1,11 +1,12 @@ import { FieldParser } from './field-parser'; import { DynamicLookupModel, DynamicLookupModelConfig } from '../ds-dynamic-form-ui/models/lookup/dynamic-lookup.model'; +import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; export class LookupFieldParser extends FieldParser { - public modelFactory(fieldValue: any): any { + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { if (this.configData.selectableMetadata[0].authority) { - const lookupModelConfig: DynamicLookupModelConfig = this.initModel(); + const lookupModelConfig: DynamicLookupModelConfig = this.initModel(null, label); this.setAuthorityOptions(lookupModelConfig, this.parserOptions.authorityUuid); diff --git a/src/app/shared/form/builder/parsers/lookup-name-field-parser.ts b/src/app/shared/form/builder/parsers/lookup-name-field-parser.ts index 05e26b0522..684e06bcb6 100644 --- a/src/app/shared/form/builder/parsers/lookup-name-field-parser.ts +++ b/src/app/shared/form/builder/parsers/lookup-name-field-parser.ts @@ -3,12 +3,13 @@ import { DynamicLookupNameModel, DynamicLookupNameModelConfig } from '../ds-dynamic-form-ui/models/lookup/dynamic-lookup-name.model'; +import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; export class LookupNameFieldParser extends FieldParser { - public modelFactory(fieldValue: any): any { + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { if (this.configData.selectableMetadata[0].authority) { - const lookupModelConfig: DynamicLookupNameModelConfig = this.initModel(); + const lookupModelConfig: DynamicLookupNameModelConfig = this.initModel(null, label); this.setAuthorityOptions(lookupModelConfig, this.parserOptions.authorityUuid); diff --git a/src/app/shared/form/builder/parsers/onebox-field-parser.ts b/src/app/shared/form/builder/parsers/onebox-field-parser.ts index 8af01961ad..8949972918 100644 --- a/src/app/shared/form/builder/parsers/onebox-field-parser.ts +++ b/src/app/shared/form/builder/parsers/onebox-field-parser.ts @@ -18,7 +18,7 @@ import { export class OneboxFieldParser extends FieldParser { - public modelFactory(fieldValue: FormFieldMetadataValueObject): any { + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { if (this.configData.selectableMetadata.length > 1) { // Case ComboBox const clsGroup = { @@ -55,14 +55,14 @@ export class OneboxFieldParser extends FieldParser { inputSelectGroup.group = []; inputSelectGroup.legend = this.configData.label; - const selectModelConfig: DynamicSelectModelConfig = this.initModel(newId + QUALDROP_METADATA_SUFFIX); + const selectModelConfig: DynamicSelectModelConfig = this.initModel(newId + QUALDROP_METADATA_SUFFIX, label); this.setOptions(selectModelConfig); if (isNotEmpty(fieldValue)) { selectModelConfig.value = fieldValue.metadata; } inputSelectGroup.group.push(new DynamicSelectModel(selectModelConfig, clsSelect)); - const inputModelConfig: DsDynamicInputModelConfig = this.initModel(newId + QUALDROP_VALUE_SUFFIX, true, true); + const inputModelConfig: DsDynamicInputModelConfig = this.initModel(newId + QUALDROP_VALUE_SUFFIX, label, true); this.setValues(inputModelConfig, fieldValue); inputSelectGroup.readOnly = selectModelConfig.disabled && inputModelConfig.readOnly; @@ -70,13 +70,13 @@ export class OneboxFieldParser extends FieldParser { return new DynamicQualdropModel(inputSelectGroup, clsGroup); } else if (this.configData.selectableMetadata[0].authority) { - const typeaheadModelConfig: DsDynamicTypeaheadModelConfig = this.initModel(); + const typeaheadModelConfig: DsDynamicTypeaheadModelConfig = this.initModel(null, label); this.setAuthorityOptions(typeaheadModelConfig, this.parserOptions.authorityUuid); this.setValues(typeaheadModelConfig, fieldValue, true); const typeaheadModel = new DynamicTypeaheadModel(typeaheadModelConfig); return typeaheadModel; } else { - const inputModelConfig: DsDynamicInputModelConfig = this.initModel(); + const inputModelConfig: DsDynamicInputModelConfig = this.initModel(null, label); this.setValues(inputModelConfig, fieldValue); const inputModel = new DsDynamicInputModel(inputModelConfig); return inputModel; diff --git a/src/app/shared/form/builder/parsers/tag-field-parser.ts b/src/app/shared/form/builder/parsers/tag-field-parser.ts index 91fafd5a58..c1c39feb2b 100644 --- a/src/app/shared/form/builder/parsers/tag-field-parser.ts +++ b/src/app/shared/form/builder/parsers/tag-field-parser.ts @@ -4,8 +4,8 @@ import { DynamicTagModel, DynamicTagModelConfig } from '../ds-dynamic-form-ui/mo export class TagFieldParser extends FieldParser { - public modelFactory(fieldValue: FormFieldMetadataValueObject): any { - const tagModelConfig: DynamicTagModelConfig = this.initModel(); + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { + const tagModelConfig: DynamicTagModelConfig = this.initModel(null, label); if (this.configData.selectableMetadata[0].authority && this.configData.selectableMetadata[0].authority.length > 0) { this.setAuthorityOptions(tagModelConfig, this.parserOptions.authorityUuid); diff --git a/src/app/shared/form/builder/parsers/textarea-field-parser.ts b/src/app/shared/form/builder/parsers/textarea-field-parser.ts index de3728b2b5..740e94721f 100644 --- a/src/app/shared/form/builder/parsers/textarea-field-parser.ts +++ b/src/app/shared/form/builder/parsers/textarea-field-parser.ts @@ -8,8 +8,8 @@ import { export class TextareaFieldParser extends FieldParser { - public modelFactory(fieldValue: FormFieldMetadataValueObject | any): any { - const textAreaModelConfig: DsDynamicTextAreaModelConfig = this.initModel(); + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { + const textAreaModelConfig: DsDynamicTextAreaModelConfig = this.initModel(null, label); let layout: DynamicFormControlLayout; diff --git a/src/app/shared/form/form.component.html b/src/app/shared/form/form.component.html index 5dfaa4bec1..1b5f2ef72f 100644 --- a/src/app/shared/form/form.component.html +++ b/src/app/shared/form/form.component.html @@ -15,7 +15,7 @@
+ class="col-xs-2 d-flex flex-column justify-content-sm-start align-items-end">