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.
Related
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>
I wrote the function for check if button was clicked twice and if it was to measure the time between two clicks. It has to prevent multiple clicks in short time.
Button click:
$("#Save").click(function () {
dateTime1 = new Date().getTime();
BtnId = this.id;
showSaveDialog();
});
And measuring function:
ButtonWasTriggeredTwice: function () {
var result = false;
var currentTime = new Date().getTime();
var time = currentTime - dateTime1;
if (PreviousBtn === null) {
result= false;
} else {
if (PreviousBtn === BtnId) {
if ( time < 1500) {
result = true;
}
else result = false;
}
else {
result= false;
}
}
PreviousBtn = BtnId;
BtnId = null;
return result;
}
BtnId and PreviosusBtn are global scope variables.
The strange thing is this function works great when I set breakpoints in debugger. If I switch off debugger function blocks every next click on button, no matter what time interval is between clicks
You can use this solution with unbind and timeout, like this:
HTML
<input type="button" id="Save" value="save me" />
JS:
function saveEventButton(){
$("#Save").click(function () {
alert('saved!');
$("#Save").unbind('click');
setTimeout(function(){
saveEventButton();
}, 5000); // 5sec
});
}
saveEventButton();
This is the JSFiddle
UPDATE This solution is a mix from mine and Revish Patel solution
function disableTimeout(_this){
$(_this).prop('disabled','disabled');
setTimeout(function(){
$(_this).prop('disabled','');
}, 5000); // 5sec
}
$("#Save").click(function () {
alert('saved!');
disableTimeout(this);
});
This is the JSfiddle
You can also disable button when you first click is performed.
$(document).ready(function () {
$("#Save").click(function(){
$('#Save').prop('disabled','disabled');
// Perform your button click operation
});
});
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);
};
});
I am working on a game made with angularjs. I have one problem that I haven't been able to solve yet. I would like to use a popup dialog ( no alert ) whose content depends on the context. This popup contains a button, that when clicked starts the game.
Since the content is dynamic the ng-click function does not work.
I've tried with directives and straight from the controller but have not gotten it to work.
My concrete question is how do I add HTML Button to a with angularjs that contains a ng-click function that will actually fire?
Edit: here one attempt (that actually gets the button to show, but ng-click does nothing):
Controller:
{
if ($scope.quiz.state === 'finished' || $scope.quiz.state === 'initialized') {
var startButton = '<br><br><button data-ng-click="startQuiz">start quiz</button>';
$scope.popupText = $sce.trustAsHtml('Stating ' + quiz.name + startButton);
$scope.showStart = false;
$scope.showPopup = true;
}
};
$scope.startQuiz = function() {
$scope.showPopup = false;
if ($scope.quiz.state === 'initialized') {
$scope.quiz.start();
$scope.quizTimer.start($scope, $timeout);
}
};
Html:
<div id="popupBox">
<div id="closePopup" data-ng-click="closePopup()">X</div>
<div data-ng-bind-html="popupText"></div>
</div>
Using the help from the other answers I got it to work by doing the following (this is probably not the best way, but it works. Please comment if there is someway to improve this.):
Controller:
...
$scope.compiledStartPopupText = $compile(angular.element('<br><br><button data-ng-click="startQuiz()">start quiz</button>'))($scope);
$scope.popupText = 'Starting ' + $scope.quiz.name;
$scope.getCompiledStartPopupText = function() {
return $scope.compiledStartPopupText;
};
$scope.openStartQuizPopup = function()
{
if ($scope.quiz.state === 'finished' || $scope.quiz.state === 'initialized') {
if($scope.quiz.state === 'finished') {
$scope.quiz.reinitialize();
}
$scope.showPopup = true;
}
};
$scope.closePopup = function() {
$scope.showPopup = false;
if($scope.quiz.state !== 'started') {
$scope.showStart = true;
}
};
$scope.startQuiz = function() {
$scope.showStart = false;
$scope.showPopup = false;
if ($scope.quiz.state === 'initialized') {
$scope.quiz.start();
$scope.quizTimer.start($scope, $timeout);
} else if ($scope.quiz.state === 'finished') {
$scope.quiz.restart();
$scope.quizTimer.restart($scope, $timeout);
}
};
$scope.endGame = function()
{
$scope.quiz.state = 'finished';
$scope.showPopup = true;
$scope.showStart = true;
};
...
Directive:
directive('popUp', function() {
return {
restrict: 'A',
link: function($scope, elm, attrs) {
$scope.$watch('quiz.state', function(value){
if(value === 'finished') {
elm.html('finished');
} else {
var compiledStartButton = $scope.getCompiledStartPopupText();
elm.html($scope.popupText);
elm.append(compiledStartButton);
}
});
}
};
};
HTML:
<div id="popup" ng-show="showPopup">
<div id="popupBox">
<div id="closePopup" data-ng-click="closePopup()">X</div>
<div data-pop-up class="cta"></div>
</div>
</div>
If you are trying to call closePopup(), let's say your app is initialized at the top of the html and you have a ng-controller="MsgCtrl" as well, within the controller have your code
<div id="popupBox">
<div id="closePopup" data-ng-click="closePopup()">X</div>
<div data-ng-bind-html="popupText"></div>
</div>
and then in the script of your app, write something like this
function MsgCtrl($scope) {
$scope.closePopup = function () {
console.log("function called");
};
}
Look at this for a similar example and experiment with it.
By using the $compile service, you can evaluate arbitrary HTML in the context of a certain scope. Example:
var element = $compile(angular.element('<button ng-click="doSomething()"></button>'))(scope);
The variable element then contains an angular.element (or jQuery if you are using it) that you can insert anywhere in the DOM. Clicking the button will result in an invocation of scope.doSomething(). Hope this helps.
I need to run execFunc(); not only when the user moves onto the next field, but also runs when the user remains focused on the same field for 5 seconds.
$('input[name="email"]').bind('blur', function () {
execFunc();
});
var timer = null;
$('input[name="email"]').blur(function(e){
if (timer) clearTimeout(timer);
execFunc();
}).focus(function(e){
timer = setTimeout(execFunc, 5000);
});
If you're doing form validation, there are better ways of doing this.
How about...
$('input[name="email"]').bind('blur', execFunc).bind('focus', function() {
setTimeout(execFunc, 5000);
});
If the function isn't idempotent and you must execute it only once, you can do:
var execFuncHasExecuted = false;
function execFunc() {
if (execFuncHasExecuted)
return false;
execFuncHasExecuted = true;
// ... remainder of implementation
}
This should suffice
var g_timeout = null;
$('input[name="email"]')
.blur(function () {
execFunc();
})
.focus(function(){
if (g_timeout) clearTimeout(g_timeout);
g_timeout= setTimeout(execFunc, 5000);
});