How can I make an AngularJS directive to stopPropagation?

JavascriptJqueryAngularjsStoppropagation

Javascript Problem Overview


I am trying to "stopPropagation" to prevent a Twitter Bootstrap navbar dropdown from closing when an element (link) inside an li is clicked. Using this method seems to be the common solution.

In Angular, seems like a directive is the place to do this? So I have:

// do not close dropdown on click
directives.directive('stopPropagation', function () {
    return {
        link:function (elm) {            
            $(elm).click(function (event) {                
                event.stopPropagation();
            });
        }
    };
});

... but the method does not belong to element:

TypeError: Object [object Object] has no method 'stopPropagation'

I tie in the directive with

<li ng-repeat="foo in bar">
  <div>
    {{foo.text}}<a stop-propagation ng-click="doThing($index)">clickme</a>
  </div>
</li>

Any suggestions?

Javascript Solutions


Solution 1 - Javascript

I've used this way: Created a directive:

	.directive('stopEvent', function () {
		return {
			restrict: 'A',
			link: function (scope, element, attr) {
                if(attr && attr.stopEvent)
				    element.bind(attr.stopEvent, function (e) {
					    e.stopPropagation();
				    });
			}
		};
     });

that could be used this way:

<a ng-click='expression' stop-event='click'>

This is more generic way of stopping propagation of any kind of events.

Solution 2 - Javascript

"Currently some directives (i.e. ng:click) stops event propagation. This prevents interoperability with other frameworks that rely on capturing such events." - link

... and was able to fix without a directive, and simply doing:

<a ng-click="doThing($index); $event.stopPropagation();">x</a>

Solution 3 - Javascript

stopPropagation has to be called on an event object, not the element itself. Here's an example:

compile: function (elm) {
    return function (scope, elm, attrs) {
        $(elm).click(function (event) {
            event.stopPropagation();
        });
    };
}

Solution 4 - Javascript

Here's a simple, abstract directive to stop event propagation. I figure it might be useful to someone. Simply pass in the event you wish to stop.

<div stopProp="click"></div>

app.directive('stopProp', function () {
  return function (scope, elm, attrs) {
    elm.on(attrs.stopProp, function (event) {
        event.stopPropagation();
    });
  };
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRobert ChristianView Question on Stackoverflow
Solution 1 - JavascriptValentyn ShybanovView Answer on Stackoverflow
Solution 2 - JavascriptRobert ChristianView Answer on Stackoverflow
Solution 3 - JavascriptJoseph SilberView Answer on Stackoverflow
Solution 4 - JavascriptVinnyView Answer on Stackoverflow