-1

Fiddle: http://jsfiddle.net/0o1mrapd/20/

Angular stackblitz link: https://stackblitz.com/edit/angular-fhtaki?file=src%2Fapp%2Fapp.component.html

I have a complex case which i need some enlightenment. (For angular developers, you can think the wrapper div as a host selector, <my-button></my-button>)

As you can see in the fiddle I have a disabled button with a wrapper div which has a click event.

<div onclick="alert('hey')" style="display:inline-block">
    <button disabled>
      <span>Click</span>
    </button>
</div>

What I expect is that when I click on that area, nothing will happen but alas I get the alert. If I remove the span element and put plain text inside the button, this works.

<div onclick="alert('hey')" style="display:inline-block">
    <button disabled>
      Click
    </button>
</div>

How can I make the div unclickable in this case? I found out that pointer-events: none does the trick but then I lose the curser-event which I need for accessibility


I stumbled upon this issue while creating a custom button component with an ng-content in Angular but then realized this is bigger than the framework. Some links i checked:

Can you prevent an Angular component's host click from firing?

Add CSS cursor property when using "pointer-events: none"

How to stop event propagation with inline onclick attribute?

https://github.com/angular/angular/issues/9587

eko
  • 39,722
  • 10
  • 72
  • 98
  • Replace button with div and use rule="button" for accessibility? https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role https://stackoverflow.com/questions/26402033/missing-click-event-for-span-inside-button-element-on-firefox – yurzui Nov 26 '18 at 13:29
  • Can I ask why you put the click event on the div & not on the button? – Wimanicesir Nov 26 '18 at 13:34
  • @Wimanicesir Thanks for the question. The reason is in the framework that I'm using, the wrapper div is shipped as a blackboxed html element. So the user can attach the events to that element. I tried to demonstrate the usage in that scenario. – eko Nov 26 '18 at 13:36
  • Did you try to redefine event `click` as suggested on one of the links you shared? – Bunyamin Coskuner Nov 26 '18 at 13:36
  • @BunyaminCoskuner yep, I will create a stackblitz that demos the issue in an Angular environment as well. – eko Nov 26 '18 at 13:37
  • @yurzui I created a stackblitz for the angular environment as well. If I make it a div, i will lose a lot of semantic attributes. I don't know whether i can replicate things like, autofocus and type="submit" for example – eko Nov 26 '18 at 13:42
  • Yes, I have tried it myself. I can't think of a way to stop this. I can suggest something else. I've developed couple of `button` components myself. I think it is better to develop it as a directive. With this way, there will be no wrapper element in the DOM and you still get to apply some styling. Also, you will not need to provide every attribute `button` element takes. – Bunyamin Coskuner Nov 26 '18 at 13:45
  • @BunyaminCoskuner I also have that approach as Angular material does (which works nicely) but this is a different scenario in my case :-) – eko Nov 26 '18 at 13:50
  • Then I'm out of options :) if you cannot find a solution, you could state in your docs that `click` event should not be bound by the user. They should subscribe to some custom event you will define within `my-button`. This would prevent the problem imo. – Bunyamin Coskuner Nov 26 '18 at 13:54
  • @BunyaminCoskuner yea I wanted it to be convenient for the user, that's why i didn't rename the (click) event. And yes I will be documenting it for sure :-) – eko Nov 26 '18 at 13:59
  • I think the (click) event you're binding is the click of that my-button which not the click event of the templated button element. Change the event name to btnClick and emit event via Output and it will work. I hope it helps. – Niral Munjariya Nov 26 '18 at 14:04
  • @NiralMunjariya for sure that will work, but still the (click) event would be usable – eko Nov 26 '18 at 14:07

2 Answers2

0

Maybe this example will be useful

function clickHandler() {
  console.log('Click');
}
<div onclick="return false;">
  <button onclick="clickHandler()">
    Click
  </button>
 </div>
eustatos
  • 686
  • 1
  • 10
  • 21
  • If you make the div disabled and put a span inside the button, the click event will still fire. I want it to be unclickable – eko Nov 26 '18 at 14:25
  • Fire event on button because it has attribute `onclick="clickHandler()"`. Replace this attribute to `disabled`. If I know what you want. – eustatos Nov 26 '18 at 14:44
0

You can use this css property to avoid click event be fired in the span tag. It could be a workaround.

<div onclick="alert('hey')" style="display:inline-block">
    <button disabled>
      <span style="pointer-events:none;">Click</span>
    </button>
</div>
manelseo
  • 587
  • 4
  • 6
  • Thank you but as I've mentioned in the question: "I found out that pointer-events: none does the trick but then I lose the curser-event which I need for accessibility' – eko Nov 26 '18 at 14:38