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 panel doesn't pop up when triggering focus on the input programatically #3106

Closed
fxck opened this issue Feb 15, 2017 · 29 comments · Fixed by #21081
Closed

autocomplete panel doesn't pop up when triggering focus on the input programatically #3106

fxck opened this issue Feb 15, 2017 · 29 comments · Fixed by #21081
Assignees
Labels
area: material/autocomplete P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@fxck
Copy link
Contributor

fxck commented Feb 15, 2017

see https://gist.run/?id=19eec6a0d5c69d65dbb847b12009ca9f, it starts working only after you do it the second time

@kara

@kara kara self-assigned this Feb 15, 2017
@kara kara added the P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent label Feb 15, 2017
@willshowell
Copy link
Contributor

willshowell commented Feb 23, 2017

I'm not at all familiar with using ngZone, but it seems like this change fixes it

autocomplete.ts


/** Panel should hide itself when the option list is empty. */
_setVisibility() {
  // Promise.resolve().then(() => this.showPanel = !!this.options.length);
  this.zone.run(() => this.showPanel = !!this.options.length);
}

@bergben
Copy link

bergben commented Jun 6, 2017

Is there any workaround for this for now?

@willshowell
Copy link
Contributor

willshowell commented Jun 6, 2017

The issue actually seems to be that clicking a button to focus the autocomplete triggers an _outsideClickStream event just after it has been opened, thus causing it to immediately close.

As a workaround, you can use a setTimeout to focus it after the outside click event fires.

http://plnkr.co/edit/cKYxnL9f8hV2Uklucd5d?p=preview

@willshowell
Copy link
Contributor

Alternatively use stopPropagation() on the click event

http://plnkr.co/edit/m4W7zAGulSaxhPqqlpzp?p=preview

@fxck fxck mentioned this issue Jun 10, 2017
30 tasks
@willshowell
Copy link
Contributor

Here's an updated plunker https://plnkr.co/edit/gyarTLKwyt97CX9304Fd?p=preview

@bruteforce
Copy link

Below code did the trick for me assuming focus is already on input field.

import { MdAutocompleteTrigger} from '@angular/material';

@ViewChild(MdAutocompleteTrigger) trigger;

this.trigger._onChange("");
this.trigger.openPanel();

@mpolutta
Copy link

mpolutta commented Apr 2, 2018

Combined willshowell and bruteforce solutions to solve for our 508 compliance scenario. Clear button is another scenario:
openAutoSearchPanel() {
if (this.searchText.length === 0) {
this.autoSearchInputTrigger._onChange('');
this.autoSearchInputTrigger.openPanel();
}
}
clearSearchText() {
console.log('>>> clearing searchText');
this.searchText = '';
/// hack: Another reported workaround - Allow the ClickStream to finish executing via setTimeout.
/// #3106
setTimeout(() => {
this.autoSearchInput.nativeElement.focus();
this.openAutoSearchPanel();
});
}

@Charius
Copy link

Charius commented Apr 28, 2018

yeah, got the same issue while implement custom field with autocomplete, timeout works, but this is pretty weird

@maxterry
Copy link

Any update on this...?

@tombolador
Copy link

+1, any updates?

@mischkl
Copy link

mischkl commented Sep 17, 2018

This problem also affects chiplist inputs with autocomplete. 😢

@RajendrasinhParmar
Copy link

Is there any workaround or fix for this issue?
I'm having a dropdown that fetches data dynamically from the server. When I click on the chip-list field it doesn't open autocomplete list until I input any character in that.

@hukacode
Copy link

This problem also affects chiplist inputs with autocomplete. 😢

Me too, do you have any workaround?

@mischkl
Copy link

mischkl commented Sep 24, 2018

I got it working with the following:

<input (focus)="onFocus()" ... >
@ViewChild(MdAutocompleteTrigger) trigger;

onFocus() {
  this.trigger._onChange(""); 
  this.trigger.openPanel();
}

@RajendrasinhParmar
Copy link

Thank you for response. I'll try this solution and will check if this works.

Just for a note that I'm fetching the list from REST API.

@hukacode
Copy link

Thanks @mischkl
I changed to (click) and it's worked.

Regards,
Huka

@RajendrasinhParmar
Copy link

Thank you @mischkl 👍 that solution worked 😄

@ozgursarikamis
Copy link

I got it working with the following:

<input (focus)="onFocus()" ... >
@ViewChild(MdAutocompleteTrigger) trigger;

onFocus() {
  this.trigger._onChange(""); 
  this.trigger.openPanel();
}

great! thanks

@omaracrystal
Copy link

@ViewChild(MdAutocompleteTrigger) trigger;

Is there any other part missing from this? It's not working for me :(

@lucas-sesti
Copy link

Hey, im trying to use the MatAutocompleteTrigger and openPanel, but, the function openPanel is undefined... how can i open the open from trigger?

@thematho
Copy link

@lucas-sesti this works for me:

@ViewChild(MatAutocompleteTrigger, { static: true }) trigger: MatAutocompleteTrigger;
// ****
 onClick(){
      this.trigger.openPanel();
} 

@PanchakshariPM
Copy link

import { MatAutocompleteTrigger } from '@angular/material/autocomplete';

Is the above import correct?

@idotj
Copy link

idotj commented Sep 22, 2020

