Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autocomplete empty text when lost focus #8740

Closed
aceberio opened this issue Apr 14, 2020 · 20 comments
Closed

Autocomplete empty text when lost focus #8740

aceberio opened this issue Apr 14, 2020 · 20 comments
Assignees
Labels
LTS-FIXED-9.2.1 Fixed in PrimeNG LTS 9.2.1 LTS-FIXED-10.0.6 Fixed in PrimeNG LTS 10.0.6 Type: Bug Issue contains a bug related to a specific component. Something about the component is not working
Milestone

Comments

@aceberio
Copy link

If i have an object in ngModel with properties, where one property is declarated in field, if search and select with enter value from items list then when lost focus text in autocomplete will become empty. But if i select from items list with mouse click text will remain after lost focus. This issue not appear in PrimeNg version 9.0.0.

Issue

PrimeNg version : 9.0.5
Angular version : 9.1

Related past issues
https://github.com/primefaces/primeng/issues/910
https://github.com/primefaces/primeng/issues/3147

@cesarrew
Copy link

Same problem here.

@cesarrew
Copy link

The problem appeared in 9.0.1 version.

@luisabreu
Copy link

luisabreu commented Apr 30, 2020

Same thing here...Any tips or workarounds? 9.0.6 still has the bug.

I've just noticed that this willl only happen when the forceSelection property is set to true (which on my case is required to ensure the proper selection of an existing item on the list).

@thornidlo
Copy link

Yes, only with forceSelection this happens. Please, take a look at this. With this bug we cannot use autocomplete via keyboard. Atributte forceSelection is mandatory for us, because selected item is not atomic, but object.

@mjonas4356
Copy link
Contributor

I have same problem, cant go back on version 9.0.0. I use improved p-Dialog.

@Cito
Copy link
Contributor

Cito commented Jun 1, 2020

Noticed the same problem. As some have already mentioned, this happens since v9.0.1 when you set forceSelection=true. I found that the problem has been caused by f8c37e1 which tried to fix #8511.

The problem still exists in the current v9.1.0.

What happens internally in the component is this: After the overlay with the suggestions is closed, onOverlayAnimationDone() sets the suggestions list to null. The same also happens in onInput when you type too few characters. When you now tab and the input had changed, onInputChange() is called which then validates the input against the suggestions, but because there are no suggestions any more, it is considered invalid and reset.

Does anybody see a reason why the suggestion list is deleted internally in these two places? My naive fix would be to simply never delete it.

@MaKCbIMKo
Copy link

Having the same problem in v9.1.0. And I confirm it was introduced by fixing #8511. But I need this fix as well, so I can't switch back to v9.0.0.

I have 'autocomplete' component inside html form and I use the following 'autocomplete' settings:

autoHighlight: true
forceSelection: true

And then I do following steps:
0. focus autocomplete input

  1. type any letter to display suggestions (since I use autoHighlight: true - first suggestion is highlighted/selected)
  2. press 'enter' on keyboard -> it will close suggestions and select first highlighted suggestion
  3. press 'enter' once again -> it will clear the input (and due to form validations - form isn't submitted)

But it behaves differently with the steps:
0. focus autocomplete input

  1. type any letter to display suggestions (since I use autoHighlight: true - first suggestion is highlighted/selected)
  2. press 'tab' on keyboard -> it will close suggestions and select first highlighted suggestion
  3. focus autocomplete input again
  4. clear selected value (for instance, by pressing 'backspace')
  5. type any letter again (to see suggestions and first suggestion is highlighted)
  6. press 'enter' on keyboard -> it will close suggestions and select first highlighted suggestion
  7. press 'enter' once again -> value still will be there and form successfully submitted

@Cito - at first glance, it seems like the problem with onInputChange and suggestions is being null. And first my example shows that methods onInputChange called when we press 'enter' second time (not sure if it gets called by first 'enter' tho). But second example shows that it misses the call of onInputChange and therefore input isn't cleared.

I also don't know exact reason to set suggestions to null, but I could make some guesses: not always we have static suggestions, if we have retrieved suggestions from some REST call, next time we want to check them internally they might be already invalid; this is seems like very rare case tho, but still...I don't know exact reason here as well

@Cito - What to you think if we could come up with solution for it and create PR to fix it? I was thinking as well about 'never set suggestions to null`, but maybe there is other solution.

Also would be nice to here someone from primeng team, what's their thoughts etc...

@Cito
Copy link
Contributor

Cito commented Jun 16, 2020

@MaKCbIMKo Before trying to create a fix, we need proper testing, so I have started with that.

Below I posted a unit test function that should replace the currently existing test function for forceSelection in autocomplete.spec.ts. This function tests that 1) an invalid value will be removed, 2) a valid value will be kept when the overlay is still open and 3) a valid value is also kept when the overlay is already closed. The currently existing test does only 1) and does not work properly.

I can confirm that this improved test detects the problem in this issue and that my naive fix satisfies the test and does not break any other tests.

The question remains whether there is a reason why suggestions is reset in the two places. In that case, we need a different fix and add another test for that szenario where this is required.

    it('should properly implement forceSelection', fakeAsync(() => {
      autocomplete.forceSelection = true;
      fixture.detectChanges();

      const inputEl = fixture.debugElement.query(By.css('.ui-inputtext.ui-widget'));
      inputEl.nativeElement.dispatchEvent(new Event('focus'));  
      inputEl.nativeElement.focus();
      inputEl.nativeElement.click();
      flush();
      fixture.detectChanges();

      // enter valid value
      inputEl.nativeElement.value = 'VW';
      inputEl.nativeElement.dispatchEvent(new Event('input'));
      tick(autocomplete.delay);  // wait for debouncing
      fixture.detectChanges();
      tick(250); // wait for animation showing overlay
      fixture.detectChanges();
      inputEl.nativeElement.dispatchEvent(new Event('change'));
      flush();
      fixture.detectChanges();
      // value should be kept
      expect(inputEl.nativeElement.value).toEqual("VW");

      // enter invalid value
      inputEl.nativeElement.value = 'vsa';
      inputEl.nativeElement.dispatchEvent(new Event('input'));
      tick(autocomplete.delay);  // wait for debouncing
      fixture.detectChanges();
      tick(250); // wait for animation showing overlay
      fixture.detectChanges();
      inputEl.nativeElement.dispatchEvent(new Event('change'));
      flush();
      fixture.detectChanges();
      // value should be removed
      expect(inputEl.nativeElement.value).toEqual('');

      // enter valid value
      inputEl.nativeElement.value = 'VW';
      inputEl.nativeElement.dispatchEvent(new Event('input'));
      tick(autocomplete.delay);  // wait for debouncing
      fixture.detectChanges();
      tick(250); // wait for animation showing overlay
      fixture.detectChanges();
      autocomplete.onKeydown({which: 27, preventDefault(){}}); // press escape
      fixture.detectChanges();
      tick(250); // wait for animation hiding overlay
      fixture.detectChanges();
      inputEl.nativeElement.dispatchEvent(new Event('change'));
      flush();
      fixture.detectChanges();
      // value should still be kept
      expect(inputEl.nativeElement.value).toEqual("VW");
    }));

@thornidlo
Copy link

thornidlo commented Jun 23, 2020

This is situation from #8511 before this bad fix. If you type "fra" and tab, string will stay in input, if you type "fra" slowly when suggestions are displayed and tab, input will be null.
https://stackblitz.com/edit/angular-8gfewa

There must be test, which detects situation on blur/change (only when forceSelection enabled):

  1. before suggestions show up:
  • in this case when you type text and there is no special condition (char length for trigger) and you cause blur, it must hold blur and immediately find suggestions. If there are suggestions, text in input will be not null and then blur wont pass (you must choose) or will pass and automatically do 2) - maybe this situation could be parametrized. If there are no suggestions, text in input will be null and then blur will pass.
  • in this case when you type text and there is special condition (char length for trigger) and you cause blur, text in input will be null and then blur will pass.
  1. after suggestions show up
  • in this case when you have typed text and cause blur, it must check, if text is exactly in key value (atomic, object), if yes, text will stay in input and blur will pass, otherwise text will be null and blur will pass.

