Select Page

How to Handle Right Click Event in Angular

Posted on July 14, 2017
James Quick, Social Developer
When using Angular, the way we interact with the DOM,  attributes of DOM elements, and event handlers differ from using vanilla javascript by itself.  Angular takes care of so much for us that it's amazing!  However, we occasionally come across certain pieces that are missing or aren't immediately apparent how to access.  The great thing about Angular, is it provides you the tools you need to be able create the missing functionality yourself should the need be.

The Scenario

This week, I’ve been working on a page that uses drag and drop functionality.  I decided that one of the potential actions the user could take was better served by right-clicking instead of doing a drag.  So, the question became how to detect right-click on an element.  Since I had never done this before, I first found how to accomplish this with plain HTML and Javascript.  Turns out it was really simple.  Using the “oncontextmenu” event in HTML, you can then define an event handler in your Javascript to do what you want.

<div oncontextmenu="javascript:alert('success!');return false;">
    Right click me
</div>

Instead of having to define the action to take place in the HTML, you can obviously define a callback function in your .JS file, but for simplicity this works for now.  But… if you try to do this with Angular, you’ll run into an issue.  Functions that you define in your controller don’t get trigger by html properties that aren’t prefixed with “ng”.  Let me rephrase.  Angular has added lots of Directives to match functionality built in to HTML.  For instance

click -> ng-click

Ng-clicks allows us to define a callback function in our controller that is recognized and executed.  So, to handle right-clicking, I found that creating a simple directive was the best way to go to accomplish the same thing. I’ll show the code first, then explain.

.directive('ngRightClick', function($parse) {
        return function(scope, element, attrs) {
            var fn = $parse(attrs.ngRightClick);
            element.bind('contextmenu', function(event) {
                scope.$apply(function() {
                    event.preventDefault();
                    fn(scope);
                });
            });
        };
    })
<div class="text-center" style="font-size: 32px; margin: 50px;">Right Click Me</div>

As you can see, I’ve created a directive called “ngRightClick” that takes a dependency on $parse, which takes in an Angular expression and returns a function.  Let’s come back to that.  Additionally, in the directive I’m binding to the ‘contextmenu’ event (the one we originally directly declared in the first HTML above).  Again, that event is already built into Javascript.  As part of that binding, I declare a callback function where I can decide what I want to do when the right click triggers.

Coming back to $Parse.  I use $Parse here to convert the content of the ng-right-click attribute (which is  “rightClickEvent()”) and returns that function.  Since $Parse returns me the function I want to execute when the “contextmenu” event is triggered, I can call it inside of the “contextmenu” event callback.

Here’s the general idea.  You create a custom directive that binds to a built in JavaScript event (in this case ‘contextmenu’).  Then, inside of the callback for that event, simply call the function that you defined in your HTML.  It’s tricky to wrap your head around, but not too bad once you understand the basics.

Check out the Code

Couldn’t find documentation or explanation originally, but inspiration for this post came from the code sample, here.

 

Subscribe

Subscribe

Javascript. Node. Angular. Bootstrap. Wordpress. You name it.  If you are a current or aspiring web developer looking to learn more, then subscribe!  I will share the latest news and tutorials as well as exclusive assets.

Thank you for subscribing!

Pin It on Pinterest

Share This

Share this post with your friends!