Quick fix in case you have more than 1 <mat-autocomplete> in your component:

In your .html

<input (focus)="onFocus(0)" ... >
<input (focus)="onFocus(1)" ... >
<input (focus)="onFocus(2)" ... >

In your .ts

import {ViewChildren, QueryList} from '@angular/core';
import {MatAutocompleteTrigger} from '@angular/material/autocomplete';

@ViewChildren(MatAutocompleteTrigger) autoComplete: QueryList<MatAutocompleteTrigger>;

onFocus(value){
this.autoComplete['_results'][value]._onChange('');
this.autoComplete['_results'][value].openPanel();
}

Still this is a patch, in my case I discovered time after, that the problem was how data arrived after the first filter was executed. So I didn't use this solution anymore.

Here the link where another developer had the same problem.
I hope will help someone:
https://stackoverflow.com/questions/52536382/how-to-show-autocomplete-options-on-focus

@marcusshepp
Copy link

Will this ever get fixed?

crisbeto added a commit to crisbeto/material2 that referenced this issue Nov 18, 2020
… programmatically

Each autocomplete has a `click` listener on the body that closes the panel when the
user has clicked somewhere outside of it. This breaks down if the panel is opened
through a click outside of the form field, because we bind the listener before the
event has bubbled all the way to the `body` so when it does get there, it closes
immediately.

These changes fix the issue by taking advantage of the fact that focus usually moves
on `mousedown` so for "real" click the input will have already lost focus by the time
the `click` event happens.

Fixes angular#3106.
@crisbeto crisbeto self-assigned this Nov 18, 2020
@Lms24
Copy link

Lms24 commented Jul 2, 2021

How is this bug still open? This is a seriously annoying bug which requires an annoying workaround when used together with reactive forms.

crisbeto added a commit to crisbeto/material2 that referenced this issue Aug 2, 2021
… programmatically

Each autocomplete has a `click` listener on the body that closes the panel when the
user has clicked somewhere outside of it. This breaks down if the panel is opened
through a click outside of the form field, because we bind the listener before the
event has bubbled all the way to the `body` so when it does get there, it closes
immediately.

These changes fix the issue by taking advantage of the fact that focus usually moves
on `mousedown` so for "real" click the input will have already lost focus by the time
the `click` event happens.

Fixes angular#3106.
@KissBalazs
Copy link

This bug is still present, and makes testing with Harness quite difficult.

This code:

    const inputField = await loader.getHarness(MatAutocompleteHarness.with(
      { selector: '#autocompleteInput' }));
    await inputField.focus();
    const options = await inputField.getOptions();
    
    expect(options.length).toBeGreaterThan(0);

will fail in roughly half of the time, as the panel gets closed immediatly in those cases.

@crisbeto
Copy link
Member

There's a pending PR that should make the autocomplete harness a bit more consistent in unit tests #23795.

crisbeto added a commit to crisbeto/material2 that referenced this issue Jan 3, 2022
… programmatically

Each autocomplete has a `click` listener on the body that closes the panel when the
user has clicked somewhere outside of it. This breaks down if the panel is opened
through a click outside of the form field, because we bind the listener before the
event has bubbled all the way to the `body` so when it does get there, it closes
immediately.

These changes fix the issue by taking advantage of the fact that focus usually moves
on `mousedown` so for "real" click the input will have already lost focus by the time
the `click` event happens.

Fixes angular#3106.
andrewseguin pushed a commit that referenced this issue Feb 22, 2022
… programmatically (#21081)

Each autocomplete has a `click` listener on the body that closes the panel when the
user has clicked somewhere outside of it. This breaks down if the panel is opened
through a click outside of the form field, because we bind the listener before the
event has bubbled all the way to the `body` so when it does get there, it closes
immediately.

These changes fix the issue by taking advantage of the fact that focus usually moves
on `mousedown` so for "real" click the input will have already lost focus by the time
the `click` event happens.

Fixes #3106.

(cherry picked from commit c0ed5ce)
andrewseguin pushed a commit that referenced this issue Feb 22, 2022
… programmatically (#21081)

Each autocomplete has a `click` listener on the body that closes the panel when the
user has clicked somewhere outside of it. This breaks down if the panel is opened
through a click outside of the form field, because we bind the listener before the
event has bubbled all the way to the `body` so when it does get there, it closes
immediately.

These changes fix the issue by taking advantage of the fact that focus usually moves
on `mousedown` so for "real" click the input will have already lost focus by the time
the `click` event happens.

Fixes #3106.
@mischkl
Copy link

mischkl commented Feb 22, 2022

Glad to see it finally got fixed! 🥳 Thanks @andrewseguin

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Mar 25, 2022
forsti0506 pushed a commit to forsti0506/components that referenced this issue Apr 3, 2022
… programmatically (angular#21081)

Each autocomplete has a `click` listener on the body that closes the panel when the
user has clicked somewhere outside of it. This breaks down if the panel is opened
through a click outside of the form field, because we bind the listener before the
event has bubbled all the way to the `body` so when it does get there, it closes
immediately.

These changes fix the issue by taking advantage of the fact that focus usually moves
on `mousedown` so for "real" click the input will have already lost focus by the time
the `click` event happens.

Fixes angular#3106.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: material/autocomplete P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet