I have a list with an object has name
and id
properties:
[
{
"name": "open",
"id": "1"
},
{
"name": "inprogress",
"id": "2"
},
{
"name": "close",
"id": "3"
}
]
And using MatSelect with *ngFor to iterate over an array and bind the current status with select using [(ngModel)]
.
Expected output:
If the current status is inprogress
then disable open
option
StackBlitz Example
It is possible to disable the entire select or individual options in the select by using the disabled property on the <select> or <mat-select> and the <option> or <mat-option> elements respectively.
which out put looks like: It fades out the text and the lining below get changes, is it possible to make it readonly? You can replace the mat-select form field with a input box and bind input box data with mat-select data.
Create Select using <mat-select> To add elements to select option, we need to use <mat-option> element. To bind value with <mat-option> , we need to use value property of it. The <mat-select> has also value property to bind selected value to keep it selected. We need to use <mat-select> inside <mat-form-field> element.
The example doesn't work properly because selected
is bound with [value]="topping.id"
, but the logic uses selected.id
which doesn't exist except on startup because you are initializing selected
with a topping object.
Also, the logic [disabled]="topping.id < selected.id"
is possibly flawed because it also disables inprogress
when close
is selected - you might want that - I'm not sure - but you only said you wanted to disable open
when inprogress
is selected.
Either use [value]="topping"
:
<mat-form-field>
<mat-select placeholder="Toppings" [(ngModel)]="selected" [formControl]="toppings">
<mat-option *ngFor="let topping of list" [value]="topping" [disabled]="selected.id === '2' && topping.id === '1'">{{topping.name}}</mat-option>
</mat-select>
</mat-form-field>
Or change the logic and initialization of selected
:
selected: any = '2';
<mat-form-field>
<mat-select placeholder="Toppings" [(ngModel)]="selected" [formControl]="toppings">
<mat-option *ngFor="let topping of list" [value]="topping.id" [disabled]="selected === '2' && topping.id === '1'">{{topping.name}}</mat-option>
</mat-select>
</mat-form-field>
Update for Angular v6/7 and later
Use [(value)]
instead of [(ngModel)]
. Support for using the ngModel input property and ngModelChange event with reactive form directives has been deprecated in Angular v6 and is removed in Angular v7.
if user can select multiple options we dont really need ngModel as well, below is my solution to disable certain option on select of some different option in angular material mat-select.
//toppings is a form control name for mat-select
this.toppings.valueChanges.subscribe((selection) => {
this.selected = '';
//includes because in case we are using multi selection we will receive selection as array
if(selection.includes('inprogress')) // if index instead of name use index value
this.selected = 'inprogress' // selected is globally defined variable
)}
checkUserSelection(topping){
if(this.selected === 'inprogress' && topping === 'open')"{
return true;
}
return false
}
----------------- Html Code ---------------------
<mat-form-field>
<mat-select placeholder="Toppings"
[formControl]="toppings">
<mat-option *ngFor="let topping of list"
<!-- Added null check for the topping field -->
[value]="topping?.id"
[disabled]="checkUserSelection(topping)"
</mat-option>
</mat-select>
I did it like this in HTML
<mat-select [(ngModel)]="algorithm">
<mat-option
*ngFor="let algo of algos"
[value]="algo.name"
[disabled]="!algo.allow">
{{ algo }}
</mat-option>
</mat-select>
and in ts
algos = ['FIFO', 'LIFO'];
somefunctionCall(){ // Map the Array
const fifoAllowed = false;
isAllowed = (algo) => algo === 'FIFO' ? fifoAllowed : true;
this.algos = this.algos.map(a => ({ name: a, allow: isAllowed(a) })
)}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With