Let me try to explain a little bit my situation...
I have a <form>
that contains a FormArray
. Every FormArray
group has the "food" control
and each of them is a <select>
.
All the selects are populated by a single array
.
What I'm trying to achieve is:
The options of each select must be exclusively selected... in other words,
the result in FormArray
must contain only unique elements.
My actual code:
HTML:
<form [formGroup]="formGroup">
<div>
<button mat-raised-button color="primary" type="button" (click)="addItem()">
<mat-icon>add</mat-icon>Add food
</button>
</div>
<ng-container
formArrayName="items"
*ngFor="let item of formArray.controls; index as i"
>
<mat-card>
<mat-card-title>
<h3>Item nÂș {{ i + 1 }}</h3>
<button
mat-mini-fab
color="warn"
matTooltip="Remove"
type="button"
(click)="removeItem(i)"
>
<mat-icon>delete</mat-icon>
</button>
</mat-card-title>
<mat-card-content [formGroupName]="i">
<mat-select
formControlName="food"
name="food"
placeholder="Favorite food"
>
<mat-option
[value]="food.value"
*ngFor="let food of foods"
>
{{ food.viewValue }}
</mat-option>
</mat-select>
</mat-card-content>
</mat-card>
</ng-container>
</form>
Component:
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'select-overview-example',
templateUrl: 'select-overview-example.html',
})
export class SelectOverviewExample {
readonly foods: readonly Food[] = [
{ value: 'steak-0', viewValue: 'Steak' },
{ value: 'pizza-1', viewValue: 'Pizza' },
{ value: 'tacos-2', viewValue: 'Tacos' }
];
readonly formArray = this.formBuilder.array([]);
readonly formGroup = this.formBuilder.group({
items: this.formArray
});
constructor(private readonly formBuilder: FormBuilder) {}
addItem(): void {
this.formArray.push(
this.formBuilder.group({
food: ''
})
)
}
removeItem(index: number): void {
this.formArray.removeAt(index);
}
}
I want to know which is the best option to achieve this.
So far I think in 3 options:
1 - Disable options that have already been selected in another <select>
;
2 - Create a custom validator and tell the user that he can't select an option in 2 or more selects.
3 - Completely remove the selected options from other selects.
I prefer the 1st. option, however I can't find a way to do this. Can someone show me something to start? I hope the question is clear enough.
Here's a demo.
Just build my own solution:
I created a method to check if it should be disabled:
So, in template...
DEMO
Isn't it an optimal solution? Maybe... if you have another option to do this, let me know.