On event start calling function periodically - javascript

I have this problem:
I have real time form validation, but the inputs have autocomplete on, so when you choose a value from it, it wont trigger eny event and I cant start validating the new value.
Here is some solution which I have figured
I was thinking when input triggers onfocus event, i can start periodically (for example every one second) calling some validating functions on input, whether the value changes or not.
And on blur event I want to stop calling the function.
But I cant figure it out how to start call the function periodically...
What I have so far:
$('input[name="'+input_name+'"]').focus(function(){
checkInput(input_name);
});
function checkInput(input_name){
setInterval(doneTyping(input_name),700);
console.log(1);
}
But this only happens once, how could I do it?
Thanks.

setInterval needs an anonymous function
myInterval = setInterval(function(){doneTyping(input_name);},700);
//To clear
clearTimeout(myInterval);

do it like
var intervalID = window.setInterval(function(){ doneTyping(input_name); }, 700);
see this fiddle.

Related

onChange / onInput alternatives?

I'm creating a typing test page and running into a small issue.
I'm trying to start the timer when the user types, and using onInput works, but the problem is that it registers every time I type into the textArea which causes the starttimer function to repeat itself.
onChange works but it only works after I click outside the page which makes sense, but is not what im looking for. I need the timer to start as soon as the user starts typing. Also with onChange the stop function works, but the timer starts after i click outside of the page.
Is there a JS event that fits what i'm looking for, or is there a way to change onInput or onChange to fix the problem i'm having.
JavaScript
document.getElementById("test-area").onchange = function () {
startTimer(1);
};
Thank you.
You need to listen to the input event because as you said change is only triggered after the input loses focus which is not what you want. You also need to handle the event only once.
document.getElementById("test-area").addEventListener("input", () => {
startTimer(1);
}, {once: true});
Note that this removes the event handler after it is fired. If you need to run it again you will have to register the event one more time. Maybe in your timer callback.
Try like this, In JavaScript, using the addEventListener() method:
The addEventListener() method attaches an event handler to the specified element.
document.getElementById("test-area").addEventListener("change", function () {
if(!this.value.length){
startTimer(1);
}
}, {once : true});
Have you tried onfocus ? its not exactly when they start typing but it works. Another option would be that you use onInput and on the clocks start function change a boolian -isRunning - to true. then put a if (isRunning) return. something like:
function start() {
if(isRunning) return;
isRunning = true;
}
and then change the boolian to false when you stop onChange
Some solutions:
Variant 1
Just create a flag:
var timerStarted = false; // Was the timer started?
document.getElementById("test-area").oninput = function () {
if(timerStarted) return; // If timer was started - do nothing
startTimer(1); // Else - start the timer
timerStarted = true; // Remember what we've started the timer
};
Variant 2
(A bit shorter)
document.getElementById("test-area").addEventListener("input", function () {
startTimer(1);
}, {once: true}); // Good thing about addEventListener
// With this it will run the event only single time
More here: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
Can you use JQuery? If so it has a method .one() which will execute the function only once. You can freely use keydown/keyup event handler then. For eg.
<script>
$(document).ready(function(){
$("#test-area").one("keydown", function() {
alert("hey");
});
});
</script>

Using Underscore _.debounce() to trigger a single event

I have the following function that is being called from a keyPress listener on an input text field. The _.debounce() is working correctly, except instead of only firing the function 1 time after the time period, it is firing as many times as the keyPress event happened.
console.log("Pre Debounce");
var debounced = _.debounce(function() {
console.log("Field updated!");
}, 2000);
debounced();
Is there a way to limit the _.debounce function to only fire 1 time after the time period?
Possibly you are constructing the debounce function each time inside the event. If that's your case then take your debounce function outside the event response code. As far as I know the debounced function should be generated only one time and then be called multiple times.
Another thing that could go weird is when you are making an async call (ex. with an ajax autocomplete) and it takes more than your wait time for debounce then the requests could fire later making appear that debouncing is not working.
It's possible that your debounce function is taking longer to execute than the user to type. In this case, you want to make sure that you prevent double debouncing by passing in a third argument (immediate) as true.
The debounce function signature is: _.debounce(function, wait, [immediate])
So change the code to:
console.log("Pre Debounce");
var debounced = _.debounce(function() {
console.log("Field updated!");
}, 2000, true);
debounced();

how to stop Javascript function execution?

My program has two buttons. One is for execute other program by using jquery load function. Whenever I click execute button, it runs some other program abc.php using load function for n times, with some time gap like k mins. These n and k will be filled with html inputs. Using jquery, will retrieve these and passing to that program file in url.
To call this function setTimeout was used.
Second one is for cancel execution.
Now my doubt is, suppose I want to stop that execution with cancel button. Is there any way to stop it ?
I would do this using boolean variable.
For example: Consider a method, perform logging.
fun () {
console.log("prints");
}
I would change it has
fun (isExecute) {
if (isExecute) {
console.log("prints");
}
}
Run fun (true); cancel fun (false);
Updates:
It seems you use setTimeout(), then it is too easy without above approach.
Run var inter = setTimeout(fun); cancel clearTimeout(inter);
FYI: The reason for assigning to a variable inter is then only you can clear this time interval.
set time for function:
timer = setTimeout(function(){$('#submenu').hide();},5000);
stop a function
clearTimeout(timer);

