Handling ng-click and ng-dblclick on the same element with AngularJS

stealz picture stealz · Dec 7, 2013 · Viewed 55.4k times · Source

I was looking for both single and double-click event handling with AngularJS, since AngularJS always fires only the ng-click event even if there is ng-dblclick directive set for our element.

Here is some working code for those who seek solution:

JS:

function MyController($scope) {

    var waitingForSecondClick = false;
    $scope.singleClickAction = function() {

        executingDoubleClick = false;
        if (waitingForSecondClick) {
            waitingForSecondClick = false;
            executingDoubleClick = true;
            return $scope.doubleClickAction();
        }
        waitingForSecondClick = true;

        setTimeout(function() {
            waitingForSecondClick = false;
            return singleClickOnlyAction();
        }, 250); // delay

        /*
         * Code executed with single AND double-click goes here.
         * ...
         */

        var singleClickOnlyAction = function() {
            if (executingDoubleClick) return;

            /*
             * Code executed ONLY with single-click goes here.
             * ...
             */

        }

    }

    $scope.doubleClickAction = function() {

        /*
         * Code executed ONLY with double-click goes here.
         * ...
         */

    };

}

HTML:

<div ng-controller="MyController">
    <a href="#" ng-click="singleClickAction()">CLICK</a>
</div>

So my question is (since I'm an AngularJS newbie): could somebody more experianced write some nice directive for handling those both events?

In my opinion the perfect way would be to change the behaviour of ng-click, ng-dblclick and add some "ng-sglclick" directive for handling single-click-only code. Don't know if it is even possible, but I'd find it very useful for everyone.

Feel free to share your opinions!

Answer

Rob picture Rob · Dec 7, 2013

You could just write your own. I took a look at how angular handled click and modified it with code I found here: Jquery bind double click and single click separately

<div sglclick="singleClick()" ng-dblClick="doubleClick()" style="height:200px;width:200px;background-color:black">


mainMod.controller('AppCntrl', ['$scope', function ($scope) {
    $scope.singleClick = function() {
      alert('Single Click');
    }
    $scope.doubleClick = function() {
      alert('Double Click');
    }
}])


mainMod.directive('sglclick', ['$parse', function($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attr) {
          var fn = $parse(attr['sglclick']);
          var delay = 300, clicks = 0, timer = null;
          element.on('click', function (event) {
            clicks++;  //count clicks
            if(clicks === 1) {
              timer = setTimeout(function() {
                scope.$apply(function () {
                    fn(scope, { $event: event });
                }); 
                clicks = 0;             //after action performed, reset counter
              }, delay);
              } else {
                clearTimeout(timer);    //prevent single-click action
                clicks = 0;             //after action performed, reset counter
              }
          });
        }
    };
}])

Here's an example

Plunker