minaise
minaise

Reputation: 103

Angular 7 - make keydown event on div not working

I have angular 7 app with a search form. When typing into form, I'm filtering the output and present output as a list of div's. When using (click) event, I can select and trigger function, but when trying to use (keydown) event, it's not working.

<input type="text" class="form-control" 
id="licensePlate" 
aria-describedby="licensePlate" 
name="licensePlate" #licensePlate="ngModel" 
required minlength="2" [(ngModel)]="carModel" [ngbTypeahead]="carAutoComplete" 
[inputFormatter]="CarFormatter" 
[resultTemplate]="carTemplate">

Working with mouse:

<ng-template #carTemplate let-r="result" let-t="term">
    <div (click)="searchCar(r.id)">{{ r.licensePlate }} - {{ r.make }} {{ r.carModel }}</div>
</ng-template>

Not working with keyboard

<ng-template #carTemplate let-r="result" let-t="term">
    <div (keydown)="keyDownFunction($event)" tabindex="0">{{ r.licensePlate }} - {{ r.make }} {{ r.carModel }}</div>
</ng-template>

Here's my TS code:

carAutoComplete = (text$: Observable<string>) =>
  text$.pipe(
    debounceTime(200),
    distinctUntilChanged(),
    map(term => term.length < 2 ? []
      : this.carsList.filter(v => v.licensePlate.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10))
  )
  CarFormatter = (x: {licensePlate: string}) => x.licensePlate;

  keyDownFunction(event) {
    console.log('Clicked keyboard:', event);
  }

  searchCar(id: number) {
    this.searchSelected = true;
    this.router.navigate(['car', id]);
  }

I want to be able to select a car with mouse and by keyboard only.

Upvotes: 2

Views: 10846

Answers (2)

minaise
minaise

Reputation: 103

Got it working, not ideal probably as requires 2 times Enter to be pressed (select div from list and then submit input, but at least works as expected. Added keydown to input:

<input type="text" class="form-control" id="licensePlate" aria-describedby="licensePlate" name="licensePlate" #licensePlate="ngModel" 
required minlength="2" [(ngModel)]="carModel" 
[ngbTypeahead]="carAutoComplete" [inputFormatter]="CarFormatter" [resultTemplate]="carTemplate" 
(keydown)="searchCarKeyboard($event, licensePlate)">

And created new function:

searchCarKeyboard(event, licensePlate) {
  if (event.keyCode === 13) {
    if (licensePlate.model.id) {
      const carId = licensePlate.model.id;
      this.searchSelected = true;
      this.router.navigate(['car', carId]);
    }
  }
}

Upvotes: 0

Andrei Gătej
Andrei Gătej

Reputation: 11979

In order to have the keydown event on elements such div, p, you must use the contenteditable attribute.

So you would have something like this:

<ng-template #carTemplate let-r="result" let-t="term">
    <div contenteditable="true" (keydown)="keyDownFunction($event)" tabindex="0">{{ r.licensePlate }} - {{ r.make }} {{ r.carModel }}</div>
</ng-template>

Upvotes: 5

Related Questions