1

What I'm trying to do:

  • using the (tap) gesture in templates
  • do not fire the (tap) event if the element is 'disabled'

this would bring the (tap) event inline with the built-in angular (click) event. i.e. (click) doesn't fire if the element is disabled

Here is a stackbliz example of a button that is disabled. if you tap/click on the item we still see the event being fired.

the HTML being

<button type="submit" (tap)="toggleButton()" [disabled]="true">
    Button 1
</button>

and the toggle method that is called

toggleButton(){
    console.log('hello');
    this.buttonClicked = !this.buttonClicked;
}

as you will note, clicking the button (even while it's disabled) is still firing. this is undesired, given how (click) works. using Click instead of the tap is not an option because of the 300-millisecond delay between the two events that cause applications to appear sluggish on mobile devices.

In doing some research I see a number of questions about how to pass in different configurations via a custom class that extends HammerGestureConfig. such as

however, these don't go into conditionally disabling an event. According to the HammerJS documentation, there is an 'enable' property that accepts a boolean or a function that returns a boolean. When I tried creating a class

import {HammerGestureConfig} from '@angular/platform-browser';
import {ElementRef} from '@angular/core';
declare var Hammer: any;

export class HammerGestureConfigCustomTap  extends HammerGestureConfig {
  e: HTMLElement;
  public buildHammer(element: HTMLElement) {
    this.e = element;
    const options = {};

    const mc = new Hammer(element, options);

    // keep default angular config
    mc.get('pinch').set({enable: true});
    mc.get('rotate').set({enable: true});
    mc.get('tap').set({enable: this.enabled });

    // retain support for angular overrides object
    for (const eventName in this.overrides) {
      mc.get(eventName).set(this.overrides[eventName]);
    }
    console.log(mc);
    return mc;
  }

  private enabled(): boolean {
    return !this.e.attributes['disabled'];
  }
}

and in the app Module, making sure to provide it

{ provide: HAMMER_GESTURE_CONFIG, useValue: HammerGestureConfigCustomTap},

I get errors

Cannot read property 'indexOf' of undefined
at HammerGesturesPlugin.isCustomEvent (platform-browser.js:3771)
at HammerGesturesPlugin.supports (platform-browser.js:3664)
at EventManager._findPluginFor (platform-browser.js:2383)
at EventManager.addGlobalEventListener (platform-browser.js:2359)
at DefaultDomRenderer2.listen (platform-browser.js:2976)
at BaseAnimationRenderer.listen (animations.js:608)
at DebugRenderer2.listen (core.js:45965)
at listenToElementOutputs (core.js:42909)
at createViewNodes (core.js:44173)
at createRootView (core.js:44081)

The last resort would be to go through each callback method called in the (tap) and add logic to ignore even if the element is disabled. but this doesn't work too well when we are listening to the (tap) event in more than a handful of templates.

I'm hoping there is a glaringly easy way to accomplish this that I am simply missing. Any help would be appreciated.

thank you kindly.

Anandhu Raj
  • 137
  • 1
  • 6
Edward
  • 1,076
  • 1
  • 12
  • 24

2 Answers2

1

I've found a nice trick with css Pointer events

In your css, you can set something like:

button[disabled] {
  pointer-events: none
}

This will disable all click events.

Attached stackblitz demo

C.OG
  • 6,236
  • 3
  • 20
  • 38
0

If you add the event to the function like this:

(tap)="toggleButton($event)"

in you ts you can use it as event.target and there will be an attribute disabled, and you can not execute function if the disabled value is true.

if(event.target.disabled){
   ...do nothing

}

GaryB
  • 374
  • 1
  • 9
  • The OP mentioned this in his question: > The last resort would be to go through each callback method called in the (tap) and add logic to ignore the even if the element is disabled. but this doesn't work to well when are listening to the (tap) event in more than a handful of templates. – C.OG Oct 24 '19 at 13:59
  • you are right, I thought I clear about the question before I read it thru... – GaryB Oct 24 '19 at 14:05