0
votes

I would like to create a directive that asks for confirmation when a user clicks on a button. To do that, I should be able to store the original event, and call it only when the user has confirmed his choice.

I have mocked a similar behavior here :

https://stackblitz.com/edit/angular-6wnvjk?file=src%2Fapp%2Fapp.component.html

(This is with a Timeout and not a confirmation, but the issue is the same)

How would one proceed to store the original event, then call it once the timeout/confirmation ends ?

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[confirm]'
})
export class ConfirmDirective {

  constructor() { }

  @HostListener('click', ['$event'])
  onClick(event: MouseEvent) {
    console.log('handler from directive');
    // 1 - Would like to store original event
    const originalEvent = () => {};
    // Would like to call it later
    setTimeout(() => {
      originalEvent();
    })
  }

}
1
@JanakPrajapati in the idea yes, but I don't want it to be a component, just a directive. - user4676340
@JanakPrajapati and also, I don't want to have a button that says "open dialog", but a button that says "confirm" and does X, and when you click on it, it opens a dialog to confirm : if you confirm, it does X, if not, it does nothing. - user4676340
Might be this will help - Prashant Pimpale
@PrashantPimpale I am using Angular, not AngularJS, concepts aren't the same. - user4676340

1 Answers

2
votes

You can build your directive to intercept the clicks and emit them only if the condition is passed:

@Directive({
    selector: '[confirm]',
})
export class ConfirmDirective implements OnInit, OnDestroy {
    @Output() confirmed = new EventEmitter();
    private clicks = new Subject();
    private subscription: Subscription;

    constructor() {}

    ngOnInit() {
        this.subscription = this.clicks
            .pipe(
                switchMap((event) =>
                    confirm('Do you agree?') ? of(event) : null
                )
            )
            .subscribe((e) => this.confirmed.emit(e));
    }

    ngOnDestroy() {
        if (this.subscription) this.subscription.unsubscribe();
    }

    @HostListener('click', ['$event'])
    clickEvent(event) {
        event.preventDefault();
        event.stopPropagation();
        this.clicks.next(event);
    }
}

Usage:

  <button confirm (confirmed)="doSomething()">Click</button>

Good luck!