How can I make an AngularJS directive to stopPropagation?
"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>
.stopPropagation() on link produced by Angular directive with transclusion
Use ng-click
only instead of href, and then call $event.stopPropagation();
as mentioned
here.
AngularJS: How to stop event propagation from ng-click?
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/
What's the best way to cancel event propagation between nested ng-click calls?
What @JosephSilber said, or pass the $event object into ng-click
callback and stop the propagation inside of it:
<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
<img src="http://some_src" ng-click="nextImage($event)"/>
</div>
$scope.nextImage = function($event) {
$event.stopPropagation();
// Some code to find and display the next image
}
How to stop ng-click from a custom directive in AngularJS?
Why not use the actual button for your button. You could change your directive to:
angular.module("Demo", []).directive("myButton", function() {
return {
restrict : "E",
replace: true,
scope: {
disabled: "="
},
transclude: true,
template: "<button class='my-button' ng-class='{ \"my-button-disabled\": disabled }' ng-disabled='disabled' type='button' ng-transclude></button>"
};
});
Then style it to look like your div. See the Short Example I've made.
AngularJS use a directive to prevent other directives to execute
You were extremely close. Instead of stopPropagation you needed stopImmediatePropagation. The difference between the two is summarized in this StackOverflow answer by @Dave:
stopPropagation
will prevent any parent handlers from being
executed whilestopImmediatePropagation
will do the same but
also prevent other handlers from executing.
So to fix the code, all we have to do is swap out that method and Voilà:
app.directive('userNeeded', function() {
return {
priority: -100
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('click', function(e) {
if(!isRegistered()) {
e.stopImmediatePropagation();
}
});
}
};
});
Here is an example Plunker of the working code. In the example I modified the directive slightly to allow specific events to be specified (such as user-needed="submit"
) by passing the value directly to the element.bind
function; however, it defaults to 'click'.
AngularJS ng-click stopPropagation
ngClick directive (as well as all other event directives) creates $event
variable which is available on same scope. This variable is a reference to JS event
object and can be used to call stopPropagation()
:
<table>
<tr ng-repeat="user in users" ng-click="showUser(user)">
<td>{{user.firstname}}</td>
<td>{{user.lastname}}</td>
<td>
<button class="btn" ng-click="deleteUser(user.id, $index); $event.stopPropagation();">
Delete
</button>
</td>
</tr>
</table>
PLUNKER
Stop mouse event propagation
If you want to be able to add this to any elements without having to copy/paste the same code over and over again, you can make a directive to do this. It is as simple as below:
import {Directive, HostListener} from "@angular/core";
@Directive({
selector: "[click-stop-propagation]"
})
export class ClickStopPropagation
{
@HostListener("click", ["$event"])
public onClick(event: any): void
{
event.stopPropagation();
}
}
Then just add it to the element you want it on:
<div click-stop-propagation>Stop Propagation</div>
Related Topics
Getting an Absolute Url from a Relative One. (IE6 Issue)
How to Pass Arguments to Event Handlers in Jquery
How to Support Promises in Internet Explorer 11
Sort Object Properties and JSON.Stringify
Recursively Print All Permutations of a String (Javascript)
Ajax Call and Clean JSON But Syntax Error: Missing ; Before Statement
Javascript/Jquery: Set Values (Selection) in a Multiple Select
Deep Copy an Array in Angular 2 + Typescript
Jquery: How to Get the Event Object in an Event Handler Function Without Passing It as an Argument
Jest: Timer and Promise Don't Work Well. (Settimeout and Async Function)
JavaScript Triple Greater Than
Unsigned Integer in JavaScript
Getting How Many People Are in a Chat Room in Socket.Io
External Template in Underscore
Capture the Close Event of Popup Window in JavaScript
Creating a JavaScript Cookie on a Domain and Reading It Across Sub Domains