Solution 1 :

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

Problem :

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;
  }

Comments

Comment posted by Tech Learner

Your code working perfectly for setting the height. Is it possible to set margin top using setStyle?

Comment posted by Eliseo

Renderer2 allow us use setStyle with all we want -you can use setStyle severals times on the same element

Comment posted by Tech Learner

Receiving error Cannot read property ‘nativeElement’ of undefined if I set margin-top

Comment posted by Eliseo

I just write

Comment posted by Tech Learner

Could you please tell me if I can use same logic for multiple mat-select. Currently I am using same code for multiple mat-select. This could be the possible reason for error.

By

Leave a Reply

Your email address will not be published. Required fields are marked *