Angular 9|8|7 | Add AutoComplete in Angular Application using Angular Material

In this post, we will discuss how to add an autocomplete/ suggestion box in Angular application using the Material UI library.

An Autocomplete control looks similar to an input field but it helps a user to select a suggestion matching from a typed string.  The list of predefined suggestions shown to the user can be saved on local, in a JSON file or can be fetched from a remote server database.

The Angular Material UI library provides a wide variety of components, today we will discuss Material’s Autocomplete UI component. Material Autocomplete can be added in the template component using the mat-autocomplete directive component.

We’ll create a new Angular 9 project using the latest version of Angular CLI tool, install and setup Material UI library. After that, we will start from a basic Autocomplete then move advanced implementation with available configurations.

Let’s start by upgrading the Angular CLI tool. Make sure you have the latest version of Angular/ Ng CLI tool installed on your system. It helps in quickly creating an Angular application and also provides other features to generate various components through the terminal.

 

#Update Ng CLI

Run the following command in the terminal window to update the Ng CLI tool. The current version is 9.0.6

$ npm install -g @angular/cli

 

#Setup a new Angular project

Let's create a new Angular project with current version 9.0.6 by executing the below ng command in the terminal window and answer a few questions:

$ ng new angular-material-autocomplete
? Would you like to add Angular routing? No
? Which stylesheet format would you like to use? CSS

After creating the project, move to project directory

$ cd angular-material-autocomplete

Then open the project in Visual Studio Code by hitting below command:

$ code .

Now you can open the terminal by pressing the Ctrl+` shortcut in Visual Studio Code then execute below command to run the project @ http://localhost:4200/:

$ ng serve --open

 

#Install and Configure Angular Material Library

In the older versions of Material, we used to have a lot of manual configurations in the project files, but after version 9 there is only a single npm command which will do all the stuff for you. Thanks to the team 🙂

Run following npm command in the terminal window at the project root, it will ask few questions to configure Material integration with Angular project.

$ ng add @angular/material

Select a theme of your choice. I choose the first one 😛

? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink

If you want typography styles. Read more about them here.

? Set up global Angular Material typography styles? Yes

Finally, if you want animations, just hit yes

? Set up browser animations for Angular Material? Yes

That's it after answering these simple questions, you have installed Material library in your project.

 

#Update App Module

The Material UI library provides number of UI components, so we need to include API of that component which we are going to use in the project. We need to define modules in the App's main module.

Open the app.module.ts file, then import MatAutocompleteModule, MatFormFieldModule and MatInputModule. We'll also use FormControl so also import the FormsModule and ReactiveFormsModule as well.

// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    ReactiveFormsModule,

    MatAutocompleteModule,
    MatFormFieldModule,
    MatInputModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now we are ready to add Material Autocomplete in the Angular project.

 

#Adding Material Autocomplete

The Material Autocomplete works in a combination of two things first is the Input control and the second is a list of autocomplete suggestions.

The mat-autocomplete wrapper with each item in the mat-option is used, as shown below:

Simple Autocomplete Example

This will only show Autocomplete items when the user focuses on Input field

    <mat-form-field class="example-full-width">

      <input type="text" placeholder="Payment type" matInput [formControl]="myControl" [matAutocomplete]="auto">

      <mat-autocomplete #auto="matAutocomplete">
        <mat-option *ngFor="let option of options" [value]="option">
          {{option}}
        </mat-option>
      </mat-autocomplete>

    </mat-form-field>

There is an Input field with the matInputdirective, which will be connected to the mat-autocomplete directive through template variable #auto ( this can be anything you like )

export class AppComponent {
  title = 'angular-material-autocomplete';

  myControl = new FormControl();
  options: string[] = ['Cash', 'Credit Card', 'Paypal'];
}

Filter Autocomplete items as user types in Input

To enable the filter on items we will map Autocomplete items then filter them using a custom _filter method

  <mat-form-field class="example-full-width">
    
    <input type="text" placeholder="Payment type" 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>

In the class file, we will define the filteredOptions as an Observable. Then we'll modify the valueChanges observable of FormControl with own _filter() method.

// app.component.ts
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'angular-material-autocomplete';

  myControl = new FormControl();
  options: string[] = ['Cash', 'Credit Card', 'Paypal'];

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

}

Autocomplete with Custom Object

We can modify the layout of suggestions shown by adding customer element in the mat-option element wrapped inside mat-autocomplete as shown below:

  <mat-form-field class="example-full-width">

    <input matInput placeholder="Search employee" [matAutocomplete]="auto" [formControl]="employeeCtrl">

    <mat-autocomplete #auto="matAutocomplete">
      <mat-option *ngFor="let employee of filteredEmployee | async" [value]="employee.name">

        <img class="example-option-img" aria-hidden [src]="employee.imageUrl" height="25">
        <span>{{employee.name}} [{{employee.jobtype}}]</span>
        <small>Email: {{employee.email}}</small>
        <small>Address: {{employee.address}}</small>

      </mat-option>
    </mat-autocomplete>

  </mat-form-field>

In the class, we have employees object

// app.component.ts
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

export interface Employee {
  id: number;
  name: string;
  jobtype: string;
  email: string;
  address: string;
  imageUrl: string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'angular-material-autocomplete';

  employeeCtrl = new FormControl();
  filteredEmployee: Observable<Employee[]>;

  employees: Employee[] = [
    {
      "id": 1,
      "name": "Lilla Nitzsche",
      "jobtype": "Human Intranet Liaison",
      "email": "[email protected]",
      "address": "11360 Bahringer Squares",
      "imageUrl": "https://s3.amazonaws.com/uifaces/faces/twitter/aleclarsoniv/128.jpg"
    },
    {
      "id": 2,
      "name": "Francisca Considine",
      "jobtype": "Dynamic Web Supervisor",
      "email": "[email protected]",
      "address": "852 Lori Turnpike",
      "imageUrl": "https://s3.amazonaws.com/uifaces/faces/twitter/hiemil/128.jpg"
    },
    {
      "id": 3,
      "name": "Gussie Stoltenberg",
      "jobtype": "Customer Intranet Representative",
      "email": "[email protected]",
      "address": "10080 Jett Corners",
      "imageUrl": "https://s3.amazonaws.com/uifaces/faces/twitter/necodymiconer/128.jpg"
    },
    {
      "id": 4,
      "name": "Fatima Dickinson",
      "jobtype": "Dynamic Directives Orchestrator",
      "email": "[email protected]",
      "address": "3249 Wilkinson Overpass",
      "imageUrl": "https://s3.amazonaws.com/uifaces/faces/twitter/pifagor/128.jpg"
    },
    {
      "id": 5,
      "name": "Edmund Nicolas MD",
      "jobtype": "Future Markets Designer",
      "email": "[email protected]",
      "address": "35163 McKenzie Forest",
      "imageUrl": "https://s3.amazonaws.com/uifaces/faces/twitter/michaelbrooksjr/128.jpg"
    },
  ];

  constructor() {
    this.filteredEmployee = this.employeeCtrl.valueChanges
      .pipe(
        startWith(''),
        map(employee => employee ? this._filterEmployees(employee) : this.employees.slice())
      );
  }

  private _filterEmployees(value: string): Employee[] {
    const filterValue = value.toLowerCase();

    return this.employees.filter(state => state.name.toLowerCase().indexOf(filterValue) === 0);
  }

}

This is how we can use Material Autocomplete using custom template for options. For complete documentation check here. Also, check this post explaining how to show remote server response in Autocomplete with a loader.

Subscribe
Notify of
1 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

for angular 8 you need to install below material
npm i –save @angular/[email protected] @angular/[email protected]