Angular Material is a popular UI framework based on Material Design for Angular.
In this article, we’ll look at how to use Angular Material into our Angular project.
Getting Started
We can install Angular Material into an existing project by running:
ng add @angular/material
Then we run:
ng serve
to serve our app.
Autocomplete
Angular comes with an autocomplete component.
To use it, we write:
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatAutocompleteModule,
MatFormFieldModule,
ReactiveFormsModule,
FormsModule,
MatInputModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
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 {
myControl = new FormControl();
options = [
{ name: 'apple' },
{ name: 'orange' },
{ name: 'grape' }
];
filteredOptions: Observable<any[]>;
ngOnInit() {
this.filteredOptions = this.myControl && this.myControl.valueChanges
.pipe(
startWith(''),
map(value => typeof value === 'string' ? value : value.name),
map(name => name ? this._filter(name) : this.options.slice())
);
}
displayFn(user): string {
return user && user.name ? user.name : '';
}
private _filter(name: string) {
const filterValue = name.toLowerCase();
return this.options.filter(option => option.name.toLowerCase().indexOf(filterValue) === 0);
}
}
app.component.html
<div>
<form class="example-form">
<mat-form-field class="example-full-width">
<mat-label>Assignee</mat-label>
<input type="text" matInput [formControl]="myControl"
[matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async"
[value]="option">
{{option.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
</div>
We add the input and the mat-autocomplete
component into the mat-form-field
to show the input and the autocomplete.
In app.component.ts
, we watch the value of myControl
and then do the filtering with the map
operator and the filter
method.
The displayFn
method is bused to display the values for the autocomplete.
We also have to import all the required modules in app.module.ts
.
We can also add a custom input into the mat-form-field
component.
Also, we defined a FormControl
and set it to the input to let us watch the input value.
For instance, we write:
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 {
control = new FormControl();
fruits: string[] = ['apple', 'orange', 'grape'];
filteredFruits: Observable<string[]>;
ngOnInit() {
this.filteredFruits = this.control.valueChanges.pipe(
startWith(''),
map(value => this._filter(value))
);
}
private _filter(value: string): string[] {
const filterValue = this._normalizeValue(value);
return this.fruits.filter(street => this._normalizeValue(street).includes(filterValue));
}
private _normalizeValue(value: string): string {
return value.toLowerCase().replace(/s/g, '');
}
}
app.component.html
<div>
<form class="example-form">
<input type="text" placeholder="Search a fruit" [formControl]="control"
[matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let street of filteredFruits | async"
[value]="street">
{{street}}
</mat-option>
</mat-autocomplete>
</form>
</div>
We added our own input into the form instead of a mat-form-field
.
Conclusion
We can add an autocomplete with Angular Material.