Reputation: 1317
In Angular material, I need to increase the height, start and end position of a mat-select dynamically based on list of items. For example, list of options may range from none to 100. So the height should fit to the content and also should not display outside of my application screen.
I used below style but when I have more items, first few items are not getting displayed in screen. If I use margin-top, it breaks the design in another dropdown which is located on top position of my screen. So irrespective of dropdown position, it should display inside my screen with maximum height.
Can any help me to fix this in CSS?
.mat-select-panel {
max-height: 95vh !important;
}
Upvotes: 2
Views: 5106
Reputation: 57929
you can use the event (openedChange) to change the heigth of the select-panel using Renderer2
Thats, in .html
<mat-select #select (openedChange)="changeHeight($event,select)">
<mat-option>...</mat-option>
<mat-option>...</mat-option>
</mat-select>
In your .ts, first inject in constructor Renderer2
constructor(private renderer:Renderer2){}
And your function changeHeight
changeHeight(event:any,element:any)
{
if (event)
{
//get the height of the "screen"
const height = window.innerHeight||
document.documentElement.clientHeight||
document.body.clientHeight;
//the max-height will be the height of the screen - the position of pannel
// - 10 px (you can change this last one)
this.renderer.setStyle(element.panel.nativeElement,
'max-height',
(height-10-element.panel.nativeElement.getBoundingClientRect().y)+'px')
}
}
You can see in this stackblitz
You can also make a directive
@Directive({
selector: "[autosize]"
})
export class AutosizeDirective {
@HostListener("openedChange", ["$event"])
changeHeight(event: any) {
if (event) {
const height =
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
this.renderer.setStyle(
this.select.panel.nativeElement,
"max-height",
(height -10 -this.select.panel.nativeElement.getBoundingClientRect().y) +"px");
}
}
constructor(@Host() private select: MatSelect, private renderer: Renderer2) {}
}
And use like
<mat-select autosize>
<mat-option *ngFor="let food of foods" [value]="food.value">
{{food.viewValue}}
</mat-option>
</mat-select>
Upvotes: 4