Question

Some actions in my Angular app require the user to be registered. If the user is not registered we want to show a "Register modal" and prevent the original action.

Those actions can be triggered via ng-click or any other "click binding" directive (for example the 'modal-toggle' one).

So I found this solution: https://stackoverflow.com/a/16211108/2719044

This is pretty cool but only works with ng-click.

I first wanted to make the "terminal" property of the directive dynamic but couldn't manage to do it.

So the idea was to set "terminal" to true and manually prevent default click action in the directive.

Here is my DOM

<!-- This can work with terminal:true and scope.$eval(attrs.ngClick) (see example above) -->
<div user-needed ng-click="myAction()">Do it !</div> 

<!-- This doesn't work. I can't manage to prevent the modal-toggle to be executed -->
<div user-needed modal-toggle="my-modal-id-yey">Show yourself modal !</div> 

And my directive(s) (which don't work...)

// First try (with terminal:true)
app.directive('userNeeded', function() {
    return {
        priority: -100,
        terminal: true,
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                if(isRegistered()) {
                    // Here we do the action like scope.$eval or something
                }
            });
        }
    };
});

// Second try (with stopPropagation)
app.directive('userNeeded', function() {
    return {
        priority: -100
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                if(!isRegistered()) {
                    e.stopPropagation();
                }
            });
        }
    };
});

...And that's why I'm here. Any idea ?

Thanks a lot.

Was it helpful?

Solution

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 while stopImmediatePropagation 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'.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top