how to get long press event in angular js?

14,865

Solution 1

It is a good implementation:

// pressableElement: pressable-element
.directive('pressableElement', function ($timeout) {
    return {
        restrict: 'A',
        link: function ($scope, $elm, $attrs) {
            $elm.bind('mousedown', function (evt) {
                $scope.longPress = true;
                $scope.click = true;

                // onLongPress: on-long-press
                $timeout(function () {
                    $scope.click = false;
                    if ($scope.longPress && $attrs.onLongPress) {
                        $scope.$apply(function () {
                            $scope.$eval($attrs.onLongPress, { $event: evt });
                        });
                    }
                }, $attrs.timeOut || 600); // timeOut: time-out

                // onTouch: on-touch
                if ($attrs.onTouch) {
                    $scope.$apply(function () {
                        $scope.$eval($attrs.onTouch, { $event: evt });
                    });
                }
            });

            $elm.bind('mouseup', function (evt) {
                $scope.longPress = false;

                // onTouchEnd: on-touch-end
                if ($attrs.onTouchEnd) {
                    $scope.$apply(function () {
                        $scope.$eval($attrs.onTouchEnd, { $event: evt });
                    });
                }

                // onClick: on-click
                if ($scope.click && $attrs.onClick) {
                    $scope.$apply(function () {
                        $scope.$eval($attrs.onClick, { $event: evt });
                    });
                }
            });
        }
    };
})

Usage example:

<div pressable-element
    ng-repeat="item in list"
    on-long-press="itemOnLongPress(item.id)"
    on-touch="itemOnTouch(item.id)"
    on-touch-end="itemOnTouchEnd(item.id)"
    on-click="itemOnClick(item.id)"
    time-out="600"
    >{{item}}</div>

var app = angular.module('pressableTest', [])

.controller('MyCtrl', function($scope) {
    $scope.result = '-';

    $scope.list = [
        { id: 1 },
        { id: 2 },
        { id: 3 },
        { id: 4 },
        { id: 5 },
        { id: 6 },
        { id: 7 }
    ];

    $scope.itemOnLongPress = function (id) { $scope.result = 'itemOnLongPress: ' + id; };
    $scope.itemOnTouch = function (id) { $scope.result = 'itemOnTouch: ' + id; };
    $scope.itemOnTouchEnd = function (id) { $scope.result = 'itemOnTouchEnd: ' + id; };
    $scope.itemOnClick = function (id) { $scope.result = 'itemOnClick: ' + id; };
})

.directive('pressableElement', function ($timeout) {
    return {
        restrict: 'C', // only matches class name
        link: function ($scope, $elm, $attrs) {
            $elm.bind('mousedown', function (evt) {
                $scope.longPress = true;
                $scope.click = true;
                $scope._pressed = null;

                // onLongPress: on-long-press
                $scope._pressed = $timeout(function () {
                    $scope.click = false;
                    if ($scope.longPress && $attrs.onLongPress) {
                        $scope.$apply(function () {
                            $scope.$eval($attrs.onLongPress, { $event: evt });
                        });
                    }
                }, $attrs.timeOut || 600); // timeOut: time-out

                // onTouch: on-touch
                if ($attrs.onTouch) {
                    $scope.$apply(function () {
                        $scope.$eval($attrs.onTouch, { $event: evt });
                    });
                }
            });

            $elm.bind('mouseup', function (evt) {
                $scope.longPress = false;
                $timeout.cancel($scope._pressed);

                // onTouchEnd: on-touch-end
                if ($attrs.onTouchEnd) {
                    $scope.$apply(function () {
                        $scope.$eval($attrs.onTouchEnd, { $event: evt });
                    });
                }

                // onClick: on-click
                if ($scope.click && $attrs.onClick) {
                    $scope.$apply(function () {
                        $scope.$eval($attrs.onClick, { $event: evt });
                    });
                }
            });
        }
    };
})
li {
  cursor: pointer;
  margin: 0 0 5px 0;
  background: #FFAAAA;
}

.pressable-element {
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
}
<div ng-app="pressableTest">
    <div ng-controller="MyCtrl">
        <ul>
            <li ng-repeat="item in list"
                class="pressable-element"
                on-long-press="itemOnLongPress(item.id)"
                on-touch="itemOnTouch(item.id)"
                on-touch-end="itemOnTouchEnd(item.id)"
                on-click="itemOnClick(item.id)"
                time-out="600"
                >{{item.id}}</li>
        </ul>
      <h3>{{result}}</h3>
    </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

JSFiddle: https://jsfiddle.net/reduardo7/u47ok38e/

Based on: https://gist.github.com/BobNisco/9885852

Solution 2

Your code is not working because the directive binds to the elements touchstart and touchend events which you're probably not using if you're testing in a browser.

When I changed them to mousedown and mouseup your script worked fine on my computer's browser.

app.directive('onLongPress', function($timeout) {
    return {
        restrict: 'A',
        link: function($scope, $elm, $attrs) {
            $elm.bind('mousedown', function(evt) { // <-- changed
                /* ... */
            });

            $elm.bind('mouseup', function(evt) { // <-- changed
                /* ... */
            });
        }
    };
})

Solution 3

Go through the below URL for the angular directive and the implementation approaches,

Source code for long press Directive:

 // Add this directive where you keep your directives
.directive('onLongPress', function($timeout) {
return {
    restrict: 'A',
    link: function($scope, $elm, $attrs) {
        $elm.bind('touchstart', function(evt) {
            // Locally scoped variable that will keep track of the long press
            $scope.longPress = true;

            // We'll set a timeout for 600 ms for a long press
            $timeout(function() {
                if ($scope.longPress) {
                    // If the touchend event hasn't fired,
                    // apply the function given in on the element's on-long-press attribute
                    $scope.$apply(function() {
                        $scope.$eval($attrs.onLongPress)
                    });
                }
            }, 600);
        });

        $elm.bind('touchend', function(evt) {
            // Prevent the onLongPress event from firing
            $scope.longPress = false;
            // If there is an on-touch-end function attached to this element, apply it
            if ($attrs.onTouchEnd) {
                $scope.$apply(function() {
                    $scope.$eval($attrs.onTouchEnd)
                });
            }
        });
    }
};
})

Your HTML Should be like this:

 <ion-item ng-repeat="item in list" on-long-press="itemOnLongPress(item.id)" on-touch-end="itemOnTouchEnd(item.id)">
 {{ item }}
 </ion-item>

Controller JS functions to make the definitions that you would prefer:

$scope.itemOnLongPress = function(id) {
    console.log('Long press');
}

$scope.itemOnTouchEnd = function(id) {
    console.log('Touch end');
}

https://gist.github.com/BobNisco/9885852

Share:
14,865
Shruti
Author by

Shruti

Updated on July 25, 2022

Comments

  • Shruti
    Shruti almost 2 years

    I am trying to get long press event in angular js .I found the solution from here https://gist.github.com/BobNisco/9885852 But I am not able to get log on console .here is my code. http://goo.gl/ZpDeFz could you please tell me where i am getting wrong ..

    $scope.itemOnLongPress = function(id) {
        console.log('Long press');
    }
    
    $scope.itemOnTouchEnd = function(id) {
        console.log('Touch end');
    }
    
  • maurycy
    maurycy over 9 years
    Ha, just finished my plunker with the same solution: plnkr.co/edit/ecZBphQWSMZYdXJn4qZT?p=preview
  • Khateeb321
    Khateeb321 about 6 years
    You're awesome!
  • Alejandro Jurado
    Alejandro Jurado over 4 years
    How can you get the event attribute from your implementation?