Tech Learner
Tech Learner

Reputation: 1317

How to adjust mat-select height to fit its items?

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

Answers (1)

Eliseo
Eliseo

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>

See another stackblitz

Upvotes: 4

Related Questions