title: Customizing mat select to allow nested values in angular
body: <p>I'm customizing angular material select/autocomplete to allow nested dropdowns.</p>
  <p>Here, I wanted to have one parent dropdown with many childs. If I expand particular parent dropdown, only childs of that dropdown should expand or collapse. Similarly, checkbox event should be selected in the same scenario.</p>
  <p>I have some bugs here</p>
  <p><strong>Case 1.</strong></p>
  <p>Select A Parent checkbox, C Parent checkbox, expand both, unselect each values of C and then finally unselecting parent C checkbox will give only the first value of A. Expected should be all values of A as parent A was already selected.</p>
  <p>There are some additional bugs also there, hope if case 1 is solved, that will get resolved.</p>
  <p>Any help would be highly appreciated.</p>
  <p><a href="https://stackblitz.com/edit/angular-f5mizr-8xar8q" rel="nofollow noreferrer">STACKBLITZ</a></p>
  <p>HTML</p>
  <pre><code>&lt;mat-form-field appearance=&quot;fill&quot;&gt;
    &lt;mat-label&gt;Toppings&lt;/mat-label&gt;
    &lt;input type=&quot;text&quot; matInput placeholder=&quot;Select Users&quot; aria-label=&quot;Select Users&quot; matInput [matAutocomplete]=&quot;auto&quot; [formControl]=&quot;states&quot;&gt;
    &lt;mat-autocomplete #auto=&quot;matAutocomplete&quot;&gt;
  
      &lt;mat-select-trigger&gt;
        {{states.value ? states.value[0] : ''}}
        &lt;span *ngIf=&quot;states.value?.length &gt; 1&quot; class=&quot;example-additional-selection&quot;&gt;
              (+{{states.value.length - 1}} {{states.value?.length === 2 ? 'other' : 'others'}})
            &lt;/span&gt;
      &lt;/mat-select-trigger&gt;
  
      &lt;mat-optgroup *ngFor=&quot;let group of stateList&quot;&gt;
        &lt;div&gt;
          &lt;mat-checkbox [checked]=&quot;group.selected&quot; (change)=&quot;toggleParent($event, group)&quot; (click)=&quot;$event.stopPropagation()&quot;&gt;
            {{group.letter}}
          &lt;/mat-checkbox&gt;
          &lt;button mat-button (click)=&quot;expandDocumentTypes(group)&quot;&gt;
                  &lt;mat-icon&gt;keyboard_arrow_down&lt;/mat-icon&gt;
                &lt;/button&gt;
        &lt;/div&gt;
        &lt;mat-option *ngFor=&quot;let name of group.names&quot; [value]=&quot;name&quot; [ngClass]=&quot;isExpandCategory[group.letter] ? 'list-show' : 'list-hide'&quot;&gt;
          &lt;mat-checkbox [checked]=&quot;group.checked&quot; (change)=&quot;toggleSelection($event, name, group)&quot; (click)=&quot;$event.stopPropagation()&quot;&gt;
            {{name}}
          &lt;/mat-checkbox&gt;
        &lt;/mat-option&gt;
      &lt;/mat-optgroup&gt;
  
    &lt;/mat-autocomplete&gt;
  &lt;/mat-form-field&gt;
  </code></pre>
  <p>TS Code:</p>
  <pre><code>export class SelectCustomTriggerExample {
    constructor(private _formBuilder: FormBuilder) {}
  
    isExpandCategory: boolean[] = [];
    toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
    stateRecord: any = [];
    states = new FormControl();
  
    expandDocumentTypes(group: any) {
      console.log(&quot;expanding dropdown&quot;, group);
      this.isExpandCategory[group.letter] = !this.isExpandCategory[group.letter];
    }
  
    toggleSelection(event: any, name: any, group: any) {
      console.log(&quot;toggleSelection&quot;, name, event.checked, group);
      if (event.checked) {
        console.log(&quot;stastateRecordtelist&quot;, this.stateRecord);
        this.stateRecord.push(name);
        this.states.setValue(this.stateRecord);
        console.log(&quot;toggleselection &quot;, this.states.value);
      } else {
        console.log(&quot;else toggleselection&quot;, name, group, this.states.value);
        this.states.setValue(this.states.value.filter((x: any) =&gt; x !== name));
        console.log(&quot;after filter &quot;, this.states.value);
      }
    }
  
    toggleParent(event: any, group: any) {
      group.checked = event.checked;
      console.log(&quot;event&quot;, event.checked, &quot;group&quot;, group, &quot;states value&quot;, this.states.value);
      let states = this.states.value;
      states = states ? states : [];
      if (event.checked) {
        states.push(...group.names)
      } else {
        console.log(&quot;else&quot;, states);
        group.names.forEach((x: string) =&gt; states.splice(states.indexOf(x), 1));
      }
      this.states.setValue(states);
      console.log(&quot;statesvalue&quot;, this.states.value);
      if (!event.checked) {
        this.states.setValue(this.states.value.filter((x: any) =&gt; !x.includes(group.names)))
      }
      console.log(&quot;final statesvalue&quot;, this.states.value);
    }
  
    stateList: StateGroup[] = [{
      letter: 'A',
      checked: false,
      names: ['Alabama', 'Alaska', 'Arizona', 'Arkansas']
    }, {
      letter: 'C',
      checked: false,
      names: ['California', 'Colorado', 'Connecticut']
    }, {
      letter: 'D',
      checked: false,
      names: ['Delaware']
    }, {
      letter: 'F',
      checked: false,
      names: ['Florida']
    }, {
      letter: 'G',
      checked: false,
      names: ['Georgia']
    }, {
      letter: 'H',
      checked: false,
      names: ['Hawaii']
    }, {
      letter: 'I',
      checked: false,
      names: ['Idaho', 'Illinois', 'Indiana', 'Iowa']
    }, {
      letter: 'K',
      checked: false,
      names: ['Kansas', 'Kentucky']
    }, {
      letter: 'L',
      checked: false,
      names: ['Louisiana']
    }, {
      letter: 'M',
      checked: false,
      names: ['Maine', 'Maryland', 'Massachusetts', 'Michigan',
        'Minnesota', 'Mississippi', 'Missouri', 'Montana'
      ]
    }, {
      letter: 'N',
      checked: false,
      names: ['Nebraska', 'Nevada', 'New Hampshire', 'New Jersey',
        'New Mexico', 'New York', 'North Carolina', 'North Dakota'
      ]
    }, {
      letter: 'O',
      checked: false,
      names: ['Ohio', 'Oklahoma', 'Oregon']
    }, {
      letter: 'P',
      checked: false,
      names: ['Pennsylvania']
    }, {
      letter: 'R',
      checked: false,
      names: ['Rhode Island']
    }, {
      letter: 'S',
      checked: false,
      names: ['South Carolina', 'South Dakota']
    }, {
      letter: 'T',
      checked: false,
      names: ['Tennessee', 'Texas']
    }, {
      letter: 'U',
      checked: false,
      names: ['Utah']
    }, {
      letter: 'V',
      checked: false,
      names: ['Vermont', 'Virginia']
    }, {
      letter: 'W',
      checked: false,
      names: ['Washington', 'West Virginia', 'Wisconsin', 'Wyoming']
    }];
  }
  </code></pre>
  <p>Output should look like below.</p>
  <p><a href="https://i.stack.imgur.com/zxycL.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zxycL.jpg" alt="enter image description here" /></a></p>