If there are a small number of inputs you require this for, I would recommend a different approach.
Swap out the select
for a readonly input
, and restore the select
when required. You can do this by togging a boolean property (in the examples below, this property is called isReadMode
)
The primary benefit of doing it this way is avoiding cross-platform / browser incompatibility of CSS and/or device events, as you'd be leaving that to Angular/HTML to handle appropriately.
You can add an icon and style it to look like a select
, but in my experience, it's sufficient to simply use a readonly input
"as is".
Documentation for input with an icon can be found here.
Angular pre-17 example without an icon:
<mat-form-field>
<mat-label>Choose an option</mat-label>
<ng-container *ngIf="isReadMode; else interactiveSelectTemplate">
<!-- Can use NG Model as well or simply double curly braces. -->
<input matInput readonly [value]="form.get('yourFormField')?.value">
</ng-container>
<ng-template #interactiveSelectTemplate>
<mat-select formControlName="yourFormField">
<mat-option **ngFor="let opt of options" [value]="opt.value">{{opt.display}}</mat-option>
</mat-select>
</ng-template>
</mat-form-field>
Documentation for Angular 17+ control flow (use of @if
) can be found here.
Angular 17+ example with an icon:
<mat-form-field>
<mat-label>Choose an option</mat-label>
@if (isReadMode) {
<!-- Can use NG Model as well or simply double curly braces. -->
<input matInput readonly [value]="form.get('yourFormField')?.value">
} @else {
<mat-select formControlName="yourFormField">
@for (opt of options; track opt.value) {
<mat-option [value]="opt.value">{{opt.display}}</mat-option>
}
</mat-select>
}
<mat-icon *ngIf="isReadMode" matSuffix>arrow_drop_down</mat-icon>
</mat-form-field>
Note: In Angular 17+ the carrot down icon is in the same scope as the
mat-form-field
and with its own *ngIf
. This can be adjusted
where the @if
/@else
contains a whole <mat-form-field>
to include the icon within the @if
condition at the cost of lengthy
code.
If there are many fields, it may be best to create a wrapper component to reduce the duplicate code or to use one of the other solutions proposed.
select
selector in HTML. [That has no attribute either of readonly][1]. [1]: developer.mozilla.org/en-US/docs/Web/HTML/Element/select – ConvertitepanelClass
worked for me – Preferential