@AlejandroFlorin
Copy link

AlejandroFlorin commented Aug 13, 2020

Confirming I have the same problem. With an autocomplete set to [forceSelection]="true", here is the behavior:

  • Start typing (suggestions are displayed)
  • Down Arrow to a suggestion
  • Press ENTER to select
  • Press TAB to move focus

The last step clears the selection

Note that the following works:

  • Start typing (suggestions are displayed)
  • Down Arrow to a suggestion
  • Press TAB to select
  • Press TAB to move focus

The above steps DON'T clear the selection

@mcrtricolor
Copy link

I'm having the same issue, we can't use autocomplete with this bug so we're stuck in version 9.0.0, but also facing the need to update to version 10+ because of the changes in virtual scrolling table.

It's weird that new versions are coming along but the bug is not being fixed. I suspect that this is something bigger and not a minor fix.

@Timmeeeey
Copy link

I have the same problem. It's still present in version 10.0.0-rc.4.
Hope this will be fixed soon.

@nikhil-kapoor-quo
Copy link

any update on this ?

@vinlos
Copy link

vinlos commented Sep 27, 2020

I have exactly the same issue with prime-ng v10.0.0

@brian428
Copy link
Contributor

brian428 commented Oct 2, 2020

For what it's worth, I'm using this override which seems to work with no ill effects that I've seen:

AutoComplete.prototype.onInputBlur = function( this: AutoComplete, event: KeyboardEvent ) {
  try {
     if( this.highlightOption ) {
       this.selectItem( this.highlightOption, false );
       this.cd.detectChanges();
     }
   } catch( e ) {
   }
  
  this.focus = false;
  this.onModelTouched();
  this.onBlur.emit( event );
};

@vinlos
Copy link

vinlos commented Oct 4, 2020

For what it's worth, I'm using this override which seems to work with no ill effects that I've seen:

AutoComplete.prototype.onInputBlur = function( this: AutoComplete, event: KeyboardEvent ) {
  try {
     if( this.highlightOption ) {
       this.selectItem( this.highlightOption, false );
       this.cd.detectChanges();
     }
   } catch( e ) {
   }
  
  this.focus = false;
  this.onModelTouched();
  this.onBlur.emit( event );
};

Thanks for the suggestion. It actually works!

Waiting for an upstream fix...

@bit-jkraushaar
Copy link

I have the same issue. Instead of overriding onInputBlur, I override onOverlayAnimationDone:

AutoComplete.prototype.onOverlayAnimationDone = function (event: any) {
    if (event.toState === 'void') {
        //this._suggestions = null;
    }
};

@cagataycivici cagataycivici added the Status: Pending Review Issue or pull request is being reviewed by Core Team label Nov 23, 2020
@cagataycivici cagataycivici added this to the 11.0.0-rc.2 milestone Nov 23, 2020
@yigitfindikli yigitfindikli added Type: Bug Issue contains a bug related to a specific component. Something about the component is not working and removed Status: Pending Review Issue or pull request is being reviewed by Core Team labels Nov 30, 2020
@yigitfindikli yigitfindikli added LTS-PORTABLE LTS-FIXED-10.0.6 Fixed in PrimeNG LTS 10.0.6 labels Nov 30, 2020
@yigitfindikli yigitfindikli added LTS-FIXED-9.2.1 Fixed in PrimeNG LTS 9.2.1 and removed LTS-PORTABLE labels Dec 8, 2020
@MaxiAringoli
Copy link

The same on version 11.0.0-rc.1

@Cito
Copy link
Contributor

Cito commented Dec 17, 2020

The same on version 11.0.0-rc.1

Now wonder, since it has been fixed in 11.0.0-rc.2 only.

@Cito
Copy link
Contributor

Cito commented Dec 17, 2020

Unfortunately, my tests to avoid regression (see above) have not been added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LTS-FIXED-9.2.1 Fixed in PrimeNG LTS 9.2.1 LTS-FIXED-10.0.6 Fixed in PrimeNG LTS 10.0.6 Type: Bug Issue contains a bug related to a specific component. Something about the component is not working
Projects
None yet
Development

No branches or pull requests