components
components copied to clipboard
autocomplete does not stick when scrolling
Bug, feature request, or proposal:
Bug
What is the expected behavior?
The autocomplete drop down list should stick to the bottom of input element when scrolling
What is the current behavior?
The drop down list is sticky to position on the screen, it will not follow the input element position when scrolling
What are the steps to reproduce?
What is the use-case or motivation for changing an existing behavior?
Which versions of Angular, Material, OS, TypeScript, browsers are affected?
Windows 10 64 bit Chrome Version 64.0.3282.167 (Official Build) (64-bit) Angular 5.1.2 Angular Material 5.0.2 TypeScript 2.7.1
Is there anything else we should know?
That's because, by default, Material won't listen to scroll events on all elements. Is your main scroll container something different than the body
?
@crisbeto yes, the scroll container is actually mat-sidenav-content element, descendant of the body element, which has overflow: auto
set into it. Is there a way to configure the event listener to listen to the element of choosing?
Usually you'd have to add the cdkScrollable
attribute to your scroll container so the CDK can pick it up, however the sidenav container has it set up already. Can you try adding the ScrollDispatchModule
from @angular/cdk/scrolling
to your imports?
I have noticed that the mat-select does not have this issue, as it blocks scroll action when the panel is opened.
May be autocomplete should follow the same approach.
Having same use case as @weijyewang with ScrollDispatchModule
inported. As @Karankang007 mentioned blocking scroll as mentioned here would be fair enough temporary fix. Tried it with MAT_AUTOCOMPLETE_SCROLL_STRATEGY
, no luck.
Having same issue when the main scroll container is content of dialog popup (mat-dialog-content). Ideally it should work similar to mat-select.
I was with the same problem, I used the workaround described in this issue:
https://github.com/angular/material2/issues/7897
@israelpereira #7897 did help. On using cdkScrollable
the dropdown section is sticking to the input, but it is no more contained within the dialog content section.
Reproduced on stackblitz. Click on the 'open popup' button and scroll the dialog section.
I think the ideal solution would be to disable scroll when the dropdown is opened as suggested by @Karankang007 in comment.
I had the same issue.. to solve it.. I found something called ScrollStrategy and I used the following code:
export function scrollFactory(overlay: Overlay): () => CloseScrollStrategy {
return () => overlay.scrollStrategies.close();
}
@NgModule({
imports: [modules],
exports: [modules],
providers: [
{ provide: MAT_AUTOCOMPLETE_SCROLL_STRATEGY, useFactory: scrollFactory, deps: [Overlay] }
]
})
export class AppModule {}
It closes the autocomplete box when it identifies the scroll outside the autocomplete.
hope it helps.
thanks @israelpereira. this helps. The dropdown overlay closes on scroll. The only side effect is that to open the dropdown overlay once again, the focus has to be taken out of the autocomplete input and back into it.
Behaviour similar to mat-select could be achieved if BlockScrollStrategy
worked, but sadly it doesn't.
Welcome, I had this issue too...
@ViewChild('searchInput', { read: MatAutocompleteTrigger })
triggerAutocompleteInput: MatAutocompleteTrigger;
openAutocompletePanel(){
this.triggerAutocompleteInput.openPanel();
}
//html
<input (click)="openAutocompletePanel()" />
add this code to the component and put the (click)="openAutocompletePanel()" in the input field, it will solves the problem.
I don't know if it is the best solution, probably not, but worked .. I was losing so much time on it..
@israelpereira thanks for MatAutocompleteTrigger.openPanel()
for opening the dropdown section
Solution:
import { ScrollingModule } from '@angular/cdk/scrolling';
Locate the Modal that has this
<div class="full-page-takeover" cdkScrollable> {{ modal content }} </div>
This worked for me.
just add below code to your autocomplete function and it will work
appendTo: $('#tag').parent(),
this will stick the autocomplete list to its parent textbox
Is there any solution for mat-autocomplete not sticking to the input when scrolled.
Note: None of the given solution worked for me
@omaracrystal solution work for me, but then , i have problem with z-index.
i have the same problem
I'm having the same issue when I used autocomplete inside mat-side-nav
Hey @weijyewang, @fzs1994 I'm in the same scenario, did you manage to solve it ? None of the given solution worked for me.
@matiasfs12 I just added cdkScrollable
to the parent element just like what @crisbeto and @omaracrystal suggested. I am happy to help if you can provide a stackblitz https://stackblitz.com/edit/angular
@matiasfs12 I just added
cdkScrollable
to the parent element just like what @crisbeto and @omaracrystal suggested. I am happy to help if you can provide a stackblitz https://stackblitz.com/edit/angular
That doesn't work for me since i'm not using mat-sidenav-container, nor mat-sidenav-content, actually i'm putting the cdkScrollable on mat-sidenav tag, but the scroll listener it's not even firing up because there is an intermediate element mat-drawer-inner-container which actually scroll up/down the content, and i cannot disable the scroll in this element with CSS.
In any case, i will try to do a stackblitz, thanks in advance!
@matiasfs12 you just have to set cdkScrollable
to the parent container that is scrollable. It can be any elements like div
. If mat-sidenav
is giving you the problem maybe you can implement a sidenav on your own? This is how I use cdkScrollable
in my code
Hey @weijyewang , Finally managed to get it working, I had to append a <mat-sidenav-content>
into <mat-sidenav>
, setting cdkScrollable
on it, and some hacky CSS styles, thx mate
All the above solutions not worked for me, Please anyone has the best solution. I have used Angular material 8.2.3 version with Angular 8.
The above solution works. you just have to find the class where you are defining the overflow property to scroll this will give you the element which is controlling the scrolling of the page. Then add cdkScrollable to that element. And add this in your module. since ScrollDispatchModule has been renamed to ScrollingModule. import { ScrollingModule } from '@angular/cdk/scrolling';
Nothing worked for me.
@panyann If you have a autocomplete within a mat dialog - this is how I solved this issue.
- Wrap all your content with
<mat-dialog-content></mat-dialog-content>
- Place the directive cdkScrollable on that ^
<mat-dialog-content cdkScrollable>...</mat-dialog-content>
- In scss target .mat-dialog-content and give it a max-height of 100vh
.mat-dialog-content {
width: 100%;
height: 100%;
max-height: 100vh;
}
@omaracrystal I don't have a dialog and cdkScrollable seems to not work whatever I do! So I made a workaround and I will share with everyone...
First of all we need to be able to use autoComplete methods, so we must take this control from the view. Add the id: #autoCompleteInput
<input
#autoCompleteInput
type="text"
class="form-control"
matInput
[matAutocomplete]="auto"
formControlName="country"
(input)="filterCountries($event.target.value)"
/>
In the component:
@ViewChild('autoCompleteInput', { read: MatAutocompleteTrigger })
autoComplete: MatAutocompleteTrigger;
Now we have autoComplete as a variable. Next we need a scrolling event:
ngOnInit(): void {
window.addEventListener('scroll', this.scrollEvent, true);
}
And finally add a function to the component:
scrollEvent = (event: any): void => {
if(this.autoComplete.panelOpen)
// this.autoComplete.closePanel();
this.autoComplete.updatePosition();
};
You can set it to close the panel or update its position. Problem solved, but is not perfect if you have a lot of these autoComplete elements.
I can only wonder why this position update does not happen automatically and we all need to make idiots out of ourselves and waste time for finding solution...
Yes this solved the problem. Thank you @panyann
Thank you @panyann
This is exactly what I wanted