Home > Enterprise >  Angular Material Autocomplete: closePanel not working
Angular Material Autocomplete: closePanel not working

Time:11-17

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.

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  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  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();
    }
  }

CodePudding user response:

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.

  • Related