angularangular-materialdropdownmat-select

Angular order of selected option in multiple mat-select


I want to be able to keep track on the order of selected options in multiple mat-select. How can I implement this use case?

Let's say first I select 'Onion' then 'Mushroom' and then 'Pepperoni'. I want to be able to get from mat-select the selected options in this order ['Onion', 'Mushroom', 'Pepperoni']. And if I then deselect 'Mushroom' and select 'Extra cheese', I want to get the selected options in an array like ['Onion', 'Pepperoni', 'Extra cheese'].

enter image description here


Solution

  • You could subscribe to MatSelect's optionSelectionChanges. It emits MatOptionSelectionChange objects. On this stream you can use rxjs's scan.

    HTML

    <mat-form-field appearance="fill">
      <mat-label>Toppings</mat-label>
      <mat-select multiple #toppingSelection>
        <mat-option *ngFor="let topping of toppingList" [value]="topping"
          >{{topping}}</mat-option
        >
      </mat-select>
    </mat-form-field>
    

    TS

    export class SelectMultipleExample implements AfterViewInit {
      @ViewChild('toppingSelection')
      toppingSelection: MatSelect;
    
      toppingList: string[] = [
        'Extra cheese',
        'Mushroom',
        'Onion',
        'Pepperoni',
        'Sausage',
        'Tomato',
      ];
    
      ngAfterViewInit() {
        // TODO: unsubscribe
        this.toppingSelection.optionSelectionChanges
          .pipe(
            scan((acc: string[], change: MatOptionSelectionChange) => {
              if (change.source.selected) {
                return [...acc, change.source.value];
              } else {
                return acc.filter((entry) => entry !== change.source.value);
              }
            }, [])
          )
          .subscribe((selectedValues: string[]) => console.log(selectedValues));
      }
    }
    

    Stackblitz: https://stackblitz.com/edit/angular-baamvq?file=src/app/select-multiple-example.ts