Looking to implement a search feature using Material's autocomplete that can filter by either user name or user ID. The current implementation is partially functional in this Stackblitz.
When selecting a user name from the autocomplete options with a mouse click, it correctly redirects to the user detail page. However, when using keyboard arrows to select and submit with 'Enter', it displays [object Object] in the input field instead of the actual Name. How can I modify this to display the user name?
Furthermore, is there a way for the autocomplete to display IDs instead of names if the user inputs numeric values?
HTML:
<p>Search Users by Name or ID</p>
<form [formGroup]="searchForm" (ngSubmit)="onSubmit()">
<input type="text" [matAutocomplete]="auto" [formControl]="searchControl" />
<mat-autocomplete #auto="matAutocomplete">
<mat-option (click)="onSubmit()" *ngFor="let option of (filteredOptions | async)" [value]="option">
{{ option.name }}
</mat-option>
</mat-autocomplete>
<input type="submit" style="display: none;">
</form>
TS:
import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs";
import { map, startWith } from "rxjs/operators";
import { Router } from "@angular/router";
import { FormGroup, FormControl } from "@angular/forms";
import { User } from "../user";
import { UserService } from "../user.service";
@Component({
selector: "app-users",
templateUrl: "./users.component.html",
styleUrls: ["./users.component.css"]
})
export class UsersComponent implements OnInit {
filteredOptions: Observable<User[]>;
users: User[] = [];
options: User[];
searchControl = new FormControl();
searchForm = new FormGroup({
searchControl: this.searchControl
});
getUsers(): void {
this.users = this.UserService.getUsers();
}
constructor(public router: Router, private UserService: UserService) {}
ngOnInit() {
this.getUsers();
this.options = this.users;
this.filteredOptions = this.searchControl.valueChanges.pipe(
startWith(""),
map(value => this._filter(value))
);
}
private _filter(value: string): User[] {
const filterValue = value;
return this.options.filter(
option =>
String(option.id)
.toLowerCase()
.indexOf(filterValue) > -1 ||
option.name.toLowerCase().indexOf(filterValue) > -1
);
}
// Search bar
onSubmit() {
let userId = this.searchControl.value.id;
this.router.navigate(["user-details", userId]);
}
}