From 176be06c12220a5601a6c04fa9a4437b45a08d71 Mon Sep 17 00:00:00 2001 From: IAfanasov Date: Fri, 4 Oct 2019 10:59:39 +0200 Subject: [PATCH] fix(typeahead): clear the model on input change when editable=false (#3267) Model is cleared on input change instead of after suggestions are fetched Fixes #3262 --- src/typeahead/typeahead.spec.ts | 39 +++++++++++++++++++++++++++++++++ src/typeahead/typeahead.ts | 11 ++-------- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/typeahead/typeahead.spec.ts b/src/typeahead/typeahead.spec.ts index 16d9448fb7..59ff5b1b6d 100644 --- a/src/typeahead/typeahead.spec.ts +++ b/src/typeahead/typeahead.spec.ts @@ -630,6 +630,39 @@ describe('ngb-typeahead', () => { expect(fixture.componentInstance.model).toBeUndefined(); }); })); + + it('should clear model on user input when the editable option is on and no search was triggered', async(() => { + const html = ` +
+ +
`; + const fixture = createTestComponent(html); + fixture.whenStable().then(() => { + fixture.detectChanges(); + const compiled = fixture.nativeElement; + expect(getNativeInput(compiled)).toHaveCssClass('ng-invalid'); + expect(getNativeInput(compiled)).not.toHaveCssClass('ng-valid'); + + changeInput(compiled, 'one'); + fixture.detectChanges(); + expect(getNativeInput(compiled)).toHaveCssClass('ng-invalid'); + expect(getNativeInput(compiled)).not.toHaveCssClass('ng-valid'); + expect(fixture.componentInstance.model).toBeUndefined(); + + const event = createKeyDownEvent(Key.Enter); + getDebugInput(fixture.debugElement).triggerEventHandler('keydown', event); + fixture.detectChanges(); + expect(getNativeInput(compiled)).not.toHaveCssClass('ng-invalid'); + expect(getNativeInput(compiled)).toHaveCssClass('ng-valid'); + expect(fixture.componentInstance.model).toBe('one'); + + changeInput(compiled, ''); + fixture.detectChanges(); + expect(getNativeInput(compiled)).toHaveCssClass('ng-invalid'); + expect(getNativeInput(compiled)).not.toHaveCssClass('ng-valid'); + expect(fixture.componentInstance.model).toBeUndefined(); + }); + })); }); describe('select event', () => { @@ -947,6 +980,12 @@ class TestComponent { return this.findOutput$; } + findFilter = + (text$: Observable) => { + return text$.pipe( + filter(term => term.length > 1), map(text => this._strings.filter(v => v.indexOf(text) > -1))); + } + findAnywhere = (text$: Observable) => { return text$.pipe(map(text => this._strings.filter(v => v.indexOf(text) > -1))); diff --git a/src/typeahead/typeahead.ts b/src/typeahead/typeahead.ts index c53543b469..f91589eb71 100644 --- a/src/typeahead/typeahead.ts +++ b/src/typeahead/typeahead.ts @@ -219,17 +219,10 @@ export class NgbTypeahead implements ControlValueAccessor, ngOnInit(): void { const inputValues$ = this._valueChanges.pipe(tap(value => { this._inputValueBackup = this.showHint ? value : null; - if (this.editable) { - this._onChange(value); - } + this._onChange(this.editable ? value : undefined); })); const results$ = inputValues$.pipe(this.ngbTypeahead); - const processedResults$ = results$.pipe(tap(() => { - if (!this.editable) { - this._onChange(undefined); - } - })); - const userInput$ = this._resubscribeTypeahead.pipe(switchMap(() => processedResults$)); + const userInput$ = this._resubscribeTypeahead.pipe(switchMap(() => results$)); this._subscription = this._subscribeToUserInput(userInput$); }