Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material Autocomplete force selection

Tags:

In my angular 5 application I have some matAutocomplete, but I want to force the selection of oone of suggestions, so I am following this approach: stackblitz but for some reason in one case I have an issue:

Cannot read property 'panelClosingActions' of undefined at CustomerDetailComponent.countryClosingActions (customer-detail.component.ts:199) at CustomerDetailComponent.ngAfterViewInit

I have multiple matAutocomplete but only this one have problems. (info about this method is here github

html

<mat-form-field>
    <input matInput #nation placeholder="{{'customer.detail.labels.country'
      | translate }}" required [matAutocomplete]="tdAuto" name="country"  
      #count="ngModel" [(ngModel)]="selected.country"
      (ngModelChange)="searchCountry($event)">
        <mat-autocomplete #tdAuto="matAutocomplete" [displayWith]="displayFn">
          <mat-option (onSelectionChange)="setCountry(country)" *ngFor="let country of countries" [value]="country">
             <div class="row">
               <img src="assets/img/flags24/{{country.alpha2Code | lowercase}}.png" />
                  <span>{{country.name}} ({{country.alpha2Code}})</span>
             </div>
         </mat-option>
        </mat-autocomplete>
    </mat-form-field>

component

@ViewChild('nation', { read: MatAutocompleteTrigger }) trigger: MatAutocompleteTrigger;
  subscription: Subscription;


ngAfterViewInit() {
    this.countryClosingActions();
  }

  private countryClosingActions(): void {
    if (this.subscription && !this.subscription.closed) {
      this.subscription.unsubscribe();
    }

    this.subscription = this.trigger.panelClosingActions
      .subscribe(e => {
        console.log('closing')
        if (!e || !e.source) {
          this.selected.country = null;
          this.selfCountry = null;
        }
      },
      err => this.countryClosingActions(),
      () => this.countryClosingActions());
  }
like image 386
Alessandro Celeghin Avatar asked Jan 24 '18 09:01

Alessandro Celeghin


Video Answer


2 Answers

Using blur event and matAutocomplete output event (optionSelected) we can force user to select option.

<mat-form-field class="example-full-width">
  <input type="text" placeholder="Country*" matInput formControlName="country" [matAutocomplete]="countryAutoList" (blur)="checkCountry()">
  <mat-autocomplete autoActiveFirstOption #countryAutoList="matAutocomplete" (optionSelected)="countryClick($event)">
    <mat-option *ngFor="let item of countryList" [value]="item.Name">{{item.Name}}</mat-option>
  </mat-autocomplete>
</mat-form-field>

ts file functions

countryClick(event: any) {
  this.selectedCountry = event.option.value;
}

checkCountry() {
 setTimeout(()=> {
  if (!this.selectedCountry || this.selectedCountry !== this.signatureFormGroup.controls['country'].value) {
    this.signatureFormGroup.controls['country'].setValue(null);
    this.selectedCountry = '';
  }
 }, 1000);
}

depend on your requirement you can always delay the function which you call in blur or optionSelect event using setTimeout window function.

setTimeout(()=> { 
// function contents
}, 1000);
like image 180
Amit kumar Avatar answered Sep 16 '22 17:09

Amit kumar


I found this helpful:

private subscribeToClosingActions(): void {
if (this.subscription && !this.subscription.closed) {
  this.subscription.unsubscribe();
}

this.subscription = this.autoCompleteTrigger.panelClosingActions
  .subscribe((e) => {
      if (!e || !e.source) {
        const selected = this.matAutocomplete.options
          .map(option => option.value)
          .find(option => option === this.formControl.value);

        if (selected == null) {
          this.formControl.setValue(null);
        }
      }
    },
    err => this.subscribeToClosingActions(),
    () => this.subscribeToClosingActions());
}
like image 36
hbthanki Avatar answered Sep 20 '22 17:09

hbthanki