Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent double click in Angular?

I have a component with click.

<my-box (click)="openModal()"></my-box> 

When I click this element, openModal function will run. And I'd like to give 1000ms throttle time in order to prevent opening multiple modals.

My first approach was using Subject (from rxJs)

//html <my-box (click)="someSubject$.next()"></my-box> //ts public someSubject$:Subject<any> = new Subject(); ...etc subscribe 

But I feel it's a bit verbose.

Next Approach was using a directive. I modified a bit of code that I found by googling.

//ts import {Directive, HostListener} from '@angular/core';  @Directive({     selector: '[noDoubleClick]' }) export class PreventDoubleClickDirective {      constructor() {     }      @HostListener('click', ['$event'])     clickEvent(event) {         event.stopPropagation();    // not working as I expected.         event.preventDefault();     // not working as I expected.          event.srcElement.setAttribute('disabled', true);    // it won't be working unless the element is input.         event.srcElement.setAttribute('style', 'pointer-events: none;');   // test if 'pointer-events: none' is working but seems not.           setTimeout(function () {             event.srcElement.removeAttribute('disabled');         }, 500);     } }  //html <my-box noDoubleClick (click)="openModal()"></my-box> 

However, whatever I try, always openModal was executed. I couldn't find how to stop executing openModal in the directive.

I can just make like

//ts //In the openModal method. openModal() {     public isClickable = true      setTimeout(() => {         this.newsClickable = true;     }, 1000);     ... } 

But for the reusable code, I think using directive is ideal.

How can I make it?

like image 400
Téwa Avatar asked Jul 17 '18 21:07

Téwa


People also ask

How do I stop my keys from double clicking?

Present Code click(function (e) { // Prevent button from double click var isPageValid = Page_ClientValidate(); if (isPageValid) { if (isOperationInProgress == noIndicator) { isOperationInProgress = yesIndicator; } else { e.

How angular double click is implemented?

The ng-dblclick directive tells AngularJS what to do when an HTML element is double-clicked. The ng-dblclick directive from AngularJS will not override the element's original ondblclick event, both are executed.


1 Answers

You can use RxJs' debounce or debounceTime operator to prevent double clicks. Here is also a post on how to create a custom debounce click directive.

In case the post is taken down in the future, here is the final code:

Directive:

import {    Directive,    EventEmitter,    HostListener,    Input,    OnDestroy,    OnInit,    Output  } from '@angular/core'; import { Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators';  @Directive({   selector: '[appDebounceClick]' }) export class DebounceClickDirective implements OnInit, OnDestroy {   @Input()    debounceTime = 500;    @Output()    debounceClick = new EventEmitter();      private clicks = new Subject();   private subscription: Subscription;    constructor() { }    ngOnInit() {     this.subscription = this.clicks.pipe(       debounceTime(this.debounceTime)     ).subscribe(e => this.debounceClick.emit(e));   }    ngOnDestroy() {     this.subscription.unsubscribe();   }    @HostListener('click', ['$event'])   clickEvent(event) {     event.preventDefault();     event.stopPropagation();     this.clicks.next(event);   } } 

Example Usage:

<button appDebounceClick (debounceClick)="log()" [debounceTime]="700">Debounced Click</button> 
like image 143
Sam Herrmann Avatar answered Sep 18 '22 12:09

Sam Herrmann