H. Soares
H. Soares

Reputation: 203

How can I populate an array with selected values from dropdown in Angular?

I'm trying to populate an array with all selected values from a mat-select dropdown. The goal is to create an input field for every selected value like this:

Image

I thought about calling a method every time I select a value, but I'm not really sure on what to do next... This is what I have:

MyComponent.component.html

<mat-form-field>
  <mat-select placeholder="Products" [formControl]="products" multiple>
    <mat-option *ngFor="let product of productsList">{{ product }}</mat-option>
  </mat-select>
</mat-form-field>

MyComponent.component.ts

import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'm-mycomponent',
  templateUrl: './mycomponent.component.html',
  styleUrls: ['./mycomponent.component.scss']
})
export class MyComponent implements OnInit {

  products = new FormControl();
  productsList = ['Prod1', 'Prod2', 'Prod3', 'Prod4', 'Prod5', 'Prod6'];
  productsToReturn = [];

  constructor() { }

  ngOnInit() {
  }

  fillProductsToReturn(product){
    if(!this.productsToReturn.includes(product)){
      this.productsToReturn.push(product);
    }
  }
}

How can I call a method in the html file and populate the productsToReturn array?

Thanks!

Upvotes: 1

Views: 9274

Answers (3)

H. Soares
H. Soares

Reputation: 203

I solved my problem... I made the following changes based on j4rey's answer

MyComponent.component.html

<mat-form-field>
  <mat-select placeholder="Products" [formControl]="products" multiple>
    <mat-option *ngFor="let product of productsList" [value]="product" (onSelectionChange)="onSelectionChange(product)">{{ product }}</mat-option>
  </mat-select>
</mat-form-field>

<div class="row" *ngFor="let product of productsToReturn">
  <div class="col-4">
    <mat-form-field>
      <input matInput disabled="disabled" [value]="product">
    </mat-form-field>
  </div>
  <div class="col-2">
    <mat-form-field class="prod-qty">
      <input matInput step="1" value="1" min="1" type="number">
    </mat-form-field>
  </div>
</div>

MyComponent.component.ts

import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'm-mycomponent',
  templateUrl: './mycomponent.component.html',
  styleUrls: ['./mycomponent.component.scss']
})
export class MyComponent implements OnInit {

  products = new FormControl();
  productsList = ['Prod1', 'Prod2', 'Prod3', 'Prod4', 'Prod5', 'Prod6'];
  productsToReturn = [];

  constructor() { }

  ngOnInit() { }

  onSelectionChange(product: string) {

    if (!this.productsToReturn.includes(product)) {
      this.productsToReturn.push(product);
    } else {
      let index = this.productsToReturn.indexOf(product);
      this.productsToReturn.splice(index, 1);
    }
  }
}

Upvotes: 0

j4rey
j4rey

Reputation: 2677

You didn't specify when you want to access the selected objects.

Its simple if you want to access it when the form is submitted, like on a click of a button. Then you can use this.products.value to get the selected options.

If you want it at the time of selection, then you can bind to selectionChange() event

<mat-select placeholder="Products" [formControl]="products" multiple (selectionChange)="onSelectionChange($event) >

then in ts file you can get the selected options

onSelectionChange(e){
    console.log(e.value); //or
    console.log(this.toppings.value);
}

Upvotes: 2

Fabian K&#252;ng
Fabian K&#252;ng

Reputation: 6183

You don't need to do this manually. Just bind the value property of the mat-option to the current product string and your FormControl will contain the array of selected options.

Template

<mat-form-field>
  <mat-select placeholder="Products" [formControl]="products" multiple>
    <mat-option *ngFor="let product of productsList" [value]="product">{{ product }}</mat-option>
  </mat-select>
</mat-form-field>

And in your component you can access the selected options via this.products.value.

Here is a minimal stackblitz with a working solution. The selected values are directly displayed next to the mat-select.

Upvotes: 1

Related Questions