Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preselecting multiple values for mat-select - Angular 6

I'm trying to preselect multiple options in a mat-select. So far I'm not able to achieve this.

Here is the HTML file:

<mat-dialog-content [formGroup]="form">
   <mat-form-field>
     <mat-select placeholder="participants" formControlName="participants"  multiple>
         <mat-option *ngFor="let participant of participants" [value]="participant">{{participant}}</mat-option>
     </mat-select>
    </mat-form-field>
</mat-dialog-content>

Here is the controller:

export class EventViewModalComponent implements OnInit {
  form: FormGroup;
  calendarEvent: CalendarEvent;
  participants = [];

  constructor(private fb: FormBuilder,
    private participantService: ParticipantService,
    @Inject(MAT_DIALOG_DATA) event: CalendarEvent) 
    { 
    this.form = fb.group({
      title: [event.title, Validators.required],
      location: [event.meta.location, Validators.required],
      description: [event.meta.description, Validators.required],
      start: [event.start, Validators.required],
      end: [event.end, Validators.required],
      participants: [this.participants, Validators.required]
    });
    this.calendarEvent = event;
  }

  ngOnInit() {
    this.participantService.getAll().subscribe(data =>{
      for(let i = 0; i < data['length']; i++){
        this.participants.push(data[i]['name']);
      }
    })
  }
}

This currently selects all the values per default. Here's a screenshot of how it looks currently: enter image description here

What I'm trying to achieve is having only Cindy and Jim preselected like this:

enter image description here

How can I achieve this? I've read through several SO questions and wasn't successful. Any help is appreciated

like image 404
Rana Avatar asked Nov 27 '18 02:11

Rana


2 Answers

With Angular6+ there is a deprecation warning when you have both a formControl and [(ngModel)]

It looks like you're using ngModel on the same form field as formControl. Support for using the ngModel input property and ngModelChange event with reactive form directives has been deprecated in Angular v6 and will be removed in Angular v7.

Option 1 using [ngModel] without FormControl

As the first answer suggests, split [ngModel] and (ngModelChange) like this.

<mat-select 
  [(ngModel)]="selectedFoods" 
  (ngModelChange)="selectedFoods" name="selectedFoods" 
  placeholder="Favorite food" multiple>
  <mat-option *ngFor="let food of allfoods" [value]="food.value">
      {{food.viewValue}}
  </mat-option>
</mat-select>

And for the ts.

  allfoods: Food[] = [
    {value: 'steak-0', viewValue: 'Steak'},
    {value: 'pizza-1', viewValue: 'Pizza'},
    {value: 'tacos-2', viewValue: 'Tacos'},
    {value: 'pasta-3', viewValue: 'Pasta'}
  ];
  selectedFoods = [
     'steak-0', 'pasta-3'
  ];

https://stackblitz.com/edit/angular-mat-select-with-ngmodel?embed=1&file=app/select-overview-example.ts

Option 2 using [formControl] without [ngModel]

<mat-form-field>
    <mat-select [formControl]="foodForm" placeholder="Favorite food" multiple>
        <mat-option *ngFor="let food of allfoods" [value]="food.value">
            {{food.viewValue}}
        </mat-option>
    </mat-select>
</mat-form-field>

In this case, the selection is initialised in the FormControl's constructor.

 allfoods: Food[] = [
    {value: 'steak-0', viewValue: 'Steak'},
    {value: 'pizza-1', viewValue: 'Pizza'},
    {value: 'tacos-2', viewValue: 'Tacos'},
    {value: 'pasta-3', viewValue: 'Pasta'}
    ];
 myselectedFoods = ['pasta-3', 'steak-0'];
 foodForm: FormControl = new FormControl(this.myselectedFoods);

https://stackblitz.com/edit/angular-mat-select-multi-with-formcontrol

like image 182
intotecho Avatar answered Oct 27 '22 03:10

intotecho


I believe that the easiest way is to use [(ngModel)] directive (or a one-way binding, I'll cover it shortly later) to manipulate the value of mat-select: you can bind a variable, which contains elements you want to preselect, something like this:

<mat-select placeholder="participants" formControlName="participants" multiple [(ngModel)]="selection">
  <mat-option *ngFor="let participant of participants" [value]="participant">{{participant}}</mat-option>
</mat-select>

And then you can just filter your initial array of items and get only those, which you want to select by default (it should be stored in selection class property in provided case).

I have created a STACKBLITZ to demonstrate, that it's possible. In this example, I filter items at even indexes, and finally we get "1'st, 3'rd, 5'th, ..." items selected.

Notice, that you can split [(ngModel)] into 2 separate directives if you want to use only a one-way binding: [ngModel] or (ngModelChange). For more info, take a look at angular template syntax guide.

like image 11
Commercial Suicide Avatar answered Oct 27 '22 02:10

Commercial Suicide