diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.spec.ts index f8d3611bb03..1edd044931d 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.spec.ts @@ -28,6 +28,7 @@ import { } from '@ng-dynamic-forms/core'; import { TranslateModule } from '@ngx-translate/core'; import { InfiniteScrollModule } from 'ngx-infinite-scroll'; +import { of } from 'rxjs'; import { APP_DATA_SERVICES_MAP } from '../../../../../../../config/app-config.interface'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model'; @@ -42,6 +43,7 @@ import { hasClass, } from '../../../../../testing/utils.test'; import { VocabularyServiceStub } from '../../../../../testing/vocabulary-service.stub'; +import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { DsDynamicScrollableDropdownComponent } from './dynamic-scrollable-dropdown.component'; import { DynamicScrollableDropdownModel } from './dynamic-scrollable-dropdown.model'; @@ -232,6 +234,50 @@ describe('Dynamic Dynamic Scrollable Dropdown component', () => { expect(scrollableDropdownComp.optionsList).toEqual(vocabularyServiceStub.getList()); expect(scrollableDropdownComp.model.value).toEqual(modelValue); }); + + it('should fall back to the underlying value when display is empty on value change', () => { + const valueWithEmptyDisplay = { display: '', value: 'Corpus' }; + scrollableDropdownComp.setCurrentValue(valueWithEmptyDisplay); + + let currentValue; + scrollableDropdownComp.currentValue.subscribe((v) => currentValue = v); + + expect(currentValue).toBe('Corpus'); + }); + + it('should fall back to the underlying value when display is empty on init', () => { + // Build the value bypassing the FormFieldMetadataValueObject constructor (which would + // otherwise apply its own `display || value`), so the init branch genuinely receives an + // empty display and exercises the fallback in setCurrentValue. + const emptyDisplayValue = Object.assign( + new FormFieldMetadataValueObject(), + { display: '', value: 'Corpus' }, + ); + spyOn(scrollableDropdownComp, 'getInitValueFromModel').and.returnValue(of(emptyDisplayValue)); + scrollableDropdownComp.setCurrentValue(emptyDisplayValue, true); + + let currentValue; + scrollableDropdownComp.currentValue.subscribe((v) => currentValue = v); + + expect(currentValue).toBe('Corpus'); + }); + + // Regression for ufal/clarin-dspace#1377: after a dc.type change the section + // reloads and pushes a new value with an empty display through the form control. + // The rendered input must not blank out. + it('should keep the rendered value when a value with empty display arrives via valueChanges', fakeAsync(() => { + const reloadedValue = Object.assign( + new FormFieldMetadataValueObject(), + { display: '', value: 'Corpus', authority: 'corpus-auth' }, + ); + + scrollableDropdownComp.group.get(scrollableDropdownComp.model.id).setValue(reloadedValue); + tick(); + scrollableDropdownFixture.detectChanges(); + + const input = scrollableDropdownFixture.debugElement.query(By.css('input.form-control')).nativeElement; + expect(input.value).toBe('Corpus'); + })); }); }); }); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts index 243efcc8963..bad01bd3b86 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts @@ -360,7 +360,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom if (init && !this.useFindAllService) { result = this.getInitValueFromModel().pipe( - map((formValue: FormFieldMetadataValueObject) => formValue.display), + map((formValue: FormFieldMetadataValueObject) => formValue.display || formValue.value), ); } else { if (isEmpty(value)) { @@ -370,7 +370,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom } else if (this.useFindAllService) { result = of(value[this.model.displayKey]); } else { - result = of(value.display); + result = of(value.display || value.value); } }