0
votes

I have an hour list box ( angular material list box which consists of numbers 1 to 12 ) which I am converting to a mat auto complete.

The list box is not in a reactive form.

Below is the html where I have created the template to pull in the static list options.

<table>
  <tr>
    <td>
      <mat-form-field>
        <input type="text" [(ngModel)]="fromCreateDateTime.Hour" [ngModelOptions]="{standalone: true}" placeholder="Hour" matInput [matAutocomplete]="autoFromCreateDateTimeHour">

        <mat-autocomplete #autoFromCreateDateTimeHour="matAutocomplete" placeholder="Hour" [displayWith]="displayFn">
          <mat-option *ngFor="let hour of hoursList" [value]=" hour ">{{hour.name}}
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </td>
  </tr>
</table>

Here the hoursList is an array as defined below. It is not an observable.

hoursList: Array, any > =
  export const hoursList: Array < any > = [{
    name: "00",
    value: 0
  }, {
    name: "01",
    value: 1
  }, {
    name: "02",
    value: 2
  }, {
    name: "03",
    value: 3
  }, {
    name: "04",
    value: 4
  }, {
    name: "05",
    value: 5
  }, {
    name: "06",
    value: 6
  }, {
    name: "07",
    value: 7
  }, {
    name: "08",
    value: 8
  }, {
    name: "09",
    value: 9
  }, {
    name: "10",
    value: 10
  }, {
    name: "11",
    value: 11
  }, {
    name: "12",
    value: 12
  }];

enter image description here

How do I apply filter ( as typed in the mat input ) to the mat autocomplete since the data here is a non - async data.

2

2 Answers

0
votes

You can use (ngModelChange) and [ngModel] instead of [(ngModel)]. Something like this:

template:

<mat-form-field>
   <mat-label>Some label</mat-label>
   <input type="text"
      matInput
      [ngModel]="someObject"
      [matAutocomplete]="autocopmlete"
      (focus)="filter('')"
      (ngModelChange)="filter($event)">
      <mat-autocomplete
         #autocopmlete="matAutocomplete"
         [displayWith]="displayName">
      <mat-option
         *ngFor="let item of filteredObject"
         [value]="item">
         {{ item.name }}
      </mat-option>
   </mat-autocomplete>
</mat-form-field>

component:

  someObject = [
     { name: 'Alex' },
     { name: 'Morty' }
  ]

  filteredObject = []

  filter(value = '') {
      if (typeof value !== 'string') {
          return;
      }
    
      this.filteredObject = this.someObject.filter(
          a => ~a.name.toLocaleLowerCase().indexOf(value.toLocaleLowerCase())
      );
  }


  displayName(item: any) {
      return item ? item.name : '';
  }
-2
votes

Pretty straight forward if you're considering to use just a String Array:

import {Component, OnInit} from '@angular/core';
import {FormControl} from '@angular/forms';
import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';

@Component({
  selector: 'autocomplete-filter-example',
  templateUrl: 'autocomplete-filter-example.html',
  styleUrls: ['autocomplete-filter-example.css'],
})
export class AutocompleteFilterExample implements OnInit {
  myControl = new FormControl();
  options: string[] = [
    "00",
    "01",
    "02",
    "03",
    "04",
    "05",
    "06",
    "07",
    "08",
    "09",
    "10",
    "11",
    "12",
  ];

  filteredOptions: Observable < string[] > ;

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

  private _filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.options.filter(
      option => option.toLowerCase().includes(filterValue)
    );
  }

}

And your Template:

<form class="example-form">
  <mat-form-field class="example-full-width">
    <input type="text" 
      placeholder="Pick one" 
      aria-label="Number" 
      matInput 
      [formControl]="myControl" 
      [matAutocomplete]="auto">
    <mat-autocomplete #auto="matAutocomplete">
      <mat-option 
        *ngFor="let option of filteredOptions | async" 
        [value]="option">
        {{option}}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</form>

Here's a Sample StackBlitz for your ref.