Priyabrat Nanda
Priyabrat Nanda

Reputation: 1095

Increase value by 1 till mouse is release using angular mouse events

I have a td span which displays some numeric value and i have 2 icons (up/down arrow) shown above and below the span. Clicking on the up arrow increases the value by 1 till 99 and clicking on down arrow decreases the value by 1 till 0. Everything is working fine with ng-click.

The problem is if i want to increase the value say from 10 to 20, i have to click the up arrow 10 times. I want to do this by keep pressing the mouse on the up arrow. It should keep increasing/decreasing till i release the mouse on the up/down arrow respectively.

I tried using ng-mousedown but it increases by 1. Is there a way i can call the js function till the mouse button is released.

Any pointers will be helpful.

Code I tried so far:

var mouseDown = true;

var interval;

$scope.keepPressing = function(){

    mouseDown = true;
    if (mouseDown){
        doSome();
    }

};
function doSome(){
    console.log(mouseDown);
    if (mouseDown){
        console.log(1);
        interval = setInterval(doSome, 1000);
    }
}

$scope.isMouseDown = function (){

    clearInterval(interval);
    mouseDown = false;
};

HTML:

The problem with this is even though the value 1 is not printed when i release the mouse, value false (mousedown value) is getting logged infinitely. This is a just the test flow to check if it works for me before i apply it to my actual function.

The output from console: true 1 true 1 true 1 true 1 true 1 true 1 true 1 true 1 63 false

After i release the mouse, the false value is printed 63 times within seconds. I have to refresh the page to stop it.

Upvotes: 1

Views: 1893

Answers (2)

Priyabrat Nanda
Priyabrat Nanda

Reputation: 1095

Here is what i did and working for me.

var interval;
scope.mousePress = function(){
    doSome();
    }
};
var doSome = function {
    increaseValue(); // separate function where all the increment logic resides.
    interval = $timeout(doSome, 1000);
}

scope.mouseRelease = function (){
    $timeout.cancel(interval);  
};

In the HTML, call the mousePress & mouseRelease functions from ng-mousedown & ng-mouseup respectively.

Upvotes: 0

artur grzesiak
artur grzesiak

Reputation: 20348

Here is directive, that enables setting your own time-interval and step:

.directive('changingValue', function(){

return {

  scope : {
    changingValue :"=",
    changingValueStep : "@",
    changingValueInterval : "@"
  },
  link : function(scope, element, attrs) {

    var step = attrs.changingValueStep;
    if(!step)step = 1;
    else step = parseInt(step);

    var interval = attrs.changingValueInterval;
    if(!interval)interval = 500;
    else interval = parseInt(interval);

    console.log("step", step, "interval", interval);

    var pressed = false;

    function changeValue() {
       if (pressed) {
          setTimeout(
            function() {
              console.log(scope.changingValue);
              scope.changingValue += step;
               scope.$apply();
              changeValue();
            }, interval
          )
       }

    }

    element.on("mousedown", function() {
      pressed = true;
      changeValue();
    });

    element.on("mouseup", function() {
       pressed = false;
    });


  }

}  

Basically it can be used like that:

<div changing-value="counter" changing-value-step="-1" changing-value-interval="200">-</div>

And here is working --->PLNKR<---.

Upvotes: 1

Related Questions