Search code examples
javascripthtmlangulartypescript

(keyup.enter) triggered twice | Angular


So I have an HTML with increment and decrement functionality on button/enter click. Button (click) works as expected however on (keyup.enter) increment function is triggered twice.

When I press Tab + enter on keyboard (keyup.enter) and (click) both events are triggered which is calling the function twice

<div class="container">
<div class="row">
    <div class="col-sm" style="text-align:center">
        <h2> Increment/Decrement Functionality</h2>
    </div>
</div>
<div class="row" style="margin: 40px">
    <div class="col-sm">
        Increment All <button  (click)="incrementAll()" (keyup.enter)="incrementAll()"> +
        </button>
        Decrement All
        <button (click)="decrementAll()" (keyup.enter)="decrementAll()"> - </button>
    </div>
</div>
<div class="row" style="margin: 40px">
    <div class="col-sm" *ngFor="let num of countNumbers; let i = index" style="margin: 20px">
        <input name="countNumbers_{{i}}" type="number" [(ngModel)]="num.number" #ngModel>
        <button (click)="decrement(i)" (keyup.enter)="decrement(i)"[ngClass]="{'disabledIcon': num.number === 0 }"style="margin:20px"> -
  </button>
        <button (click)="increment(i)"
     (keyup.enter)="increment(i)"> +
  </button>
    </div>
</div>

Typescript:

increment(index) {
    this.countNumbers[index].number += 1;
}

decrement(index) {
    if (this.countNumbers[index].number > 0) {
        this.countNumbers[index].number -= 1;
    }
}

incrementAll() {
for (let i = 0; i < this.countNumbers.length; i++) {
  this.countNumbers[i].number += 1;
}
}
decrementAll() {
for (let i = 0; i < this.countNumbers.length; i++) {
  if (this.countNumbers[i].number > 0) {
    this.countNumbers[i].number -= 1;
  }
}

DEMO


Solution

  • By default, an HTML button can be "clicked" on with enter (e.g. for people who use the keyboard to navigate the form).

    In your code, if a button is focused (if you've clicked on it before), and you press enter, these things happen:

    1. The default "click" event is registered, so you get an increment.
    2. your (keyup.enter)="incrementAll()" is registered, so you get a second increment.

    A quick fix is to get rid of (keyup.enter)="incrementAll()":

    <div class="container">
        <div class="row">
            <div class="col-sm" style="text-align:center">
                <h2> Increment/Decrement Functionality</h2>
            </div>
        </div>
        <div class="row" style="margin: 40px">
            <div class="col-sm">
                Increment All <button  (click)="incrementAll()"> +
                </button>
                Decrement All
                <button (click)="decrementAll()"> - </button>
            </div>
        </div>
        <div class="row" style="margin: 40px">
            <div class="col-sm" *ngFor="let num of countNumbers; let i = index" style="margin: 20px">
                <input name="countNumbers_{{i}}" type="number" [(ngModel)]="num.number" #ngModel>
                <button (click)="decrement(i)"[ngClass]="{'disabledIcon': num.number === 0 }"style="margin:20px"> -
          </button>
                <button (click)="increment(i)"> +
          </button>
            </div>
        </div>
    </div>