Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material: Hide Autocomplete Panel when User hits enter Key

I'm currently working on a table where the user is able to tab through editable elements by pressing enter. I also use Angular Material in this.

I have a mat-form-field with several dynamically created input fields with the mat-autocomplete element. However my enter key event acts a bit different in this.

When you press on the input field, a panel will open (dropdown) where the user can select the input or he can simply write himself and the panel will give suggestions (autocomplete).

What happens if you press the tab key?

If you press on tab while typing, the cursor will move onto the next editable element and the panel (dropdown) of the latest element will close.

What happens if you press the enter key

If you press on enter while typing, the cursor will move onto the next editable element HOWEVER the panel (dropdown) of the latest element stays open which resulst in multiple input fields having an open dropdown panel even though the user has already wrote what he needed to.

Template:

<tr *ngFor="let row of rows; let rowIdx = index">
            <td *ngFor="let col of columns; let colIdx = index">
                <mat-form-field class="example-full-width">             
                <input  #inputs type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto"
                    (keyup.enter)="shiftFocusEnter(rowIdx, colIdx)">
                    <mat-autocomplete #auto="matAutocomplete">
                            <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
                            {{ option }}
                            </mat-option>
                        </mat-autocomplete>
                    </mat-form-field>
            </td>
      </tr>

This simply creates rows based on the number of objects in an array (not quite important here).

There's also a keyup.enter event on the input fields which gets triggered when ever the user presses on enter while focus is on an input field and passes row index and column index to get the next editable element.

Component:

shiftFocusEnter(rowIdx: number, colIdx: number) {
console.log("Enter", rowIdx, colIdx);  
if(colIdx == 4 && rowIdx == 5) {
  console.log("Reached end of row");
}
else {
  colIdx = colIdx + this.columns.findIndex(c => c.editable);
  this.autocomplete.showPanel = false;
  this.focusInput(rowIdx, colIdx);
}

}

This function receives two parameters. Row Index and Column Index and calculates the index of the next editable element to focus on that.

The line this.autocomplete.showPanel = false was written to see if I could simply close the panel like this but it didnt work.

this.autocomplete is an object of class MatAutocomplete. I've added this by writing

@Input('matAutocomplete')
autocomplete: MatAutocomplete

What I need:

I want the dropdown panel of the mat autocomplete element to close after pressing enter.

Thanks in advance!

Update:

So after working a bit I found this

@ViewChild('test', { read: MatAutocompleteTrigger }) test: MatAutocompleteTrigger;

+

this.test.closePanel();

This time I'm able to close the panel of the FIRST cell in the table however all the panels of the other input fields will stay open

like image 429
Ekos Avatar asked Jan 23 '18 09:01

Ekos


3 Answers

My use case was slightly different so your update didn't work for me, but I found a slightly different solution that does the trick:

@ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger;

Then you can use this to close the dropdown options:

this.autocomplete.closePanel(); 

Make sure to also import ViewChild:

import { ViewChild } from '@angular/core';

Works like a charm.

like image 73
Kyle Krzeski Avatar answered Nov 19 '22 06:11

Kyle Krzeski


This comment provides a solution where you can get a reference to the matAutocompleteTrigger directly on the input element, so that you can call closePanel() within the template. For example:

    <input
      type="text"
      matInput
      #trigger="matAutocompleteTrigger"
      (keydown.enter)="$event.target.blur(); trigger.closePanel()"
      [formControl]="myControl"
      [matAutocomplete]="auto"
    />
like image 39
Tim Avatar answered Nov 19 '22 06:11

Tim


// This is my solution  ios/android panel not hide on done button virtual // 


<input type="text" placeholder="{{lbl.TipDoc}}"
class="form-control ui-inputtext ui-widget autocomp"
 #trigautoTipDoc ="matAutocompleteTrigger"
 aria-label="name" matInput                                        (blur)="OcuPanelAuto(trigautoTipDoc);"
formControlName="tipDocLbl" [matAutocomplete]="autoTipDoc" >
<mat-autocomplete #autoTipDoc="matAutocomplete" role="combobox">
<mat-option  *ngFor="let option of tipDocFiltObs | async"
                                                            [value]="option.name">
 {{option.name}}
</mat-option>
</mat-autocomplete>


OcuPanelAuto(cc: MatAutocompleteTrigger) {
        setTimeout(function a() {
            cc.closePanel();
        }, 130);
    }
like image 1
andres robanesky Avatar answered Nov 19 '22 05:11

andres robanesky