Components: Autocomplete stops showing the List when clicking in the input field after adding a Mat-Chip

Created on 4 Oct 2019  路  10Comments  路  Source: angular/components

Reproduction

Use StackBlitz to reproduce your issue:
Official Demo shows this issue.
https://run.stackblitz.com/api/angular/v1?file=app%2Fchips-autocomplete-example.ts

This example starts showing a Lemon in the autocomplete component.

Steps to reproduce:

  1. Click in the Input of Autocomplete, next to the Lemon matchip
  2. It properly shows the List associated
  3. Click in an Option of the List, i.e "Apple". The mat-chip is added next to "Lemon".
  4. Click in the Input of Autocomplete. Now it does not show the "List", as you would expect and as it did in step 2, which breaks the UIX.
  5. Click outside the component (it loses the Focus)
  6. Click again the Input field: it receives the Focus and the List is again shown.

Expected Behavior

What behavior were you expecting to see?
Users expect that clicking in the Input field would show them the List of options again, as it did in the very beginning without needing to use the "hackish" click out-and-in.

Actual Behavior

What behavior did you actually see?
If a Mat-chip is added, the user needs to focus out and then click to set the Focus in, in order to have the List shown.

Environment

  • Angular: 8.1.0
  • CDK/Material: Material 8.0.2
  • Browser(s): Chrome, Safari, Firefox
  • Operating System (e.g. Windows, macOS, Ubuntu): Windows, Ubuntu, MacOS
P4 materiachips has pr

Most helpful comment

As an ugly fix, you can disable and enable the Control at the end of the "selected" method:
formControl.disable(); formControl.enable();
as you can see in this proof of concept:
https://angular-cp6d1k-h8up2b.stackblitz.io
You can see that thanks to the enable/disable hack in the selected() now the described issue is "solved". Feel free to comment/uncomment to feel the difference.

However I bet this will expose some counterbacks with advanced user navigation probably.
Hope it helps!

All 10 comments

As an ugly fix, you can disable and enable the Control at the end of the "selected" method:
formControl.disable(); formControl.enable();
as you can see in this proof of concept:
https://angular-cp6d1k-h8up2b.stackblitz.io
You can see that thanks to the enable/disable hack in the selected() now the described issue is "solved". Feel free to comment/uncomment to feel the difference.

However I bet this will expose some counterbacks with advanced user navigation probably.
Hope it helps!

I'm guessing it's because the list only shows up on focus and focus technically hasn't left the input. There's a PR to make it also open on clicks https://github.com/angular/components/pull/16020.

Yup. That's my guess too "(...) the user needs to focus out and then click to set the Focus in, in order to have the List shown."
So a Focus issue to me. I didn't find a unsetFocus method for FormControls, so I decided to use the disable/enable which seemed to unset focus.

It might be simpler to call blur on the input.

It might be simpler to call blur on the input.

This worked for me, good idea :)

It might be simpler to call blur on the input.

how it make?

``` //.ts

const chipElement = document.querySelector('#chip-list');
chipElement.blur();
setTimeout(() => { chipElement.focus() }, 1);
```
help resolve the problem for me.

For anyone still needing this...

  @ViewChild('inputName') inputName: ElementRef<HTMLInputElement>;

  selected(event: MatAutocompleteSelectedEvent): void {
    ....
    this.inputName.nativeElement.blur();
    ....
  }

Hope this helps took a while to get it working smoothly today

Edit: Heres a snippet of the template...

<mat-form-field>
      <mat-label>{{ 'views.user.permissions.additional_data_center' | translate }}</mat-label>
      <mat-chip-list #chipList aria-label="{{ 'views.user.permissions.additional_data_center' | translate }}">
          <mat-chip *ngFor="let d of dataCenters | idFilter:'id':selectedDataCenters:5" 
              [selectable]="true"
              [removable]="true" 
              (removed)="remove(d)">
              {{d.name}}
              <mat-icon matChipRemove>cancel</mat-icon>
          </mat-chip>
          <input #dcInput
                  [matChipInputFor]="chipList"
                  [matAutocomplete]="auto"
                  [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
                  [matChipInputAddOnBlur]="true"
                  (matChipInputTokenEnd)="add($event)">
          <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
              <mat-option *ngFor="let dc of filterDataCenters" [value]="dc.id">
              {{dc.name}}
              </mat-option>
          </mat-autocomplete>
          <span matSuffix *ngIf="selectedDataCenters.length > 5">+{{selectedDataCenters.length - 5 }} </span>
      </mat-chip-list>
  </mat-form-field>

For anyone still needing this...

  @ViewChild('inputName') inputName: ElementRef<HTMLInputElement>;

  selected(event: MatAutocompleteSelectedEvent): void {
    ....
    this.inputName.nativeElement.blur();
    ....
  }

Hope this helps took a while to get it working smoothly today

Edit: Heres a snippet of the template...

<mat-form-field>
      <mat-label>{{ 'views.user.permissions.additional_data_center' | translate }}</mat-label>
      <mat-chip-list #chipList aria-label="{{ 'views.user.permissions.additional_data_center' | translate }}">
          <mat-chip *ngFor="let d of dataCenters | idFilter:'id':selectedDataCenters:5" 
              [selectable]="true"
              [removable]="true" 
              (removed)="remove(d)">
              {{d.name}}
              <mat-icon matChipRemove>cancel</mat-icon>
          </mat-chip>
          <input #dcInput
                  [matChipInputFor]="chipList"
                  [matAutocomplete]="auto"
                  [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
                  [matChipInputAddOnBlur]="true"
                  (matChipInputTokenEnd)="add($event)">
          <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
              <mat-option *ngFor="let dc of filterDataCenters" [value]="dc.id">
              {{dc.name}}
              </mat-option>
          </mat-autocomplete>
          <span matSuffix *ngIf="selectedDataCenters.length > 5">+{{selectedDataCenters.length - 5 }} </span>
      </mat-chip-list>
  </mat-form-field>

This was a clear solution to the chip list autocomplete not working properly after selection. Even the current documentation has this bug.
Thanks for the help!

@Koniouchine .. glad I could help.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Hiblton picture Hiblton  路  3Comments

RoxKilly picture RoxKilly  路  3Comments

LoganDupont picture LoganDupont  路  3Comments

kara picture kara  路  3Comments

jelbourn picture jelbourn  路  3Comments