Why does AJAX + GET refresh page? - javascript

I try a lot of ways to prevent this, but nothing works which is puzzling.
This is the route for get.
router.get('/some', function(request, response, next) {
console.log('> info: some');
response.send({"hello": "world"});
}
This is the AJAX part hooked to onClick of an element.
on_click = function(event) {
//console.log(event.href);
event = event || window.event;
var target = event.target || event.srcElement;
if (target.nodeType == 3)
target = target.parentNode;
target.preventDefault();
target.stopPropagation();
target.stopImmediatePropagation();
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
$.ajax({
type: 'GET',
url: target.href,
dataType: 'json',
cache: false
})
.done(function(received_data) {
$('.container').html('<h1>hello here</h1>');
return false;
})
.fail(function(xhr, status, error) {
alert(xhr.responseText);
return false;
});
return false;
}
I expect to see "hello here". It works for a small test program. But when I add to my development code, it always show a white page with the JSON string of hello world.
So far I have tried the followings.
send string instead of JSON object directly
change dataType to text
set processData to false
preventDefault, stopPropagation, stopImmediatePropagation
I apology that I cannot upload the development code, but any guess why it is so stubborn to refresh the page?
BTW, for POST, it works perfectly.
This is the related element:

Instead of
response.send({"hello": "world"});
Try
response.json({"hello": "world"});
Express docs: https://expressjs.com/en/api.html#res.json
Using response.json() correctly sets the Content-Type header in the response.

Related

preventDefault of a link depending on the Ajax response

I've created a controller in Magento which check whether or not there are products in a list. If there are products in list it will return true otherwise false.
Here is the front-end which triggers the ajax call, bare in mind I can not change this to be a form. It has to be a link.
Compare Products
Here is the ajax call.
jQuery(".compare-product-link").on("click", function(e) {
jQuery.ajax({
async : false,
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
//console.log(data);
if(data.isAllowed != true) {
e.preventDefault();
}
}
});
});
The problem I have is that the async is deprecated and is not good for user experience, saying that there are many answer out there which add a delay of 3 seconds, I also don't want that because thats not good for user experience.
I've also tried using a promise call but it only works with async : false.
jQuery(".compare-product-link").on("click", function(e) {
var response = false;
jQuery.ajax({
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
console.log(data);
if(data.isAllowed) {
response = true;
}
}
}).done(function (){
console.log(response);
if(response != true) {
e.preventDefault();
}
});
});
EDIT
Another problem I also have is if I store the link into a variable and then open a new window as so window.location = href; most browser will block it and users will have to manually accept pop ups from the target site, which again is not good for user experience.
you cannot really achieve this using preventDefault like you said - because of async.
what I would try is:
preventDefault
store href as a variable
call ajax
redirect to href variable if true and not if false
jQuery(".compare-product-link").on("click", function(e) {
var href = $(this).attr('href');
e.preventDefault();
jQuery.ajax({
async : false,
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
//console.log(data);
if(data.isAllowed == true) {
window.location = href;
}
}
});
});
if you need to create a link action you can use this code:
function triggerClick(url){
$('body').append('<span id="click_me_js"></span>');
$('span#click_me_js a')[0].click();
$('span#click_me_js').remove();
}
which will mimic a regular click on <a>

Jquery - Ajax : Unhandled multiple clicks event with ajax button "on Click method"

I have a button where i'm injecting an ajax request to a distant web service.
the traitment takes effects after checking a condition given from the success of another ajax request (thats why i am usung "ajaxSuccess")
My fonction looks like this :
$('body').on('click', '#btn', function (e) {
$(document).ajaxSuccess(function (event, xhr, settings) {
if (settings.url === window.annonce.route.testService) {
xhr = xhr.responseJSON;
var msg = {},
if (xhr == 1) { //case of traitement to be done
msg["attr1"] = attr1;
msg["attr2"] = attr2;
msg = JSON.stringify(msg);
console.log(msg);
$.ajax({
method: 'POST',
url: servicePostulation,
data: {msg: msg},
dataType: 'json',
success: function (data) {
console.log(data);
$("#btn").addClass("active");
},
error: function (data) {
console.log(data);
}
});
}
}
})
}
I my case , the "console.log(msg)" shows me a multiple sending of data msg , which means a multiple clicking events , and that's exactly the problem i wanna evitate,
i have tried many solutions with the " $('body').on('click') like :
e.stopImmediatePropagation();
e.preventDefault();
stopPropagation()
one()
off()
unbind()
but nothing works , so is there any further solution or explication ??
My suggest is to disable the button when user click and then enable the button when ajax complete.
**onClick:**
$('#btn').prop("disabled", true);
Ajax complete/success:
$('#btn').prop("disabled", false);

Detect when any ajax calls fail

I have a website where users can work on projects and their work gets automatically saved to my database. Every couple seconds on my site an ajax (post) call occurs (usually in jquery) to check permissions and what not.
With one section of code is there any way so check if any of the ajax calls on your page fail. I don't want to have to go to every individual call and add a block of code to the end.
Basically this is so I can alert the user if they have lost connection or if something is going wrong.
You can use the jQuery event ajaxError. It will be triggered whenever an Ajax request completes with an error:
$(document).ajaxError(function() {
console.error('Error');
});
Check out the documentation.
$(document).ready(function(){
//ajax setup settings
$.ajaxSetup ({
cache: false,
async: false,
statusCode: {
404: function() {
alert('Page not found!');
},
500: function(jqXHR, textStatus) {
alert('Server side: ' + textStatus);
}
}
});
});
I hope this may help you
I would suggest you to override the original jquery ajax function.
var $_ajax = $.ajax; // reference to original ajax
$.ajax = function(options) {
if (options.error) {
// reference to original error callback
var originalErrorHandler = options.error;
var errorHandlerContext = options.context ? options.context : $;
var customErrorHandler = function(xhr, status, error) {
// notify error to your user here
};
// override error callback with custom implementation
options.error = customErrorHandler;
};
return $_ajax.apply($, arguments);
}

no Callback in JSONP in an iframe with data

I am using chrome.
I have an iframe in which i require to hit a url that supports jsonp.
so i used this code :
$.ajax({
dataType: 'jsonp',
url: my_url.endpoint + '/login/v1/token' ,
data: form_to_object("#signin_form"),
context: window,
// All Ajax calls to ABC are json
// Response statuses other than 200 are caught in a timeout
timeout: 10000, //10s
// Handler for successful calls to ABC: calls that return with statusCode 200
success: function(data, textStatus, jqXHR) {
// console.log(data);
alert("in access_token success");
if (data.hasOwnProperty('error_flag')) {
// Errors associated with this action are caught here:
// invalid_credentials, account_lockout, etc.
if (data.hasOwnProperty("jump")) {
ABC_show_frame(data.jump);
} else {
ABC_error_handler(data);
}
return;
}
// Auth succeeded, we can log in the user
GetUserProfile(data);
// ABC_success_handler(data);
},
error: function(data, textStatus, jqXHR) {
alert("In access_token error");
if (data.hasOwnProperty("jump")) {
ABC_show_frame(data.jump);
} else {
ABC_error_handler(data);
}
}
});
Now this code does not attach a callback=some_random_function_name in the url that it generates after attaching the parameters of data.
like https://abc/login/v1/token?username=ashish?password=abc but no callback.
When i debug it line by line, it do call the url with callback=something, and it seems to work. (seems because may be sometime it does not attach even in debugging line by line.)
But when i just run it, it does not.
I think that may be the problem is a bug in jquery where it also has to attach data that it got from form_to_object() and may be that overrides the callback parameter. But that is just a guess.
What should i do ?
I had a form and i was writing my own custom function that would be called when submit button of the form was clicked. In that function i was not stopping the event from propagating further. This lead to this weird errors.
$("form.ims.ajax").submit(function(event) {
event.preventDefault();
// do your stuff
});
This solved the problem.

Magnific popup closes on content click after replacing content

I am using Magnific Popup version 0.8.9.
I am loading content into it via Ajax, and I use a callback for ajaxContentAdded. This callback sets up an event handler for submitting a form that was loaded into the popup, like so:
$('.add-item-btn').magnificPopup({
type: 'ajax',
closeOnContentClick: false,
callbacks: {
ajaxContentAdded: HandleItemFormSubmit
}
});
This works fine, the form submit is handled correctly. The event handler function posts it to the server, which (in case of errors) returns the entire form including error messages.
For this purpose I let it replace the popup's content with the returned form, and setup the submit handler again.
function HandleItemFormSubmit()
{
var popup = this;
// Submit form using ajax
$('form.item-form').submit(function()
{
var data = $(this).serialize();
var url = $(this).attr('action');
$.post(url, data, function(resp)
{
if (resp == 'OK')
{
// All good, close up
popup.close();
}
else
{
// Show HTML from response (with errors)
popup.closeOnContentClick = false;
popup.content.replaceWith(resp);
popup.updateItemHTML();
HandleItemFormSubmit();
}
});
return false;
});
}
However, despite setting closeOnContentClick to false at two different points, the popup immediately closes when content is clicked after the content was replaced (it does work the first time).
The content in the popup has a single root element by the way.
I hope the author or someone else can help out here, I have no idea what is wrong here.
Thank you very much!
I've found another solution:
$('html').on('submit', '#UR_FORM', function(e) {
e.preventDefault();
$.ajax({
data: $(this).serialize(),
type: $(this).attr('method'),
url: $(this).attr('action'),
success: function(response) {
var magnificPopup = $.magnificPopup.instance;
magnificPopup.items[0].type = "inline";
magnificPopup.items[0].src = response;
magnificPopup.updateItemHTML();
}
});
});
You need to call the HandleItemFormSubmit for the popup object:
HandleItemFormSubmit.call(popup);
Otherwise when you call it the way you do, HandleItemFormSubmit();, the this will be set to window and this will not work as expected.
Update
Use this in the else clause:
if (resp == 'OK')
{
popup.close();
}
else
{
// Show HTML from response (with errors)
popup.closeOnContentClick = false;
popup.content.replaceWith(resp);
popup.updateItemHTML();
HandleItemFormSubmit.call(popup);
}

Categories