stealz stealz - 3 months ago 161
Javascript Question

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

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!

Rob Rob
Answer

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

Comments