From 6c8d16c8788af19030ff15f4641d130769b1cff6 Mon Sep 17 00:00:00 2001 From: Amad Ul Hassan Date: Fri, 10 Apr 2026 11:44:54 +0200 Subject: [PATCH] 123 selecting language from dropdown in submission form is broken (ufal/dspace-angular#124) * show ISO code on selection for language field Ensure language autocomplete displays ISO codes consistently after selection and after form reload by handling string values in the input formatter. * removing unnecessary comments removing unnecessary comments * Normalize autocomplete values and add tests Normalize autocomplete values and add tests (cherry picked from commit 940861d353d52b310f8f03444e20912ac9377da5) --- .../ds-dynamic-autocomplete.component.spec.ts | 25 +++++++++++++- .../ds-dynamic-autocomplete.component.ts | 34 ++++++++++++------- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/autocomplete/ds-dynamic-autocomplete.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/autocomplete/ds-dynamic-autocomplete.component.spec.ts index 9e844a8b17d..646125eae5a 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/autocomplete/ds-dynamic-autocomplete.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/autocomplete/ds-dynamic-autocomplete.component.spec.ts @@ -170,9 +170,32 @@ describe('DsDynamicAutocompleteComponent test suite', () => { autFixture.detectChanges(); flush(); - expect(autComp.model.value).toEqual(modelValue.display); + expect(autComp.model.value).toEqual(modelValue.value); + expect(autComp.currentValue).toEqual(modelValue.value); expect(autComp.change.emit).toHaveBeenCalled(); })); + + it('should normalize object value to string on blur', () => { + spyOn(autComp.change, 'emit'); + autComp.currentValue = { value: 'aig', display: 'Alumu-Tesu' }; + + autComp.onBlur(new Event('blur')); + + expect(autComp.model.value).toEqual('aig'); + expect(autComp.change.emit).toHaveBeenCalledWith('aig'); + }); + + it('should format string values as-is', () => { + expect(autComp.formatter('aig')).toEqual('aig'); + }); + + it('should format object values using value first', () => { + expect(autComp.formatter({ value: 'aig', display: 'Alumu-Tesu' })).toEqual('aig'); + }); + + it('should format object values using display fallback', () => { + expect(autComp.formatter({ display: 'Alumu-Tesu' })).toEqual('Alumu-Tesu'); + }); }); }); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/autocomplete/ds-dynamic-autocomplete.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/autocomplete/ds-dynamic-autocomplete.component.ts index 4a85aaf9905..a0d82c4875a 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/autocomplete/ds-dynamic-autocomplete.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/autocomplete/ds-dynamic-autocomplete.component.ts @@ -133,7 +133,7 @@ export class DsDynamicAutocompleteComponent extends DsDynamicTagComponent implem * @param event */ onBlur(event: Event) { - this.dispatchUpdate(this.currentValue); + this.dispatchUpdate(this.normalizeValue(this.currentValue)); this.cdr.detectChanges(); } @@ -148,7 +148,9 @@ export class DsDynamicAutocompleteComponent extends DsDynamicTagComponent implem updateValue.value = this.handlePrefix.value + handle_title[0]; } - this.dispatchUpdate(updateValue.display); + const selectedValue = this.normalizeValue(updateValue); + this.currentValue = selectedValue; + this.dispatchUpdate(selectedValue); } /** @@ -170,15 +172,11 @@ export class DsDynamicAutocompleteComponent extends DsDynamicTagComponent implem if (init) { this.getInitValueFromModel() .subscribe((formValue: FormFieldMetadataValueObject) => { - this.currentValue = formValue; + this.currentValue = this.normalizeValue(formValue); this.cdr.detectChanges(); }); } else { - if (isEmpty(value)) { - result = ''; - } else { - result = value.value; - } + result = isEmpty(value) ? '' : this.normalizeValue(value); this.currentValue = result; this.cdr.detectChanges(); @@ -186,13 +184,25 @@ export class DsDynamicAutocompleteComponent extends DsDynamicTagComponent implem } /** - * Do not show whole suggestion object but just display value. - * @param x + * Formats input values for the typeahead. + * If x is a string (persisted ISO), return it as-is. + * If x is an object, return value first and fallback to display. + * @param x raw string/object value from model/typeahead */ - formatter = (x: { display: string }) => { - return x.display; + formatter = (x: string | { value?: string; display?: string }) => { + return this.normalizeValue(x); }; + /** + * Normalize autocomplete values to string. + */ + private normalizeValue(value: string | { value?: string; display?: string }): string { + if (typeof value === 'string') { + return value; + } + return value?.value || value?.display || ''; + } + /** * Pretify suggestion. * @param suggestion