简体   繁体   中英

How to load angular material select mat-option list below the select field correctly.

I am using the material select element mat-select in my application. I want to load the option list just below the select field, like a regular select box and not as a overlay style give. For that I have applied the below style to given select element.

             <mat-form-field>
                  <mat-select [formControlName]="input1">
                        <mat-option>None</mat-option>
                        <mat-option *ngFor="let opt_value of  input1.enumNames; let i = index" value="{{input1.enum[i]}}" >{{opt_value}}</mat-option>
                  </mat-select>

             </mat-form-field>   

Use disableOptionCentering attribute of mat-select . https://material.angular.io/components/select/api

I think the position of the mat-option list is dynamically determined. I used panelClass="testClass" and disableOptionCentering properties in mat-select .

<mat-select placeholder="Select a movie" disableOptionCentering panelClass="testClass">
   <mat-option *ngFor="let movie of movies" [value]="movie">
     {{movie}}
   </mat-option>
</mat-select>

Also, added this style class in my style.scss file:

.testClass{
  margin-top: 35px;
  margin-bottom: 30px;
}

It worked fine for my app!

This experience is prescribed by Material Design .

Menus are positioned over their emitting elements such that the currently selected menu item appears on top of the emitting element.

The first question you should ask yourself is "why do I want/need to change that experience?" For a Material Design application, it is the correct user experience.

You can modify the mat-select-panel class's position as already suggested, but there are three technical problems with that approach, in addition to being against Material Design guidelines.

First, the panel is dynamically inserted into the DOM when the list is opened, and it is not a child of it's mat-select element, so if you have more than one select component, they will all be affected the same way. However, you can get around that problem by using the panelClass property of mat-select .

Second, the "offset" amount that would be needed depends on the size of the panel (related to number of items and window size) and the index of the selected item. Adjusting the position by a fixed a distance will not produce the desired result all of the time. You would need to know specifically how many other items appear above the selected item, and multiply that number by the offset amount for one item (eg 48px - the standard height of selection list items).

Third, the position of the panel is dynamically determined so that when the select field is near the bottom of the window such that there is not enough room to display it below the field, the panel is displayed above the field instead. So adjusting the position of the panel downward will only work when there is room for the panel below the field. While you might be able to get away with that most of the time, it is nothing more than a hack that will probably fail eventually.

If you can solve all of those problems in a predictable, reliable fashion (not a hack), please post your code here - I'm sure others would benefit from it.

A better solution might be to create your own custom select control based on the menu component which allows for custom positioning.

You can modify your CSS to use a margin:

.mat-select-panel {
  margin-top: 45px;
}

It works fine for me in this example .

in your: app.module.ts<\/strong>

 import {MAT_SELECT_CONFIG} from '@angular/material/select'; // <---- import this
     
    providers: [
       { provide: MAT_SELECT_CONFIG, useValue: { disableOptionCentering:'false'}}  // <---- and set the disableOptionCentering in false
    ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM