javascriptcssangularangular-materialmat-autocomplete

How to enable/visible mat-autocomplete only if condition gets true


UPDATED

Creating user input popup form, in one field trying to do autocomplete, with THIS solution.

I guess the auto-complete is working fairly fine, the issue is the options not coming below the input box.

Code:

<div>
 <div class="modal-header">
 
 </div>
 <div class="modal-body">
   <form  novalidate [formGroup]="myform">
     <div class="form-floating form-group">
      <input type="text" class="form-control" id="fltName" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto">
      <label for="fltName">Name</label>
      

      <mat-autocomplete autoActiveFirstOption #emp="matAutocomplete"  class="form-control">
         <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
        {{option}}
         </mat-option>
      <mat-autocomplete>
    </div>
    

Question:

1. The options box should display, only if there 2 or less matches?

2. return emp names options by inserting emp_id?

How can I setup option such as {name:xyz, emp_id:123, emp_no:333}, and if I text any value should give name as option like if I write 33 should bring option xyz.


Solution

  • Question 1: The options box should display, only if there 2 or less matches

    For this you need to apply the ng-container (To avoid rendering the option box) directive and apply the length condition over there according to your requirement.

    <mat-autocomplete #auto="matAutocomplete">
      <ng-container  *ngIf="filteredOptions && (filteredOptions | async)?.length <= 2">
        <mat-option  *ngFor="let option of filteredOptions | async"   [value]="option" >
          {{option.name}} //this is the value you always want to display
        </mat-option>
      </ng-container>
    </mat-autocomplete>
    

    Question 2: return emp names options by inserting emp_id?

    The second part can be achieved by applying filter on the required fields, i.e.

    private _filter(value: string): string[] {
      if(value && value !== ""){
        const filterValue = value.toLowerCase();
        return this.options.filter(option => option.name.toLowerCase().includes(filterValue) || option.emp_no.toString().startsWith(filterValue));
      } else {
        return [];
      }
    }
    

    apart from this you need to fix the pipe part as well, you have to pass the control value in RxJs startWith operator like,

     this.filteredOptions = this.myControl.valueChanges
      .pipe(
        startWith(this.myControl.value),
        map(value => this._filter(value))
      );
    

    Note: you can access the working solution here