Clear Form Fields on Inactivity

I'm currently working on a simple form that stores users inputted information to a database.
The form will be displayed on iPads at a Kiosk.
If a user walks up to the form and starts to fill in the fields, but doesn't finish and walks away, I want the form fields to clear for the next person.
This is being done to prevent someone from walking up to an iPad with half of the previous users information that was never submitted.
I know I'll have to use Javascript, but I have no clue where to start.
I would say handle the keydown event of the window object and save the current time. Something like this:
var timerID = null;
var timeoutDuration = 60000; // Put the timeout duration here
window.addEventListener('keydown', function(e) {
if(timerID !== null) {
clearTimeout(timerID);
timerID = null;
}
timerID = setTimeout(function() {
// Clear all the fields here
}, timeoutDuration);
}, false);
Here's a demo.
Why not just reload the page after a period of inactivity? Safer bet. Just use setTimeout and clearTimeout JavaScript functions to achieve this when the fields get updated to reset the timers. Use setTimeout to reload the page. This will ensure that the page is reset.
See Reload and JavaScript timing.
In my opinion, the best thing to use it the javaScript timing event.
This can be done by setTimeout() and clearTimeout() functions. Then in those functions you can address the input boxes document.getElementById("nameofElement") and then clear them.
Good example that is easy to follow see :
JavaScript Timing Events
Hope this helps.

Javascript: Do processing when user has stopped typing

I have a text box on a web page, whose value I want to send to a XMLHttpRequest. Now I want the user to just type the value, without pressing a button. But If i just send the request int he keyboard events, it will fire every time a key is pressed.
So basically I want something liek this
function KeyUpEvent()
{
if (user is still typing)
return;
else
//do processing
}
It would be great if the solution could come from plain javascript or mootools. I dont want to use any other library.
The way this is usually done is by restarting a timer on the keyup event. Something like this:
var keyupTimer;
function keyUpEvent(){
clearTimeout(keyupTimer);
keyupTimer = setTimeout(sendInput,1000); // will activate when the user has stopped typing for 1 second
}
function sendInput(){
alert("Do AJAX request");
}
Basically, you want to start a timer on KeyUp, and when KeyUp starts again, reset the timer. When the user stops typing, the timer runs out, and your request can go at that point.
Example:
var timout_id;
function keyup_handler(event) {
if (timout_id) {
clearTimeout(timout_id);
}
timout_id = setTimeout(function(){
alert('sending data: \n' + event.target.value)
}, 800);
}
Just attach the function to the input using your preferred method, and replace the alert with your preferred action.
Of course there are many ways you could generalize this approach and make it more reusable, etc, but I think this illustrates the basic idea.
I always use this simple function to handle a timer, that will fire a callback function, after the user has stopped typing for a specified amount of time:
var typewatch = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
}
})();
Usage (example with MooTools):
$('textInput').addEvent('keyup', function(e){
typewatch(function () {
// executed only 500 ms after the last keyup event
// make Ajax request
}, 500);
});
The main difference between this solution and solutions from other answers is that all the timer logic is handled by the typewatch function itself, the event handler doesn't need to know anything about the timer, it just invokes the function. Also, there are no global variables to take care (the timer id is not stored on a global variable).
You never know when a user is really "finished" typing. The user might take a sneeze break, or a stretch break, or a coffee break, and then continue typing.
However, if you're implementing something like an autocomplete mechanism, you can set a timer (cf. window.setTimeout(...)) to see if the user hasn't typed anything in a certain amount of time. If you get another key-up event while the timer is running, you can start the timer over.
var keyTimer;
function onKeyUp(){
clearTimeout(keyTimer);
setTimeout(stoppedTyping,1500);
}
function stoppedTyping(){
// Profit! $$$
}
EDIT: Damn ninjas
I wrote a custom jQuery event because I use this logic a lot:
jQuery.event.special.stoppedtyping = {
setup: function(data, namespaces) {
jQuery(this).bind('keyup', jQuery.event.special.stoppedtyping.keyuphandler);
},
teardown: function(namespaces) {
jQuery(this).bind('keyup', jQuery.event.special.stoppedtyping.keyuphandler);
},
keyuphandler: function(e) {
var interval = 1000;
var el = this;
if (jQuery.data(this, 'checklastkeypress') != null) {
clearTimeout(jQuery.data(this, 'checklastkeypress'));
}
var id = setTimeout(function() {
jQuery(el).trigger('stoppedtyping');
}, interval);
jQuery.data(this, 'checklastkeypress', id);
}
};
You can use it like this:
$('input.title').bind('stoppedtyping', function() {
// run some ajax save operation
});
For some reason I could never get it to work with .live( ... ). I'm not sure why...
Use onBlur and maybe an onKeyDown to check for the user pressing the return/enter key.

Categories