10

I have directive that does something like so:

app.directive('custom', function(){
    return {
        restrict:'A',
        link: function(scope, element){
            element.bind('click', function(){
                alert('want to prevent this');
            });

        }
    }
});

yes, it's necessary to do jQuery-way binding for this case.

And now I want to stop this event(click) propagation if some condition met.

Tried to do:

  $event.stopPropagation();
  $event.preventDefault();

but it did not help.

here fiddle for example - http://jsfiddle.net/STEVER/5bfkbh7u/

Michael Kang
  • 52,003
  • 16
  • 103
  • 135
Stepan Suvorov
  • 25,118
  • 26
  • 108
  • 176

5 Answers5

9

In your case you can't stop propagtion because click event happens on the same element, there are just two different handlers.

However you can leverage the fact that this is the same event object in both controller ngClick and in directive. So what you can do is to set some property to this event object and check for it in directive:

$scope.dosomething = function($event){
    $event.stopPropagation();
    $event.preventDefault();
    alert('here');

    if (someCondtion) {
        $event.stopNextHandler = true;
    }
}

and in directive:

link: function(scope, element){
    element.bind('click', function(e) {
        if (e.stopNextHandler !== true) {
            alert('want to prevent this');    
        }
    });            
}

Demo: http://jsfiddle.net/5bfkbh7u/6/

dfsq
  • 191,768
  • 25
  • 236
  • 258
2

Have you tried lowering the priority of this directive to make sure it binds after the ng-click directive? I assume the events fire in the order they were bound which is in turn determined by the priority of the ng-click directive vs your directive.

You also need stopImmediatePropagation to prevent any more handlers on the same element from firing. stopPropagation just prevents the event propagating to parent handlers.

James Gaunt
  • 14,631
  • 2
  • 39
  • 57
  • I played with priorities, but may be I was not correct. both directives has 0 priority, right? – Stepan Suvorov Feb 18 '15 at 14:51
  • Yes ng-click does, so I'd make yours -1, to make sure it runs afterwards, and use stopImmediatePropagation instead of stopPropagation. stopPropagation won't stop an event firing on the same element. – James Gaunt Feb 18 '15 at 14:52
1
Use e.stopImmediatePropagation();
elem.bind('click', function (e) {
  if (disable(scope)){
    e.stopImmediatePropagation();
    return false;
  }

  return true;
});
Manik Thakur
  • 294
  • 2
  • 15
  • 1
    Would help to explain why `stopPropagation` didn't work and why you expect `stopImmediatePropagation` to work. I personally don't know. – apokryfos Jun 23 '16 at 15:01
  • 1
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. - [From review](https://stackoverflow.com/review/low-quality-posts/12789020) – Ferrybig Jun 23 '16 at 17:40
0

there isnt any event propagation here as you have button and you are having to events on the same element this isnt going to parent element of child element, i.e no event bubbling or event capturing is here

A.B
  • 20,110
  • 3
  • 37
  • 71
0

You attach both events to the button. Check the element when you register the second event

<div ng-controller="mainCtrl" custom>
    Hi! I'm the parent.
    <button ng-click="dosomething($event)">BUTTON</button>
</div>

Showcase

Mx.
  • 3,588
  • 2
  • 25
  • 33
  • is it solution? you just removed "custom" directive – Stepan Suvorov Feb 18 '15 at 14:57
  • no I tried to show why your event is still fired even when you prevent the propagation. thats the reason why i attached your "custom" event to your actual parent. – Mx. Feb 18 '15 at 14:58
  • @STEVER if your question is "how can i prevent a second attached event from firing?" then you will mostly go with check-flag solutions. dfsq provided one – Mx. Feb 18 '15 at 15:03