Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Angular Material Autocomplete: closePanel not working

I’m working on a form on a dialog, from which one of the form fields uses mat-autocomplete. Submitted forms are added to a table. When the user clicks on a row of the table, the form dialog opens again and he or she can edit this previously submitted form.

Current behaviour: when user opens the form, the autocomplete field is already filled with the previously submitted value, and the autocomplete panel is open

Wanted behaviour: same thing but with autocomplete panel closed.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

What I’m trying to do:
@ViewChild(MatAutocompleteTrigger) autoComplete: MatAutocompleteTrigger;
and then
this.autoComplete.closePanel();

I’ve tried with #autoComplete or #MatAutocompleteTrigger selectors on input in HTML template.

The actual error I get is ERROR TypeError: Cannot read properties of undefined (reading 'closePanel'), because autocomplete is undefined.

I’ve also tried this approach:
HTML:

<input #autoCompleteInput type="text" [matAutocomplete]="auto"/>

TS:

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

I’ve seen a few questions about it: here, here, here, but can’t make it work.

Code below:

HTML (showing only the autocomplete section)

    <mat-form-field class="top-form-field" appearance="outline">
      <mat-label>Brigada</mat-label>
      <input matInput
             #autoComplete
             aria-label="Brigada"
             [matAutocomplete]="auto"
             formControlName="nome_brigada">
      <mat-autocomplete #auto="matAutocomplete">
        <mat-option *ngFor="let brigade of filteredBrigades | async" [value]="brigade.name">
          <img class="option-img" aria-hidden [src]="brigade.typeIcon" height="25">
          <span>{{brigade.name}}</span> |
          <small>{{brigade.category}}</small>
          <span *ngIf="brigade.plate">
            | <small>{{brigade.plate}}</small>
          </span>
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>

TS: (without imports)

OBS: when "row" is not null, it’s the case when the user has clicked in the table and will edit the previously submitted form (the case I want the close the panel)

export interface Brigade {
  type: string;
  typeIcon: string;
  name: string;
  category: string;
  filterString: string;
  id_brigada: string;
  plate: string;
}

@Component({
  selector: 'select-brigade-dialog',
  templateUrl: 'select-brigade-dialog.html',
})
export class SelectBrigadeDialog {

  @ViewChild(MatAutocompleteTrigger) autoComplete: MatAutocompleteTrigger;

  public brigadeForm: FormGroup;
  brigadeCtrl = new FormControl('', [Validators.required]);
  filteredBrigades: Observable<Brigade[]>;

  public brigades: Brigade[] = [];

  public tipos_brigada:string[];
  public categorias_brigada:string[];
  public nomes_brigada: string[];

  combateChecked: boolean;
  rescaldoChecked: boolean;
  
  constructor(
    @Inject(MAT_DIALOG_DATA)
    public data: any,
    public fb: FormBuilder,
    private dtValidators: DatetimeValidators,
    private amplitude: AmplitudeService
  ) {

    this.combateChecked = false;
    this.rescaldoChecked = false;

    for (let b of data.brigadas){
      this.brigades.push({
        type: b['tipo_brigada'],
        typeIcon: brigadeIconMap[b['id_tipo_brigada']],
        name: b['nome_brigada'],
        category: b['categoria_brigada'],
        filterString: b['nome_brigada'] + b['placa'] + b['categoria_brigada'],
        id_brigada: b['id_brigada'],
        plate: b['placa']
      })
    }

    this.brigades.sort((a, b) => a.name.localeCompare(b.name));

    if (data.row === null){
      this.filterBrigades('');
    } else {
      this.filterBrigades(data.row['nome_brigada']);
    }

    let id_acionamento = `${data.id_report}_${data.len_acionamentos}`

    this.initForm(data.row, id_acionamento);
  }

  filterBrigades(nome_brigada) {
    this.filteredBrigades = this.brigadeCtrl.valueChanges.pipe(
      startWith(nome_brigada),
      map(brigade => (brigade ? this._filterBrigades(brigade) : this.brigades.slice())),
      );
    }
    
  private _filterBrigades(value: string): Brigade[] {
    const filterValue = value.toLowerCase();
    return this.brigades.filter(brigade => brigade.filterString.toLowerCase().includes(filterValue)).sort((a, b) => a.name.localeCompare(b.name));
  }
  
  initForm(row, id_acionamento){
    let datetime_now = formatDate(new Date(), 'yyyy-MM-ddTHH:mm', 'en-US');
    let dt_midnight = this.setMidnight();

    let dt_validators = [
      this.dtValidators.dtAcionamento(),
      this.dtValidators.dtCombate(),
      this.dtValidators.dtRescaldo(),
      this.dtValidators.dtChegadaCombate(),
      this.dtValidators.dtChegadaRescaldo(),
      this.dtValidators.dtFuturo(dt_midnight)
    ]
    
    if (row === null){
      this.brigadeForm = this.fb.group({
        nome_brigada: this.brigadeCtrl,
        contagem_equipe:['1',[Validators.required, Validators.min(1)]],
        dt_acionamento:[`${datetime_now}`,[Validators.required]],
        dt_chegada:[''],
        combate: false,
        dt_inicio_combate:[''],
        dt_fim_combate:[''],
        rescaldo: false,
        dt_inicio_rescaldo:[''],
        dt_fim_rescaldo:[''],
        id_acionamento:[id_acionamento],
        id_brigada: ['']
      },{
        validators: dt_validators,
      });
    } else {
      if (row['dt_inicio_combate'] !== null && row['dt_inicio_combate'] !== ''){
        this.combateChecked = true;
      };
      if (row['dt_inicio_rescaldo'] !== null && row['dt_inicio_rescaldo'] !== ''){
        this.rescaldoChecked = true;
      };
      this.brigadeForm = this.fb.group({
        nome_brigada: [row['nome_brigada'],[Validators.required]],
        contagem_equipe:[row['contagem_equipe'],[Validators.required, Validators.min(1)]],
        dt_acionamento:[row['dt_acionamento'],[Validators.required]],
        dt_chegada:[row['dt_chegada']],
        combate: this.combateChecked,
        dt_inicio_combate:[row['dt_inicio_combate']],
        dt_fim_combate:[row['dt_fim_combate']],
        rescaldo: this.rescaldoChecked,
        dt_inicio_rescaldo: [row['dt_inicio_rescaldo']],
        dt_fim_rescaldo: [row['dt_fim_rescaldo']],
        id_acionamento: [row['id_acionamento']],
        id_brigada: [row['id_brigada']]
      },{
        validators: dt_validators,
      });
      console.log('autocomplete: ', this.autoComplete)
      this.autoComplete.closePanel();
    }
  }

>Solution :

let dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
  width: '250px',
  data: { name: this.name, animal: this.animal },
  autoFocus: false   <============================== this line
});

May be if i am not wrong then you have a problem with auto focus to
first control. so using above you can handle your task. still you have
no luck let me know. Happy coding.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading