Stopping the $timeout - AngularJS - javascript

var app = angular.module('myapp', []);
app.controller('PopupCtrl', function($scope, $timeout){
$scope.show = 'none';
$scope.mouseover = function(){
console.log('Mouse Enter');
$scope.show = 'block';
};
$scope.mouseout = function(){
console.log('Mouse Leave');
var timer = $timeout(function () {
$scope.show = 'none';
}, 2000);
};
});
When I mouseover a button, a pop up dialog box is show. When I mouseout, the pop up dialog box is going to be hidden in two seconds. The problem come when I mouseover the button for the second time. Even my cursor is still on the button, the pop up dialog box is hide in two second. How to stop the timer when the mouse is over the button again?

The $timeout service returns a promise that can be cancelled using $timeout.cancel(). In your case, you have to cancel the timeout in every button mouse over.
DEMO
JAVASCRIPT
var app = angular.module('myapp', []);
app.controller('PopupCtrl', function($scope, $timeout){
var timer;
$scope.show = false;
$scope.mouseover = function(){
$timeout.cancel(timer);
$scope.show = true;
};
$scope.mouseout = function(){
timer = $timeout(function () {
$scope.show = false;
}, 2000);
};
});

Related

After giving input show div for sometime

I have a scenario where i need to show a div when a user provides input.
When a user continuously changes the input value the div must be shown and when the user stops providing input after 5 secs or so the div must be hidden.
Ctrl :
function MainCtrl($scope,$timeout) {
$scope.appear = false;
$scope.showDiv = function() {
debugger;
$scope.appear = true;
}
$scope.$watch('appear',
function(newValue, oldValue) {
if(newValue && newValue===true){
$timeout(function(){
$scope.appear=false;
}, 5000);
}
}
);
}
html:
<body ng-controller="MainCtrl">
Name: <input type="text" ng-change="showDiv()" ng-model="inputText"/> <br/>
<div ng-show="appear">Content</div>
</body>
DEMO
The issue i am facing here is when i continuously provide input the div at some point of time it is getting hidden and reappearing again.
But I need the div to be shown till the input is being provided and when a user stops providing any input after 5 secs it should disappear.
Any help would be appreciated.
I have made some changes to your plunkr, check this link https://plnkr.co/edit/EsiG3Ifgk0maYF4GJTGm?p=preview
angular.module('plunker', []).controller('MainCtrl',function($scope,$timeout) {
$scope.appear = false;
$scope.timerId;
$scope.showDiv = function() {
if($scope.timerId!=undefined){
clearTimeout($scope.timerId);
}
$scope.appear = true;
$scope.timerId = $timeout(function(){
$scope.appear=false;
},5000);
}
});
You should clear your timeout: https://plnkr.co/edit/wY4C1wvBZKJ7RSwtgnCv?p=preview
angular.module('plunker', []);
function MainCtrl($scope,$timeout) {
var timeout;
$scope.appear = false;
$scope.showDiv = function() {
// debugger;
$scope.appear = true;
if(timeout) {
console.log('timeout')
$timeout.cancel(timeout);
}
timeout = $timeout(function(){
$scope.appear=false;
}, 5000);
}
}
I got below code working :
$scope.showDiv = function () {
alert(1);
$('#divShow').show();
setTimeout("$('#divShow').hide();", 5000);
}
Write this in the controller and give that "divShow" id to div and remove ng-show thing.
This worked for me, Hope help you.

AngularJS $timeout service

