0

I have an angular material drop down selector where I have multiple options to choose from. There is also an option where I can select all the options at once.

enter image description here

I used the code from this link, ( found it in answer for a similar question ).

These are my problems

  1. The solution that was given in stack blitz is not fully accessible. The events do not get triggered on click of space bar.
    What I have tried : using (onSelectionChange) event. But this will throw " Maximum call stack size exceeded" error as soon as there is a change.

  2. How do I check these ( select all ) options on load ?
    What I have tried : adding [checked]=true. But this will throw "Can't bind to 'checked' since it isn't a known property of 'mat-option'" error.

How do I achieve these behaviours ?

karthik sadanand
  • 219
  • 1
  • 2
  • 9
  • Can you show the code you've put together? The issue with your item 1 is that you have code in your onSelectionChange that triggers another selectionchange and the recursion eventually fills up the call stack and ... well you know the rest :) – Peter4499 Dec 08 '21 at 18:13
  • Hi, @Peter4499, my current code snippet is pretty much similar to the one stackblitz link I have added in the question. [here](https://stackblitz.com/edit/angular-material-with-angular-v5-jsgvx6?file=app/app.component.html) – karthik sadanand Dec 08 '21 at 19:04

1 Answers1

0

I have found a hack ( or an actual solution ) for this problem. Feel free to edit my code Turns out I wasn't the only one with the same problem. Even though there were lot of people with the same issue under this link. My problem was slightly different. I wanted even the 'All' option to be accessible via keyboard. And I had to load all the options on load.

Here's the code that I wrote for it :

app.component.html

 <div class="ddHolder">
  <div>
    <form [formGroup]="selectYearsForm" autocomplete="off" >
      <mat-form-field appearance="fill">
        <mat-select formControlName="yearOption" multiple class="custom-select-csRp"
          panelClass="custom-select-panelCsrp mat-select-custom scrollcsrp" disableOptionCentering #selectcsrp
          contentTabIndex=null  #matSelect (selectionChange)="matOPtionChanged($event)">
  
          <mat-option #allSelected [value]="0">
            All
          </mat-option>
  
          <mat-option *ngFor="let year of selectedYearDD" [value]="year">
            {{year}}
          </mat-option>
        </mat-select>
      </mat-form-field>
    </form>
  </div>
</div>

app.component.ts

import { Component, ViewChild } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { MatOption } from '@angular/material/core';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent {
  toppings = new FormControl();
  selectYearsForm!: FormGroup;
  selectedYears: any = [];
  selectedYearDD: any = [];
  selectedYearDDCopy: any = [];

  
  @ViewChild('allSelected')
  private allSelected!: MatOption;


  constructor(
    private fb: FormBuilder
  ){

  }

  ngOnInit(): void {

    this.selectYearsForm = this.fb.group({
      yearOption: new FormControl('')
    });

    this.selectedYearDD = ['1999','2000','2001','2002','2003','2004','2005'];
    this.selectedYearDDCopy.push([...this.selectedYearDD.map((item: any) => item), 0])
  }

  ngAfterViewInit() {

    //if needed load all the values by default
    setTimeout(() => {
      this.selectYearsForm.controls.yearOption
        .patchValue([...this.selectedYearDD.map((item: any)=> item), 0]);

      this.selectedYears = [];
      this.selectYearsForm.controls.yearOption.value.forEach((item: any) => item == 0 ? "" : this.selectedYears.push(item));
  
    }, 1);

  }

  matOPtionChanged(event: { value: number[]; }) {

    const filteredArray = event.value.filter(val => !this.selectedYearDDCopy.includes(val));

    if (event.value.length == this.selectedYearDD.length && !event.value.includes(0)) {
      if (this.allSelected.selected || event.value.length - 1 == this.selectedYearDDCopy.length) {
        this.selectYearsForm.controls.yearOption
          .patchValue([...this.selectedYearDD.map((item: any)  => item), 0]);
      }
      else {
        this.selectYearsForm.controls.yearOption
          .patchValue([]);
      }
    }

    else if (filteredArray.length == 1 && filteredArray[0] === 0) {
      this.selectYearsForm.controls.yearOption
        .patchValue([...this.selectedYearDD.map((item: any)  => item), 0]);
    }

    else if (event.value.includes(0) && event.value.length - 1 < this.selectedYearDD.length) {
      event.value.shift();
      this.selectYearsForm.controls.yearOption
        .patchValue(event.value);
    }

    this.selectedYearDDCopy = this.selectYearsForm.controls.yearOption.value;

    this.selectedYears = [];
    this.selectYearsForm.controls.yearOption.value.forEach((item: any)  => item == 0 ? "" : this.selectedYears.push(item));

  }
}
karthik sadanand
  • 219
  • 1
  • 2
  • 9