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 51e7667200..449481152d 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
@@ -28,7 +28,8 @@
aria-hidden="true"
[authorityValue]="currentValue"
(whenClickOnConfidenceNotAccepted)="whenClickOnConfidenceNotAccepted($event)">
- {
inputElement.value = 'test value';
inputElement.dispatchEvent(new Event('input'));
- expect((typeaheadComp.model as any).value).toEqual(new FormFieldMetadataValueObject('test value'))
+ expect(typeaheadComp.inputValue).toEqual(new FormFieldMetadataValueObject('test value'))
});
@@ -173,19 +173,56 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
});
- it('should emit blur Event onBlur', () => {
+ it('should emit blur Event onBlur when popup is closed', () => {
spyOn(typeaheadComp.blur, 'emit');
+ spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false);
typeaheadComp.onBlur(new Event('blur'));
expect(typeaheadComp.blur.emit).toHaveBeenCalled();
});
- it('should emit change Event onBlur when AuthorityOptions.closed is false', () => {
+ it('should not emit blur Event onBlur when popup is opened', () => {
+ spyOn(typeaheadComp.blur, 'emit');
+ spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(true);
+ const input = typeaheadFixture.debugElement.query(By.css('input'));
+
+ input.nativeElement.blur();
+ expect(typeaheadComp.blur.emit).not.toHaveBeenCalled();
+ });
+
+ it('should emit change Event onBlur when AuthorityOptions.closed is false and inputValue is changed', () => {
typeaheadComp.inputValue = 'test value';
typeaheadFixture.detectChanges();
spyOn(typeaheadComp.blur, 'emit');
spyOn(typeaheadComp.change, 'emit');
- typeaheadComp.onBlur(new Event('blur'));
- // expect(typeaheadComp.change.emit).toHaveBeenCalled();
+ spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false);
+ typeaheadComp.onBlur(new Event('blur', ));
+ expect(typeaheadComp.change.emit).toHaveBeenCalled();
+ expect(typeaheadComp.blur.emit).toHaveBeenCalled();
+ });
+
+ it('should not emit change Event onBlur when AuthorityOptions.closed is false and inputValue is not changed', () => {
+ typeaheadComp.inputValue = 'test value';
+ typeaheadComp.model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG);
+ (typeaheadComp.model as any).value = 'test value';
+ typeaheadFixture.detectChanges();
+ spyOn(typeaheadComp.blur, 'emit');
+ spyOn(typeaheadComp.change, 'emit');
+ spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false);
+ typeaheadComp.onBlur(new Event('blur', ));
+ expect(typeaheadComp.change.emit).not.toHaveBeenCalled();
+ expect(typeaheadComp.blur.emit).toHaveBeenCalled();
+ });
+
+ it('should not emit change Event onBlur when AuthorityOptions.closed is false and inputValue is null', () => {
+ typeaheadComp.inputValue = null;
+ typeaheadComp.model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG);
+ (typeaheadComp.model as any).value = 'test value';
+ typeaheadFixture.detectChanges();
+ spyOn(typeaheadComp.blur, 'emit');
+ spyOn(typeaheadComp.change, 'emit');
+ spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false);
+ typeaheadComp.onBlur(new Event('blur', ));
+ expect(typeaheadComp.change.emit).not.toHaveBeenCalled();
expect(typeaheadComp.blur.emit).toHaveBeenCalled();
});
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
index ace6812858..136d1db1c2 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
@@ -1,4 +1,4 @@
-import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { FormGroup } from '@angular/forms';
import {
@@ -8,14 +8,13 @@ import {
} from '@ng-dynamic-forms/core';
import { catchError, debounceTime, distinctUntilChanged, filter, map, merge, switchMap, tap } from 'rxjs/operators';
import { Observable, of as observableOf, Subject } from 'rxjs';
-import { NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap';
+import { NgbTypeahead, NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap';
import { AuthorityService } from '../../../../../../core/integration/authority.service';
import { DynamicTypeaheadModel } from './dynamic-typeahead.model';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model';
-import { isEmpty, isNotEmpty } from '../../../../../empty.util';
+import { isEmpty, isNotEmpty, isNotNull } from '../../../../../empty.util';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
-
import { ConfidenceType } from '../../../../../../core/integration/models/confidence-type';
@Component({
@@ -32,6 +31,8 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp
@Output() change: EventEmitter = new EventEmitter();
@Output() focus: EventEmitter = new EventEmitter();
+ @ViewChild('instance') instance: NgbTypeahead;
+
searching = false;
searchOptions: IntegrationSearchOptions;
searchFailed = false;
@@ -105,16 +106,26 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp
onInput(event) {
if (!this.model.authorityOptions.closed && isNotEmpty(event.target.value)) {
this.inputValue = new FormFieldMetadataValueObject(event.target.value);
- this.model.valueUpdates.next(this.inputValue);
}
}
onBlur(event: Event) {
- if (!this.model.authorityOptions.closed && isNotEmpty(this.inputValue)) {
- this.change.emit(this.inputValue);
- this.inputValue = null;
+ if (!this.instance.isPopupOpen()) {
+ if (!this.model.authorityOptions.closed && isNotEmpty(this.inputValue)) {
+ if (isNotNull(this.inputValue) && this.model.value !== this.inputValue) {
+ this.model.valueUpdates.next(this.inputValue);
+ this.change.emit(this.inputValue);
+ }
+ this.inputValue = null;
+ }
+ this.blur.emit(event);
+ } else {
+ // prevent on blur propagation if typeahed suggestions are showed
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ // set focus on input again, this is to avoid to lose changes when no suggestion is selected
+ (event.target as HTMLInputElement).focus();
}
- this.blur.emit(event);
}
onChange(event: Event) {
@@ -141,4 +152,5 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp
this.click$.next(this.formatter(this.currentValue));
}
}
+
}