Ajax search when user stops typing - javascript

I want the ajax to executed when user stops typing but this it isn't working on key up event and when I am putting onkeyup=doneTyping() in input with id searchtext the browser is crashing
<script>
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms, 5 second for example
var $input = $('#search_text');
var txt = $(this).val();
$input.on('keyup', function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
$input.on('keydown', function () {
clearTimeout(typingTimer);
});
function doneTyping () {
$.ajax({
url:"fetch.php",
method:"post",
data:{search:txt},
dataType:"text",
success:function(data)
{
$('#searchresults').html(data);
}
});
//do something
}
</script>
Thank you

I turned your code into a snippet and added some console logging to show what is going on.
This shows that the events are working exactly as you describe ... and 'Done typing' shows in the console 5 seconds after I quit typing.
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms, 5 second for example
var $input = $('#search_text');
console.log("$input = ", $input.length);
$input.on('keyup', function() {
console.log("Key up");
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
$input.on('keydown', function() {
console.log("Key down");
clearTimeout(typingTimer);
});
function doneTyping() {
console.log("Done typing");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
Test input: <input id="search_text">

Related

Unable to add event into DataTable Pagination buttons when using setInterval

I'm working on a Table that logs all action and refreshes the table based on the interval given.
Everything works fine except when using setInterval, here's my code:
var interval = 3000;
var interval_en = true;
$(document).ready(function() {
$('#logs_tbl').DataTable();
$('.paginate_button,.paginate_button.current').click(function(){
e.preventDefault();
console.log("paginate click");
interval_en = false;
}).change(function(e){
e.preventDefault();
console.log("paginate click");
interval_en = false;
});
var aclogs_interval = setInterval(function () {
if(interval_en){
console.log("logging=true");
aclog_refresh(); //This function refreshes the table via Ajax
}else{
console.log("logging stopped");
clearInterval(aclogs_interval);
}
}, interval);
} );
What have I tried so far:
Different selector:
$('#logs_tbl_paginate a').click(function(){
interval_en = false;
clearInterval(aclogs_interval);
});
Binding per interval:
var aclogs_interval = setInterval(function (e) {
if(interval_en){
console.log("logging=true");
aclog_refresh();
$('.paginate_button,.paginate_button.current').click(function(){
e.preventDefault();
console.log("paginate click");
interval_en = false;
}).change(function(e){
e.preventDefault();
console.log("paginate click");
interval_en = false;
});
}else{
console.log("logging stopped");
clearInterval(aclogs_interval);
}
}, interval);
Though manually triggering interval_en = false; in the browser console will stop it. Still can't find out what went wrong.
Also clicking the pagination buttons before the first interval occur works.
You could try the following:
$('#logs_tbl').on( 'page.dt', function () {
console.log("paginate click");
$('.btn-live,.btn-notlive').prop('class','btn-notlive');
interval_en = false;
} );
This example is reference by datatable site.

Run JS code when user finished typing

I have a lot of input fields with the same class. When the user finishes typing the function doneTyping should run.
I tried this but somehow it doesn't work.
Can I use one function for all the input fields I have?
$(function() {
console.log('ready');
var timer;
var doneTypingInt = 5000;
$('.typing').keyup(function(){
clearTimeout(timer);
if ($('.typing').val()) {
timer = setTimeout(doneTyping, doneTypingInt);
}
});
function doneTyping () {
console.log('function doneTyping');
}
});
what you're looking for is debounce
$('.typing').keypress(_.debounce(yourfunc, 3000))
You basically want to use the keypress function. Your adjusted code:
$(function() {
console.log('ready');
var timer;
var doneTypingInt = 5000;
$('.typing').keypress(function(event){
if(timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(doneTyping, doneTypingInt);
});
function doneTyping () {
console.log('function doneTyping');
}
});
I don't think that you have something wrong in your code, you just have to wait 5 seconds to see the result, and in order to use one function for all inputs with the "typing" class, you should use the bind method as follows:
Javascript code: (Jsfiddle)
$(function() {
console.log('ready');
var timer;
var doneTypingInt = 1000;
$('.typing').keyup(function(){
clearTimeout(timer);
if ($('.typing').val()) {
timer = setTimeout(doneTyping.bind($(this)), doneTypingInt);
}
});
function doneTyping () {
alert('function doneTyping ' + this.val());
}
});

check user is inactive show a popup and reset if he clicks on continue button javascript

Requirement :
If user is inactive then show a popup after 5 minutes. and if selected continue session the timer will reset for this and again check for the same.
If user haven't click any continue button then the page will refresh.
How do you want to check if they are inactive?
You can tie an event to both the keyboard and mouse and reset timer each time the mouse moves/clicks or keydown.
<body onmousemove = "canceltimer()"; onclick = "canceltimer()">
var tim = 0;
function reload ()
{
tim = setTimeout("location.reload(true);",180000); // 3 minutes
}
function canceltimer()
{
window.clearTimeout(tim); // cancel the timer on each mousemove/click
reload(); // and restart it
}
Using jQuery:
$(function() {
(function handleInactivity() {
var maxIdleTime = 5000; // 5 seconds
var timeout = setTimeout(displayPopup, maxIdleTime);
function resetTimer() {
console.log("Timer reset");
clearTimeout(timeout);
timeout = setTimeout(displayPopup, maxIdleTime);
}
function displayPopup() {
console.log("You're up");
// Display popup of your choice
}
$(document).on("mousemove", resetTimer);
$(document).on("mouseDown", resetTimer);
$(document).keypress(resetTimer);
})();
});
_inactiveUserPopUp = function(warningTime,PageReloadTimeAfterWaring){
var maxIdleTime = warningTime *1000,timeout,resetTimer,displayPopup,pageReload;
timeout = setTimeout(displayPopup, maxIdleTime);
resetTimer = function(){
// console.log("Timer reset");
clearTimeout(timeout);
timeout = setTimeout(displayPopup, maxIdleTime);
};
displayPopup = function(){
//console.log("You're up");
clearTimeout(timeout);
var reloadPage = setTimeout(pageReload, PageReloadTimeAfterWaring*1000);
$(".modalDialog").css({
"opacity": 1,
"display": "block"
});
$(".close").on("click", function() {
$(".modalDialog").css({
"opacity": 0,
"display": "none"
});
});
$("#extend-session").off().on("click", function() {
clearTimeout(reloadPage);
$(".modalDialog").css({
"opacity": 0,
"display": "none"
});
$.ajax({
url: $("#openModal").data("ajaxUrl"),
type: "POST",
data: {
activeUser: true
},
success: function(data) {
}
});
});
};
pageReload = function(){
//console.log("reload page now")
$(document).off("mousemove");
$(document).off("mouseDown");
$(document).off("keypress");
window.location.reload();
};
$(document).on("mousemove", resetTimer);
$(document).on("mouseDown", resetTimer);
$(document).keypress(resetTimer);
};

jQuery: determine when a user is done changing text

I have a table where one of the td cells has a input type=text field. Each row in the table has something like this:
<td class="expected_minutes">
<input id="minutes-980" class="minutes" type="text" value="39" name="minutes-980">
</td>
Now what I'm trying to do is change the value in another cell if the user changes the value in this particular one. It doesn't necessarily have to be done when the user is done changing text. It can be whenever the value in the text box changes at all -- whatever works best. Here's some code I found on SO to get me started:
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 2000; //time in ms
//on keyup, start the countdown
$('.minutes').keyup(function(){
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$('.minutes').keydown(function(){
clearTimeout(typingTimer);
});
//user is "finished typing," do something
function doneTyping () {
console.log("DONE TYPING");
}
The problem I've found here is this code was most likely targeting an application with a single input text box. I have several rows where each row has one and I need to run some code when the minutes value in that particular row has been modified.
Is there anyway I can make this work for all of the text boxes in my table?
You need some way to associate a timeout with a specific input. One convenient way of doing this would be using jQuery's .data function:
var doneTypingInterval = 2000; //time in ms
//on keyup, start the countdown
$('.minutes').keyup(function(){
var typingTimer = $(this).data('timer');
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
$(this).data('timer', typingTimer);
});
//on keydown, clear the countdown
$('.minutes').keydown(function(){
clearTimeout($(this).data('timer'));
});
//user is "finished typing," do something
function doneTyping () {
console.log("DONE TYPING");
}
Also, as a sidenote, I don't really see the need for the keydown handler at all. You could do all of this with one handler (on keyup or keydown).
Example: http://jsfiddle.net/RkWH5/
Update from comment: If you need to know which input is "done", you could use $.proxy to create a function whose this value is the value of the input:
var doneTypingInterval = 2000; //time in ms
$('.minutes').keydown(function () {
var typingTimer = $(this).data('timer');
clearTimeout(typingTimer);
typingTimer = setTimeout($.proxy(doneTyping, this), doneTypingInterval);
$(this).data('timer', typingTimer);
});
function doneTyping() {
/* `this` is the element that the user is done typing in. */
$(this).css('color', 'red');
}
If you don't want to use this, you could pass a parameter to doneTyping this way:
var doneTypingInterval = 2000; //time in ms
//on keyup, start the countdown
$('.minutes').keydown(function () {
var typingTimer = $(this).data('timer')
, el = this;
clearTimeout(typingTimer);
typingTimer = setTimeout(function () {
doneTyping(el);
}, doneTypingInterval);
$(this).data('timer', typingTimer);
});
//user is "finished typing," do something
function doneTyping(el) {
/* do something with "el" */
}
Need to loop and set the timers as internal to the closure so they're independent on each one:
(trying to keep it close to your code, all I did was function wrap and loop)
var typeTimingSingle = function(elem){
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 2000; //time in ms
//on keyup, start the countdown
$(elem).keyup(function(){
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$(elem).keydown(function(){
clearTimeout(typingTimer);
});
//user is "finished typing," do something
function doneTyping () {
console.log("DONE TYPING");
}
};
$('.minutes').forEach(typeTimingSingle); // Use any loop needed

Trigger event every 2 minutes when typing

I'm looking for a way to trigger an event for every 2 minutes when you are typing, in any input or textarea.
If you then stops typing, the event will happen one more time, in the remaining time of the 2 minutes. (Hope you understand)
It is very much the same function as the one WordPress are using, when a draft is autosaved once per minute.
I am no Wordpress expert, so I can't find the function they are using in their scripts.
This is what I've got so far:
$("input, textarea").keyup(function () {
var minutes = 2;
var time = minutes * 60000;
setInterval(function () {
// Do event here
}, time);
});
It doesn't work that well. If you are typing many characters the event will be triggered multiple times right after each others. Also the event is triggered even if you are clicking on Ctrl, the arrow keys..... which is not intended.
Fiddle Demo
And I can't seem to find a good way to detect, when a user has stopped typing.
I've found this code, but I don't know how to use it, along with the other code I'm using:
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms, 5 second for example
//on keyup, start the countdown
$('#myInput').keyup(function(){
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$('#myInput').keydown(function(){
clearTimeout(typingTimer);
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
Can someone please help me?
You should not use setInterval but setTimout and spawn a new one only after the first has been run..
var saveTimer = null,
minutes = 2,
time = minutes*60000;
$("input, textarea").keyup(function () {
if (!saveTimer){
saveTimer = setTimeout(function() {
alert("Hello");
saveTimer = null;
}, time);
}
});
Demo at http://jsfiddle.net/gaby/h9pe3/
You could set a boolean to check for new user input like I did in this fiddle
var hasTyped = false;
$("input, textarea").keyup(function () {
hasTyped = true;
});
var minutes = 0.1;
var time = minutes*60000;
setInterval(function() {
if(hasTyped){
alert("Hello");
hasTyped = false;
}
}, time);
The other code you posted works a bit different: instead of running every 2 minutes, it will run 5 seconds after you stopped typing. For autosave this would be a good solution as well, depending on your preference.
You need something called time based event throttling.
Demo on http://jsfiddle.net/Gobie/LUv2u/
// taken from Remy Sharp's page
function throttle(fn, threshhold, scope) {
threshhold || (threshhold = 250);
var last,
deferTimer;
return function () {
var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
// actual code
var interval = 2 * 60 * 1000; // 2min
$("input, textarea").keyup(throttle(function () {
console.log(new Date);
}, interval));
Edit http://jsfiddle.net/Varinder/RWBYH/2/
//setup before functions
var typingTimer = null; //timer identifier
var doneTypingInterval = 2000; //time in ms, 2 second for example
//on keyup, start the countdown
$('input').keyup(function(){
clearTimeout(typingTimer); // clearing timer
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$('input').keydown(function(){
clearTimeout(typingTimer);
});
//user is "finished typing," do something
function doneTyping() {
alert("Saving draft");
}
The sample code provided works just fine: http://jsfiddle.net/Varinder/RWBYH/1/
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms, 5 second for example
//on keyup, start the countdown
$('input, textarea').keyup(function(){
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$('input, textarea').keydown(function(){
clearTimeout(typingTimer);
});
//user is "finished typing," do something
function doneTyping () {
alert("Saving draft");
}
First we want to be able to tell if the user is typing or he as stopped. We can do that by checking every couple of seconds when the last key stroke was. If it's been, let's say 30sec. since the last one we can assume that he's not typing. The second interval will autosave every two minutes and if the user is not typing anymore it will clear itself.
var isTyping = false;
var lastKeystroke = null;
var autosaveInterval = null;
$('#myInput').keyup(function() {
lastKeystroke = Date.now();
if (autosaveInterval == null) {
startAutosaveInterval();
}
});
setInterval(function() {
if (Date.now() - lastKeystroke > 30000) { // 30 sec. since last key stroke
isTyping = false;
} else {
isTyping = true;
}
}, 2000);
function startAutosaveInterval() {
autosaveInterval = setInterval(function() {
// do whatever
if (!isTyping) {
clearInterval(autosaveInterval);
autosaveInterval = null;
}
}, 2 * 60 * 1000); // every two minutes
}
I have not tested this code. but you should be able to take it from here.

Categories

Resources