Below is my full JS file beginning to end. I set a variable 'rendered' outside all functions. Then, since it is required in the if check just before issuing a POST request I want to use it as flag and update it's value to be true upon post request completion. The issue is that all the console.log calls do print the changed value but it does not persist. When again the position coordinates are fetched automatically in the watchPosition function, calculateDistance function is invoked again. Then, the previous saved value with "window.rendered = true" is not there, it is actually false and it enters the if condition. How can I achieve the goal of not issuing the post request again until another post request changes this flag variable back to false?
var rendered = false;
function myfunc() {
rendered = true;
console.log(window.rendered);
}
function updatePosition() {
if(navigator.geolocation) {
navigator.geolocation.watchPosition(calculateDistance);
}
else {
console.log("Geolocation is not supported by this browser.")
}
}
function calculateDistance(position) {
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var target = new google.maps.LatLng(55.85365783555865, -4.288739944549508);
var dis = google.maps.geometry.spherical.computeDistanceBetween(pos, target);
console.log(window.rendered);
var self = this;
if(dis <= 1000 && dis >= 0 && window.rendered == false) {
console.log("Distance"+dis);
var url = '/dogpark/near_park/';
var csrftoken = getCookie('csrftoken');
$.ajax({
url: url,
type: "POST",
data: {
csrfmiddlewaretoken: csrftoken,
in_proximity : 1
},
async: false,
success: function(data) {
myfunc();
self.rendered = true;
window.rendered = true;
alert(window.rendered);
window.location = '/dogpark/near_park/';
},
complete: function(data) {
console.log("Trying");
window.rendered = true;
alert(window.rendered);
},
error: function(xhr, errmsg, err) {
console.log(xhr.status+": "+xhr.responseText);
},
});
}
window.onload = updatePosition()
A simple way is to use another variable to track the ajax call completion. So that you don't make another Ajax call until the previous one returns a repsonse(success/failure).
var isWaitingForResponse = false;
...
function calculateDistance(position) {
...
if(dis <= 1000 && dis >= 0 && window.rendered == false && !isWaitingForResponse) {
isWaitingForResponse = true;
...
success: function(data) {
isWaitingForResponse = false
...
},
complete: function(data) {
isWaitingForResponse = false
...
},
error: function(xhr, errmsg, err) {
isWaitingForResponse = false
...
}
...
Related
This question already has answers here:
Ajax call is never success
(2 answers)
Closed 5 years ago.
I have a little issue,
I'm working on a contact form,
My problem is that the ajax call doesn't show a success message, it sticks
on "sending"
the call is working because it goes to the PHP page and runs the function from there, so everything works fine expect the success message.
I will really glad for assistance, thanks!
this is the JavaScript page:
var nameRegx = /^[' a-zא-ת]+(\s[' a-zא-ת]+)*$/i,
emailRegx = /^([\w-\.]+#([\w-]+\.)+[\w-]{2,4})$/,
phoneRegx = /^(?:0(?!(5|7))(?:2|3|4|8|9))(?:-?\d){7}$|^(0(?=5|7)(?:-?
\d){9})$/,
td = 'p.text-danger',
sa = '#submitAnimate',
sb = '#submitBtn',
nf = '#name',
ef = '#email',
pf = '#phone',
mf = '#message';
$(sa).hide();
$('#contactForm').on('submit', function (event) {
event.preventDefault();
var isValid = true;
$(td).text('');
$(' input[type="text"], textarea').removeClass('error');
$(sb).attr('disabled', true);
$(sa).show();
var userData = {
name: $(nf).val().trim(),
email: $(ef).val().trim(),
phone: $(pf).val().trim(),
message: $(mf).val().trim()
};
if (userData.name.length < 2 || userData.name.length > 70 ||
!nameRegx.test(userData.name)) {
isValid = false;
setError(nf, 'name');
}
if (!emailRegx.test(userData.email)) {
isValid = false;
setError(ef, 'email');
}
if (!phoneRegx.test(userData.phone)) {
isValid = false;
setError(pf, 'phone');
}
if (userData.message.length < 3) {
isValid = false;
setError(mf, 'message');
}
if (!isValid) {
$(sb).attr('disabled', false);
setTimeout(function(){ $(sa).hide(); }, 500);
} else {
$.ajax({
url: "assets/contact_form/process-contact.php",
type: "POST",
dataType: "html",
data: userData,
beforeSend: function () {
$( sb ).val('Sending...');
},
success: function (response) {
if (response == true) {
successmessage = 'Data was succesfully captured';
$("#gmsg").text(successmessage);//THIS MESSAGE DOESN'T APPEAR
} else {
$( sb ).val('Can not send, please try latter');
}
}
});
}
});
$('input[type="text"], textarea').on('keyup', function () {
$(this).next().text('');
});
function setError(target, field) {
setTimeout(function () {
$(target).val('').addClass('error');
$(target).next().text('* Please enter your ' + field);
}, 500);
}
In success : function(response) the object response is not a Boolean. it is the returned response of the ajax call, it will be a string.
just remove the if(response == true) from your code.
then, it will work fine.
I am saving data on a save button click that calls ajax and passing json data to a controller method but when we save it loading starts and suddenly stop though the data is not saved.
It is not working I have tried it in all way but not working please help me on this.
<button type="button" id="saveDeleg" class="btn_reg_back btnmainsize btnautowidth btngrad btnrds btnbdr btnsavesize " aria-hidden="true" data-icon="">#Resources.Resource.Save</button>
$('#saveDeleg').click(function() {
var response = Validation();
if (!response) {
return false;
}
$("#overlay").show();
$('.loading').show();
if ($('#organName').val() == '') {
$('#validorganisation').show();
return false;
} else {
$('#validorganisation').hide();
}
//Contact name
var SubDelegation = $('#subdelegation').is(':checked');
var CopyNotification = $('#copynotification').is(':checked');
var ArrangementId = $("#ArrangementId").val();
var paramList = {
ArrangementId: ArrangementId,
ArrangementName: $('#arrangName').val(),
OrganisationName: $('#organName').val(),
OrganisationId: $('#OrganisationId').val(),
ContactName: $('#contactName').val(),
ContactId: $('#ContactId').val(),
SubDelegation: $('#subdelegation').is(':checked'),
CopyNotification: $('#copynotification').is(':checked'),
ContactType: $('#ContactType').val(),
SelectedTypeName: $("input[name$=SelectedType]:checked").val()
};
setTimeout(function() {
$.ajax({
async: false,
type: "POST",
url: '#Url.Action("SaveDelegation", "Structures")',
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(paramList),
processdata: true,
success: function(result) {
//stopAnimation()
paramList = null;
if (result == 0) {
window.location.href = '../Structures/MyDelegationArrangement';
} else if (result == 1) {
window.location.href = '../Structures/CreateDelegation';
} else if (result == 2) {
window.location.href = '../Home/Error';
} else if (result == 3) {
window.location.href = '../Account/Login';
} else {
//validation message
alert('Error');
}
},
error: function() {},
complete: function() {
$("#overlay").hide();
$('.loading').hide();
}
});
}, 500);
});
The problem with the loading indicator is because you used async: false which locks up the UI. Remove that setting.
Also note that if the data is not being saved I would assume that your AJAX call is returning an error. If so, check the console to see the response code. It may also be worth putting some logic in the error callback function to give you some information on whats happened, as well as inform your users about what to do next.
I am wanting to implement a recaptcha process that captures all ajax requests before they go through - the desired process would be as follows:
User completes an action which is going to cause an ajax request of some sort.
If the user has already completed the recaptcha process, the ajax request proceeds without further delay
If the user has not completed the recaptcha process, put the ajax request "on hold" temporarily until the recaptcha process is completed, then continue the ajax request.
I have got things to a state where I intercept the call, however I don't know how to put it on hold temporarily. Here's the relevant code:
<script>
var captchaValidated = null;
var currentRequests = [];
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.url != "/ValidateCaptcha") {
if (captchaValidated == null || captchaValidated == false) {
if (captchaValidated == null){
openRecaptcha();
} else {
verifyCaptcha(); //see async question in method
}
if (!captchaValidated) {
jqXHR.abort();
} else {
//let the original request proceed now - but how?!
}
}
}
});
function verifyCaptcha() {
var grecaptcha = $("g-recaptcha-response");
var encodedResponse;
if (grecaptcha != null) {
encodedResponse = grecaptcha.val();
$.ajax({
async: false, //set to false so that the calling method completes rather than async - what do you think?
headers: headers,
cache: false,
url: "/ValidateCaptcha",
type: 'POST',
contentType: 'application/json',
success: function (data) {
//parse the data - did we get back true?
captchaValidated = data;
},
error: function (raw, textStatus, errorThrown) { captchaValidated = null; alert("Validate ReCaptcha Error: " + JSON.stringify(raw)); },
data: JSON.stringify({ "encodedResponse": encodedResponse })
});
}
}
function invalidateCaptcha(){
captchaValidated = null;
}
function openRecaptcha() {
grecaptcha.render('recaptcha', {
'sitekey': "thekey",
'callback': verifyCaptcha,
'expired-callback': invalidateCaptcha,
'type': 'audio image'
});
$("#recaptchaModal").modal('show');
}
</script>
Any suggestions of how to proceed would be appreciated, thanks in advance!
Thank you #Loading and #guest271314 for your help in pointing me in the right direction that helped me get things figured out. I've pasted how I accomplished it below - perhaps it will be of help to someone else. Of course if anyone would like to weigh in on my implementation please do.
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCaptcha&render=explicit&hl=en" async defer></script>
<script>
var captchaValidated = null;
var currentRequests = [];
var captchaPrompted = false;
var captchaReady = false;
var resetCaptcha = false;
function onloadCaptcha() {
captchaReady = true;
captcha = grecaptcha.render('recaptcha', {
'sitekey': '<yoursitekey>',
'callback': verifyCaptcha,
'expired-callback': invalidateCaptcha,
'type': 'audio image'
});
}
var deferredCaptcha = null;
var promiseCaptcha = null;
var captcha = null;
function openRecaptcha() {
if (!captchaReady) {
setTimeout(openRecaptcha, 50);
}
if (captchaPrompted) {
return;
}
captchaPrompted = true;
var captchaTimer = setInterval(function () {
if (captchaValidated != null) {
if (captchaValidated) {
deferredCaptcha.resolve();
} else {
deferredCaptcha.reject();
captchaValidated = null;
}
}
}, 100);
if (resetCaptcha) {
captcha.reset();
}
deferredCaptcha = $.Deferred();
promiseCaptcha = deferredCaptcha.promise();
promiseCaptcha.done(function () {
//captcha was successful
clearInterval(captchaTimer);
//process the queue if there's items to go through
if (currentRequests.length > 0) {
for (var i = 0; i < currentRequests.length; i++) {
//re-request the item
$.ajax(currentRequests[i]);
}
}
});
promiseCaptcha.fail(function () {
//captcha failed
clearInterval(captchaTimer);
currentRequests = []; //clear the queue
});
$("#recaptchaModal").modal('show');
}
function verifyCaptcha() {
resetCaptcha = true;
var response = $("#g-recaptcha-response").val();
var encodedResponse;
// confirm its validity at the server end
$.ajax({
headers: headers,
cache: false,
url: "/ValidateCaptcha",
type: 'POST',
contentType: 'application/json',
success: function (data) {
captchaValidated = data;
if (!data) {
captchaPrompted = false;
}
},
error: function (raw, textStatus, errorThrown) { captchaValidated = false; captchaPrompted = false; alert("WTF Validate ReCaptcha Error?!: " + JSON.stringify(raw)); },
data: JSON.stringify({ "encodedResponse": response })
});
}
function invalidateCaptcha(){
deferredCaptcha.reject();
captchaValidated = null;
resetCaptcha = true;
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (settings.url == '/ValidateCaptcha' || captchaValidated) {
// we're validating the captcha server side now or it's already been validated - let it through
} else {
if (typeof settings.nested === 'undefined'){
settings.nested = true; //this flag is to determine whether it's already in the queue
currentRequests.push(settings); //add the request to the queue to be resubmitted
//prompt them with the captcha
openRecaptcha();
}
return false; // cancel this request
}
}
});
</script>
At $.ajaxPrefilter() use .then() chained to openCaptcha to call verifyCaptcha
if (captchaValidated == null){
openRecaptcha().then(verifyCaptcha);
}
at verifyCaptcha use .is() with parameter "*" to check if an element exists in document
if (grecaptcha.is("*")) {
at openRecaptcha(), if grecaptcha.render does not return asynchronous result return jQuery promise object using .promise(); else chain to grecaptcha.render and $("#recaptchaModal").modal('show'); using $.when()
return $("#recaptchaModal").modal('show').promise()
or
return $.when(grecaptcha.render(/* parameters */)
, $("#recaptchaModal").modal('show').promise())
Something like this? (pseudo-code)
verified = false;
$('#myButton').click(function(){
if (!verified) verify_by_captcha();
if (verified){
$.ajax(function(){
type: 'post',
url: 'path/to/ajax.php',
data: your_data
})
.done(function(recd){
//ajax completed, do what you need to do next
alert(recd);
});
}
});//end myButton.click
I have a radio button that displays a list of records in a telerik grid. When the radio button is checked, it displays complete and incomplete records. However, the user wants a way of displaying only complete or incomplete records. I added two mutually exclusive checkboxes. The user can either check the complete or incomplete checkbox to display the data. It works fine on my local, but it does not work well on the server. The first time, the user has to click the checkbox two or three times before it can keeps the state. In addition, if complete is checked and the user checked incomplete next, the checkmark will go back to complete. The user has to do it a second times. What I am doing wrong here?
Here is the html for the checkbox
#Html.CheckBox("complete", SessionWrapper.currentEncounter.complete, new { id = "chkComplete", onclick = "chkInCompleteOption(1);this.form.submit();" }) <strong>Complete</strong>
#Html.CheckBox("Incomplete", SessionWrapper.currentEncounter.incomple, new { id = "chkInComplete", onclick = "chkInCompleteOption(2);this.form.submit();" }) <strong>Incomplete</strong>
//Here is the javascript
var completeCheck = '#SessionWrapper.currentEncounter.complete';
var inCompleteCheck = '#SessionWrapper.currentEncounter.incomplete';
function chkInCompleteOption(e) {
if (e == 1) {
var cc = $('#chkComplete').is(':checked');
var data = { "complete": cc, "inComplete": false };
var url = '#Url.Action("CompletedOption", "Orders")';
$.ajax({
url: url,
type: 'post',
dataType: 'text',
data: data,
success: function (data) {
testComplete();
return true;
},
error: function (error) {
alert("An error has occured.");
return false;
}
});
}
else if (e == 2) {
var inc = $('#chkInComplete').is(':checked')
var data = { "complete": false, "inComplete": inc };
var url = '#Url.Action("CompletedOption", "Orders")';
$.ajax({
url: url,
type: 'post',
dataType: 'text',
data: data,
success: function (data) {
testInComplete();
return true;
// $('#chkComplete').removeAttr("checked", "checked");
// $('#chkInComplete').attr("checked", "checked");
},
error: function (error) {
alert("An error has occured.");
return false;
}
});
}
}
function testInComplete() {
if (inCompleteCheck == true) {
inCompleteCheck = $('#chkInComplete').attr("checked", "checked");
document.getElementById('chkInComplete').checked = true;
} else {
$('#chkInComplete').removeAttr("checked");
}
}
function testComplete() {
if (inCompleteCheck == true) {
completed = $('#chkComplete').attr("checked", "checked");
document.getElementById('chkComplete').checked == true;
} else {
$('#chkComplete').removeAttr("checked");
}
}
//Setting the mutually exclusive value on the server side
public bool CompletedOption(bool complete, bool inComplete)
if (inComplete == true && complete == true)
{
return false;
}
if (complete == true)
{
SessionWrapper.currentEncounter.complete = true;
}
else if (SessionWrapper.currentEncounter.complete == true && (complete == null || inComplete == null))
{
SessionWrapper.currentEncounter.complete = true;
}
else
{
SessionWrapper.currentEncounter.complete = false;
}
if (inComplete == true)
{
SessionWrapper.currentEncounter.incomplete = true;
}
else if (SessionWrapper.currentEncounter.incomplete == true && (complete == null || inComplete == null))
{
SessionWrapper.currentEncounter.incomplete = true;
}
else
{
SessionWrapper.currentEncounter.incomplete = false;
}
return true;
}
I found the issue. The server side was being updated properly; however, the ajax was returning an error message every time it executed. The method on the server side was returning a Boolean when a string was expected. I've also set async and cache to false. I ran the application again, and it works.
//Change Method Signature from boolean to string
public string CompletedOption(bool complete, bool inComplete)
{
return "true";
}
ajax post
$.ajax({
url: url,
type: 'post',
dataType: 'text',
async: false, //Added
cache: false, //Added
data: data,
success: function (data) {
return data;
},
error: function (error) {
alert("An error has occured.");
return false;
}
});
My code can get data in Chrome console
but cant get data in my program
code like this:
$(document).ready(function () {
var theme = '';
var source = [];
var rsps = '';
$.ajax({
url: '#Url.Content("~/Home/RoleMenus")',
type: "GET",
cache: false,
success: function(response, status, xhr) {
rsps = response;
source = eval(response);
},
error: function(XMLHttpRequest,textStattus,errorThrown) {
$('#jqxErrorMsg').html(errorThrown);
}
});
for(var src in source) {
if (src.items.legth > 0) {
src.expanded = true;
}
}
// Create jqxTree
$('#jqxTree').jqxTree({ source: source, theme: theme});
$('#jqxTree').bind('select', function (event) {
var args = event.args;
var item = $('#jqxTree').jqxTree('getItem', args.element);
for (var menu in source[0]) {
if (item.label == menu.label) {
window.location = menu.actionUrl;
//break;
}
}
});
});
=====update=====
the response is right, if i move
// Create jqxTree
$('#jqxTree').jqxTree({ source: source, theme: theme});
into success: function(response, status, xhr) {}
the menu shows correctly
but the source variable still has no value outside
=====solved====
for (var menu in source[0])
should be
for (int i=0;i<source[0].length;i++)
The ajax call is async so source variable may not be initialized yet. Try putting
for(var src in source) {
if (src.items.legth > 0) {
src.expanded = true;
}
}
// Create jqxTree
$('#jqxTree').jqxTree({ source: source, theme: theme});
in the succes function.