I have html form with three elements - buttons start and stop and text area. Once start button is pressed, I would like to do multiple ajax requests and once result is received to update the text area, once stop is pressed, processing of ajax requests should be stopped.
I tried to do something like below:
$(document).ready(function(){
var inProgress = false;
$("#stop").click(function() {
inProgress = false;
});
$("#start").click(function() {
inProgress = true;
while (inProgress) {
$('#textarea').html($('#textarea').val()+sometext+'\n');
$.ajax({url: 'http://example.com'})
.done(function(data, textStatus, jqXHR) {
$('#textarea').html($('#textarea').val()+someresult+'\n');
});
}
});
But it doesn't work as expected - browser tab hangs. What is wrong with my code?
Don't use while loop. You should do it in an asynchoronous way: At the end of .done function, put another asynchronous ajax call.
// other stuff goes here
function doRequest() {
$.ajax({url: 'http://example.com'})
.done(function(data, textStatus, jqXHR) {
$('#textarea').html($('#textarea').val()+someresult+'\n');
if (inProgress) doRequest();
});
}
$("#start").click(function() {
inProgress = true;
$('#textarea').html($('#textarea').val()+sometext+'\n');
doRequest();
});
Well, since $.ajax is asynchronous by default, you are making a loooot of XHR (ajax calls) ! ;-)
Try this :
$(document).ready(function(){
var inProgress = false;
$("#stop").click(function() {
inProgress = false;
});
$("#start").click(function() {
inProgress = true;
refresh();
});
function refresh() {
$('#textarea').html($('#textarea').val()+sometext+'\n');
$.ajax({url: 'http://example.com'})
.done(function(data, textStatus, jqXHR) {
$('#textarea').html($('#textarea').val()+someresult+'\n');
if (inProgress) refresh();
});
}
});
Probably because the browser is busy doing requests and it cannot listen other events. Try to put the code in a function and then use the
setTimeout( function_reference, timeoutMillis );
with a reasonable timeout.
See this code as an example:
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
// add a zero in front of numbers<10
m = checkTime(m);
s = checkTime(s);
document.getElementById("txt").innerHTML = h+ ":" + m + ":" + s;
t = setTimeout(function(){startTime()}, 500);
}
function checkTime(i) {
if (i<10) {
i = "0" + i;
}
return i;
}
Related
I have a button when clicked send an ajax request to fire a PHP function which takes a while for it to complete. I have a timed function that checks the status of the first function. The problem being is that these two have a status of pending, and the function that is on a timer seems to freeze until the first function is completed.
$(document).ready(function() {
var ripstatus;
var intervalID;
$("#ripe_start").click(function() {
if (ripstatus) return;
console.log('started');
$("#ripe_start").addClass("ripe_start_activate");
$("#ripe_start").removeClass("ripe_clickable");
getid('ripe_start').innerHTML = 'Initializing';
ripe_getstatus();
intervalID = window.setInterval(ripe_getstatus(), 500);
})
function ripe_getstatus() {
console.log('getting number ' + ripstatus);
$.get('./?ajax=1&callfunction=returnNumScan', function(data) {
getid('ripe_start').innerHTML = data + ' file(s) left to organize';
});
}
$('#ripe_start').on('transitionend webkitTransitionEnd oTransitionEnd', function() {
console.log('ended');
doextorg();
});
function doextorg() {
if (ripstatus == 1) return;
console.log('exc org processing ' + ripstatus);
ripstatus = 1;
$.ajax({
url: "./?ajax=1&callfunction=organize",
context: document.body
}).done(function(output) {
clearinterval(intervalID);
$("#ripe_start").removeClass("ripe_start_activate");
getid('ripe_start').innerHTML = 'Complete ' + output + ' File(s) organized';
});
} //end function
});
I have a start button which triggers a function.
<button type="button" onclick="start()">START</button>
Here is my java script
function start() {
var cookieValue = document.getElementById('balance').getAttribute('value');
if (cookieValue == 0){
alert("insufficient funds");
exit();
}else{
var url = $("#url").val() + '.php?check=';
console.log(url);
var line = $("#ccs").val();
var linesend = line.split("\n");
linesend.forEach(function(value, index) {
setTimeout(
function start() {
Array.prototype.randomElement = function () {
return this[Math.floor(Math.random() * this.length)]
}
$.ajax({
url: url + value,
type: 'GET',
async: true,
success: function(result) {
if (result.match("success")) {
removeline();
live(result);
}else {
removeline();
dead(result);
}
}
});
},2500 * index);
});
}
}
How do I stop this 2500 * index loop right here using a stop function? Cause I wanted a stop button for this one
Clear timeout?
var timeout = setTimeout(start, 2500*index);
clearTimeout(timeout);
I have a script that makes an ajax GET request once the user gets near the bottom of the page.
$(function(){
window.addEventListener('scroll', fetchImages);
window.addEventListener('scroll', fetchNotifications);
});
function fetchImages() {
var imagePage = $('.endless-pagination').data('next-page');
if(imagePage !== null) {
var last = $('.endless-pagination').data('last-item');
var within = $('.endless-pagination').data('within');
var orderBy = $('.endless-pagination').data('order-by');
clearTimeout( $.data( this, "scrollCheckImages" ) );
$.data( this, "scrollCheckImages", setTimeout(function() {
var scroll_position_for_images_load = $(window).height() + $(window).scrollTop() + 900;
if(scroll_position_for_images_load >= $(document).height()) {
$(".dual-ring-container").show();
$.ajax({
url: imagePage,
method: 'get',
cache: false,
})
.done(function( data ) {
if (last != null) {
$(".dual-ring-container").hide();
var newPageUrl = data.next_page + "&within=" + within + "&orderBy=" + orderBy + "&last=" + last;
$('.endless-pagination').append(data.images);
$('.endless-pagination').data('next-page', newPageUrl);
setResizeVariables();
updateReadMore();
initMentions();
}
});
}
}, 350))
}
}
However, there's a bit of a problem. This get request is essentially being spammed since the function is being triggered by a "scroll" event listener.
How could I make it so that this request can only be called once every few seconds or so?
Use a variable that keeps track of the last time the main body of the function was run, and return early if it was run less than a few seconds ago:
let lastCall = 0;
function fetchImages() {
const now = Date.now();
if (now - lastCall < 3000) return;
lastCall = now;
// ...
Note that you can use a similar strategy to reduce unnecessary indentation hell. Rather than
if (imagePage !== null) {
// big block of code
}
} // end of fetchImages
you can use
if (imagePage === null) return;
which will have the exact same effect, but will make your code a bit more readable.
i have a JavaScript/jQuery code function that is supposed to call itself up to ten times if there is no data available (determined by web service call). I have implemented the code but the logging inside the web service call indicates that it is called only 1 or 2 times. What is the error in this code?
function CallIsDataReady(input) {
var timer;
var count = 0;
$.ajax({
url: "https://www.blah.com/services/TestsService.svc/IsDataReady",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
success: function (data) {
if (!data) {
setTimeout(function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}, 1000);
} else {
console.log("data returned - returning true");
//Continue as data is ready
var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
GetDataFromServer(0, tableView.get_pageSize());
}
},
error: function (jqXHR, textStatus, errThrown) {
console.log("AJAX call failed in CallIsDataReady");
console.log(errThrown);
}
});
}
EDIT: It should try up to ten times and then quit, not go on to the GetDataFromServer. It should return an error. How can I do that?
setTimeout is meant to trigger a function call once, and only once.
Repeat call to setTimeout from within your timeouted callback if you want this to work:
function CallIsDataReady(input) {
var timer;
var count = 0;
function callWebService(){
console.log('calling webservice');
$.ajax({
url: "https://www.blah.com/services/TestsService.svc/IsDataReady",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
success: function (data) {
console.log('count = ' + count);
console.log('data = ' + data);
if (!data){
if(count < 10) {
count++;
setTimeout(callWebService, 1000);
} else {
count = 0;
}
}else{
console.log("data returned - returning true");
//Continue as data is ready
var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
GetDataFromServer(0, tableView.get_pageSize());
}
},
error: function (jqXHR, textStatus, errThrown) {
console.log("AJAX call failed in CallIsDataReady");
console.log(errThrown);
}
});
};
callWebService();
}
count is being reset every time CallIsDataReady is called.
Replace:
function CallIsDataReady(input) {
var timer;
var count = 0;
With:
var count = 0;
function CallIsDataReady(input) { // You won't need the `timer` variable
This will set count to 0 before the first call of CallIsDataReady. Then, each call, the count will be incremented.
Now, to handle that counter properly, replace:
if (!data) {
setTimeout(function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}, 1000);
With:
if (!data && count !== 10) {
setTimeout(function(input) {
CallIsDataReady(input);
count++;
}, 1000);
Now, I'm not sure what inputInner is supposed to be, so I replaced that with input. If you want a different variable to be passed to subsequent calls, you'll have to assign a value to inputInner.
In addition to making timer and count into global variables, I think you need to assign a value to inputInner when you execute it:
if (!data) {
setTimeout(function() {
function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}(input);
}, 1000);
}
It looks like you are trying to use setTimeout instead of setInterval. setTimeout calls function only once after certain amount of time. setInterval will be calling your function in intervals until you call clearInterval.
http://www.w3schools.com/jsref/met_win_setinterval.asp
timer= setInterval(function(inputInner) {
CallIsDataReady(inputInner);
count++;
if (count == 10) {
clearInterval(timer);
count = 0;
}
}, 1000);
I have a function which works when the enter key is hit or when the submit button is pressed...I am using this...
$('#searchBtn').click(function(){
var str = $('#searchTxt').val();
$.get(searchStr+"&text=" + str, function(data){
fetchPhoto(data);
}, "json");
});
$('#searchTxt').keydown(function(event){
if (event.which == 13)
var str = $('#searchTxt').val();
$.get(searchStr+"&text=" + str, function(data){
fetchPhoto(data);
}, "json");
});
fetchPhoto is a pretty long process as it hits a few external libraries and if someone makes it go off multiple times it gives some strange results(multiple results)
How do I prevent this from happening? Sort of need a timer or a lock or something...
You can add a flag to prevent the .get() being fired multiple times.
Try this:
var ok_to_click = true; // this var will prevent the $.get() to be fired when its value is false
$('#searchBtn').click(function () {
var str = $('#searchTxt').val();
if (ok_to_click) {
$.get(searchStr + "&text=" + str, function (data) {
fetchPhoto(data);
ok_to_click = true;
}, "json");
ok_to_click = false;
}
});
$('#searchTxt').keydown(function (event) {
if (event.which == 13) var str = $('#searchTxt').val();
if (ok_to_click) {
$.get(searchStr + "&text=" + str, function (data) {
fetchPhoto(data);
ok_to_click = true;
}, "json");
ok_to_click = false;
}
});
You can disable button until your process get finished and then enable it.