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.
Related
Simply i just loop an array, and submit data with get in the loops, but i runs so fast that the server stops running. I mini Ddos myself doing this. How i can i make the loop wait until the calls finish, perhaps adding a 1 sek break between loops
$( document ).on("submit", "#add_links", function() {
var error = 0;
var success = 0;
var total = 0;
//Gets data from input field
var new_urls = $("#new_urls").val();
var array_urls = new_urls.split("\n");
var promiss = [];
array_urls.forEach(function(entry) {
var request = $.get("action.php",
{
add_link: "1",
url: encodeURIComponent(entry.trim()),
},
function(data, status){
console.log("Data: " + data + "\nStatus: " + status);
if (data == 1)
{
success++;
total++;
//update fields removed in this post
$("#success_count").html((success));
$("#total_count").html((total));
}
if (data == 2) {
error++;
total++;
//update fields removed in this post
$("#error_count").html((error));
$("#total_count").html((total));
}
});
promiss.push(request);
});
$.when.apply(null, promiss).done(function(){
//do something when done;
});
return false;
});
You could use recursive function to achieve this.
Example
$(document).on("submit", "#add_links", function() {
var error = 0;
var success = 0;
var total = 0;
var new_urls = $("#new_urls").val();
var array_urls = new_urls.split("\n");
var promiss = [];
let index = 0;
function sendAjaxCall() {
if(count >= array_urls.length) return;
var request = $.get(
"action.php",
{
add_link: "1",
url: encodeURIComponent(array_urls[index].trim())
},
function(data, status) {
console.log("Data: " + data + "\nStatus: " + status);
if (data == 1) {
success++;
total++;
$("#success_count").html(success);
$("#total_count").html(total);
}
if (data == 2) {
error++;
total++;
$("#error_count").html(error);
$("#total_count").html(total);
}
count++;
promiss.push(request);
sendAjaxCall();
}
);
}
$.when.apply(null, promiss).done(function() {
$("#close_bug_reportwindow").html(
"Import done, close tab by clicking here"
);
$("#close_icon").html('(<i class="fas fa-times"></i>)');
$("#progress").remove();
});
return false;
});
I have the following code which works fine for most cases, but the problem I am having is on mouse over . After you hover for 10 sec the content expands and then calls ajax. The Ajax is making calls 5 times instead of just once.
I am not sure why its keep calling 5 times. Can someone help me fix this so ajax call runs only once?
Here is my code snippet below and the full working fiddle demo is here
$(".previewCard-content").hide();
var timeo = null;
$("body").on("mouseenter", ".previewCard-showhide", function() { // Use rather mouseenter!
var $that = $(this); // Store the `this` reference
clearTimeout(timeo); // Clear existent timeout on m.Enter
timeo = setTimeout(function() { // Before setting a new one
$that.hide().closest('p').next(".previewCard-content").slideDown("slow");
/**************** AJAX CALL********************/
var LinkTextVal = $that.closest('.previewCard-b').find('.previewCardPageLink').text();
console.log(" LinkTextVal " + LinkTextVal);
var descPageName = LinkTextVal + ' | About';
if ($('#userID').val() !== '' && $('#userID').val() !== undefined && $('#userID').val() !== null) {
$.ajax({
url: '/localhost/biz/actions/searchBookmark' + '?cachestop=' + nocache,
type: "get",
data: {
bookmarkName: descPageName
},
success: function(response) {
if (response === true) {
$that.parents('.previewCard-b').find('.save a').addClass('saved');
$that.parents('.previewCard-b').find('.save a').addClass('active');
$that.parents('.previewCard-b').find('.save a').find(".action-text").text("Saved");
}
},
error: function(e) {
console.log('Unable to check if a bookmark exists for the user.');
}
});
}
/***************** END AJaX/SAVE BUTTON ************/
}, 1000);
}).on("mouseleave", ".previewCard-showhide", function() { // mouse leaves? Clear the timeout again!
clearTimeout(timeo);
});
$(".close-btn").on("click", function() {
var $itemB = $(that).closest(".previewCard-b");
$itemB.find(".previewCard-content").slideUp();
$itemB.find(".previewCard-showhide").show();
});
Mouse hover events happen every time the mouse moves over the element. You need is to have a boolean which checks if you have sent the AJAX Request or not, and if it hasn't send the AJAX request, else ignore the event.
$(".previewCard-content").hide();
var timeo = null;
var ajaxSent = false
$("body").on("mouseenter", ".previewCard-showhide", function() { // Use rather mouseenter!
var $that = $(this); // Store the `this` reference
clearTimeout(timeo); // Clear existent timeout on m.Enter
timeo = setTimeout(function() { // Before setting a new one
$that.hide().closest('p').next(".previewCard-content").slideDown("slow");
/**************** AJAX CALL********************/
var LinkTextVal = $that.closest('.previewCard-b').find('.previewCardPageLink').text();
console.log(" LinkTextVal " + LinkTextVal);
var descPageName = LinkTextVal + ' | About';
if ($('#userID').val() !== '' && $('#userID').val() !== undefined && $('#userID').val() !== null && !ajaxSent) {
ajaxSent = true;
$.ajax({
url: '/localhost/biz/actions/searchBookmark' + '?cachestop=' + nocache,
type: "get",
data: {
bookmarkName: descPageName
},
success: function(response) {
if (response === true) {
$that.parents('.previewCard-b').find('.save a').addClass('saved');
$that.parents('.previewCard-b').find('.save a').addClass('active');
$that.parents('.previewCard-b').find('.save a').find(".action-text").text("Saved");
}
},
error: function(e) {
console.log('Unable to check if a bookmark exists for the user.');
}
});
}
/***************** END AJaX/SAVE BUTTON ************/
}, 1000);
}).on("mouseleave", ".previewCard-showhide", function() { // mouse leaves? Clear the timeout again!
clearTimeout(timeo);
});
$(".close-btn").on("click", function() {
var $itemB = $(that).closest(".previewCard-b");
$itemB.find(".previewCard-content").slideUp();
$itemB.find(".previewCard-showhide").show();
});
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;
}
I'm just trying to learn some ajax so I wrote some code for basically an address book to pull some data. My javascript is rubbish but I cannot seem to understand what I am doing wrong, the error points to function ajaxCall but I see no issue with that function either:
(function () {
var searchForm = document.getElementById("search-form"),
searchField = document.getElementById("q"),
getAllButton = document.getElementById("get-all"),
target = document.getElementById("output");
var addr = {
search: function (event) {
var output = document.getElementById("output");
//start ajax call
ajaxCall("data/contacts.json", output, function (data) {
var searchValue = searchField.value,
addrBook = data.addressBook,
count = addrBook.length,
i;
//stop default behavior
event.preventDefault();
//clear target
target.innerHTML = "";
if (count > 0 && searchValue !== "") {
for (i = 0; i < count; i++) {
var obj = addrBook[i],
isItFound = obj.name.indexOf(searchValue);
if (isItFound !== -1) {
target.innerHTML += '<p>' + obj.name + ', ' + obj.email + '<p>';
} //end if isItFound
} //end for loop
} //end if count check
}); //end ajax call
}, //end method search
getAllContacts: function () {
var output = document.getElementById("output");
ajaxCall("data/contacts.json", output, function (data) {
var addrBook = data.addressBook,
count = addrBook.length,
i;
target.innerHTML = "";
if (count > 0) {
for (i = 0; i < count; i++) {
var obj = addrBook[i];
target.innerHTML += '<p>' + obj.name + ', ' + obj.email + '<p>';
} //end for loop
} //end if
}); //end ajax call
}, //end method getAllContacts
setActiveSection: function () {
this.parentNode.setAttribute("class", "active");
}, //end method setActiveSection
removeActiveSection: function () {
this.parentNode.removeAttribute("class");
}, //end method removeActiveSection
addHoverClass: function () {
searchForm.setAttribute("class", "hovering");
}, //end method addHoverClass
removeHoverClass: function () {
searchForm.removeAttribute("class");
} //end method removeHoverClass
} //end addr object
searchField.addEventListener("keyup", addr.search, false);
searchField.addEventListener("focus", addr.addActiveSection, false);
searchField.addEventListener("blur", addr.removeActiveSection, false);
getAllButton.addEventListener("click", addr.getAllContacts, false);
searchForm.addEventListener("submit", addr.search, false);
searchForm.addEventListener("mouseover", addr.addHoverClass, false);
searchForm.addEventListener("mouseout", addr.removeHoverClass, false);
})(); //end anon function
function getHTTPObject() {
var xhr;
//in most cases this first if is executed
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
//otherwise support crappy IE6 and below
else if (window.ActiveXObject) {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
}
return xhr;
}
function ajaxCall(dataUrl, outputElement, callback) {
//get ajax object
var request = getHTTPObject();
outputElement.innerHTML = "Loading...";
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
//good ajax response..now save it
var contacts = JSON.parse(request.responseText);
if (typeof callback === "function")
callback(contacts);
} //end upper if
} //end onreadystatechange
request.open("GET", dataUrl, true);
request.send(null);
}
The javascript development tools keeps giving me an unexpected token } on line 97 but that changes all so often. Am I missing a curly brace somewhere?
I did put your code to this fiddle and fixed the errors as far as i can.
You missed some curly braces and semicolons. Also, you used ajaxCall() and getHTTPObject() before they were declared. Check it out. Unfortunately, i dont know if the problem is already fixed, but now the code is valid at least :)
Btw: (in my opinion) such long Code-Samples are always better pasted into a fiddle. Not only because you can focus on the probably messy code here while referring to the complete code sample somewhere else, also because you can make sure that there are no syntax-errors as you can quickly validate you code using jsLint before asking the question here.
You must re-check what your JSON response is, in console, and see if it is invalid.
Because at that very 97 line you say that you are parsing a response.
I have been struck up in a condition where i need to halt the Confirm box. This is what I have done:
function onBeforeClientInsert(record) {
var eventtype = parseInt(record. < %= CEO.FieldEvaluator.GetEvaluatorByDId("EVENT_TYPE_ID").GetFieldDataFieldId() % > );
var begindate = record. < %= CEO.FieldEvaluator.GetEvaluatorByDId("BeginDate").GetFieldDataFieldId() % > ;
var enddate = record. < %= CEO.FieldEvaluator.GetEvaluatorByDId("EndDate").GetFieldDataFieldId() % > ;
$.ajax({
type: "POST",
url: "Data.aspx/CheckInsertRecord",
data: "{EventType:'" + eventtype + "',BeginDate:'" + begindate + "'," + "EndDate:'" + enddate + "' }",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
if (msg.d == "No duplicate") {
} else {
alert(msg.d);
eval("var data = " + msg.d + ";");
}
var i = 0;
alert(i);
alert(data[i]);
do {
$("#beginDate").html(data[i].BeginDate);
$("#eventTypeID").html(data[i].EVENT_TYPE_ID);
$("#endDate").html(data[i].EndDate);
$("#beginlatlong").html(data[i].BeginLATLONG);
$("#endlatlong").html(data[i].EndLATLONG);
var modal = document.getElementById('Div1');
modal.style.display = '';
modal.style.position = 'fixed';
modal.style.zIndex = '100';
modal.style.left = '30%';
modal.style.top = '10%';
var screen = document.getElementById('modalScreen');
screen.style.display = '';
i++;
if (confirm("Are you sure you want to continue?") == false) {
hide();
continue;
}
}
while (msg.d != null);
}
});
if (confirm("Are you sure you want to insert this new record ?") == false) {
hide();
return false;
}
if (Page_ClientValidate("<%= CEO.GridUtils.Global_ValidationGroupName%>")) {
hide();
SetPostBackCause('INSERT');
return true;
}
return false;
}
So,the problem has been that
if (confirm("Are you sure you want to insert this new record ?") == false) {
hide();
return false;
}
would be run immediately after the confirm box
if(confirm("Are you sure you want to continue?")==false){
hide();
continue;
}
But i want it to be halted until the user clicks something on the first confirm box. Can u please let me know how to do this? Also Can u let me know any other way to do this, if I'm approaching it in wrong way?
Ajax is asynchronous.
You need to move all dependent code into the success callback.
success: function (msg) {
// snip ...
if (confirm("Are you sure you want to insert this new record ?") == false) {
hide();
}
if (Page_ClientValidate("<%= CEO.GridUtils.Global_ValidationGroupName%>")) {
hide();
SetPostBackCause('INSERT');
}
}
You could use async: false to make the request sychronous but I do not recommend this.
You need to place all of this:
if (confirm("Are you sure you want to insert this new record ?") == false) {
hide();
return false;
}
if (Page_ClientValidate("<%= CEO.GridUtils.Global_ValidationGroupName%>")) {
hide();
SetPostBackCause('INSERT');
return true;
}
within your AJAX callback if you want it to run after the first dialog. Currently, you set the callback, and then call the code above. If your internet connection was really slow, the first dialog you are seeing could theoretically come after the second you are seeing.
Have you considered the async: false option to $.ajax?