I have to have something visible for 3-4 seconds. I am trying to use $timeout for achieving that. Here's what I got so far:
$timeout(function() {
debugger;
$scope.$on(broadcastService.topErrorBar.show,
function(event, message) {
$scope.rootElement.addClass('is-visible');
$scope.isVisible = true;
$scope.message = message;
});
}, 3000);
$timeout.cancel(function() {
$scope.close();
});
$scope.close = function() {
$scope.rootElement.removeClass('is-visible');
$scope.isVisible = false;
};
This is not working and I'm not able to resolve the issue. What am I doing wrong? Should I use a timeout in this case.
what about:
$scope.$on(broadcastService.topErrorBar.show,
function(event, message) {
$scope.isVisible=false;
$timeout(function () { $scope.isVisible= true; }, 3000);
});
you have to use in html ng-show="isVisible">
It should be like this :
$scope.$on(broadcastService.topErrorBar.show,
function(event, message) {
$scope.rootElement.addClass('is-visible');
$scope.isVisible = true;
$scope.message = message;
$timeout(function() {
$scope.close();
}, 3000);
$scope.close = function() {
$scope.rootElement.removeClass('is-visible');
$scope.isVisible = false;
};
On Broadcast , make element visible , start a timeout so that after 3 seconds $scope.close will be called. No need for $timeout.cancel in your case.
Your logic is inverted. The function in a timeout fires after the time has elapsed. You want the element to be visible, and then set visibility to false in your timeout function. Here's an example.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $timeout) {
$scope.visible = true;
$timeout(function () {
$scope.visible = false;
}, 3000);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
This is always visible.
<span ng-show="visible">This should hide after 3 seconds</span>
</div>

Broadcasting functions through a service trigger the function multiple times instead of one

I created a service that shares a confirm modal method, and allow to broadcast methods between controillers.
services.SharedService = function($rootScope, $modal) {
var sharedService = {
controller : '',
method : '',
args : []
};
sharedService.prepare = function(controller, method){
this.controller = controller;
this.method = method;
this.broadCast();
};
sharedService.broadCast = function(){
$rootScope.$broadcast('menuBroadcast');
};
return sharedService;
});
Then I have three controllers :
controllers.ctrl1 = function($scope, $rootScope, SharedService) {
$rootScope.$on('menuBroadcast', function() {
if (SharedService.controller == 'ctrl1') {
$scope[SharedService.method]();
}
});
$scope.delete = function(){
var c = window.confirm("Are you sure you want to delete it?");
if(c === true){
//delete
}
};
};
and
controllers.ctrl2 = function($scope, $rootScope, SharedService) {
$rootScope.$on('menuBroadcast', function() {
if (SharedService.controller == 'ctrl1') {
$scope[SharedService.method]();
}
});
$scope.delete = function(){
var c = window.confirm("Are you sure you want to delete it?");
if(c === true){
//delete
}
};
};
};
controllers.menu = function($scope, SharedService) {
$scope.delete1 = function() {
console.debug("Calling delete 1");
SharedService.prepare('ctrl1', 'delete');
};
$scope.delete2 = function() {
console.debug("Calling delete 2");
SharedService.prepare('ctrl2', 'delete');
};
}
The first time I open the confirm from ctrl1, clicking on the ok button works as expected. I can open this modal as many times, it will work.
Then, switching to ctrl2, I open the confirm , I have to click two times on the ok button to be able to close the confirm box.
The console debugs shows that the "calling delete1" and "calling delete2" are triggered only once. But the console.debug from on("menuBroadcast") is triggered sometimes up to 3 times. Any idea why the service triggers the event more than one time? When injected, is it instantiated more than once?
Duplicate of
How can I unregister a broadcast event to rootscope in AngularJS?
The controller is instantiated more than once . I have to un-register the $rootScope.$on listener on when the $destroy is invoked.
var cleanUpFunc = $rootScope.$on('menuBroadcast', function {
if (SharedService.controller == 'ctrl1') {
$scope[SharedService.method]();
}
});
$scope.$on('$destroy', function() {
cleanUpFunc();
});

Stop time interval during navigation in angularjs

Currently i am using angular js
I have one get method to get data from server side in default.html page
function bindActiveLoans() {
$http.get(rootUrlSingleEscaped + '/cooperativa/allunfundedloans/?authId=' + userInfo.UserId)
.success(function (response) {
if (response.Loans.length == 0) {
$scope.IsValues = false;
$scope.$apply();
return true;
}
$scope.IsValues = true;
$scope.unfundedLoans = response;
});
};
setInterval(function () {
$scope.$apply(bindActiveLoans());
}, 5000);
The above function helps to get the data from server side method in every 5 seconds.
Here, I have an issue.
Additionally I have some more pages, like
default2.html,default3.html,default4.html,default5.html.
The timer is still running while i navigation default.html page to default1.html page. I want to only that timer running in default.html page.If i go to another page,then the timer should stop. How can we achieve it?
From the angularjs example in the $interval API page.
var interval = $interval(function() {
console.log('say hello');
}, 1000);
$interval.cancel(interval);
With $interval.cancel(var) you can stop the interval and if you want to stop it when navigating to another page you should try something like this.
var interval = null;
module.controller('SomeController', '$interval', function($interval) {
interval = $interval(function() {
...
}, 2000);
}).run(['$rootScope', '$interval', function($rootScope, $interval) {
$rootScope.$on('$routeChangeStart', function() {
$interval.cancel(interval);
});
}]);
You can listen to the $routeChangeStart event and do the clearing of the interval depending on the route parameters,
$scope.$on('$routeChangeStart', function (scope, next, current) {
if(<next is not default.aspx>){
// clear interval here
}
});
call clearInterval function when navigating from default page
e.g.
var myVar = setInterval(function () {
$scope.$apply(bindActiveLoans());
}, 5000);
function myStopFunction()
{
clearInterval(myVar);
}
Call myStopFunction

intermediate values of counter

please help to fix the script. http://jsfiddle.net/k9r4t/
when hovering. button_hover increasing the value of the counter. but the value of the counter is displayed on the screen when the cursor leaves the. button_hover. and the user sees only the initial and final value of the counter.
I would like the user to see the intermediate values
controller code:
var app = angular.module("moduleCounter", []);
app.controller("controllerCounter", function ($scope){
$scope.counter = 0;
$scope.incrementCounter = function(){
$scope.startNext = setInterval(function(){
$scope.counter++;
}, 400);
}
$scope.stopCounter = function(){
clearInterval($scope.startNext);
}
});
Use $timeout , it is Angular's native service:
var app = angular.module("moduleCounter", []);
app.controller("controllerCounter", function ($scope , $timeout){
$scope.counter = 0;
$scope.incrementCounter = function(){
$scope.setTimeout();
}
$scope.setTimeout = function(){
$scope.startNext = $timeout( $scope.counterUp , 400);
}
$scope.counterUp = function(){
$scope.counter++;
$scope.setTimeout();
}
$scope.stopCounter = function(){
$timeout.cancel($scope.startNext);
}
});
JSFiddle: http://jsfiddle.net/cherniv/k9r4t/1/

Categories