I'm trying to use the ajaxStop function in jquery but can't get it to fire, any ideas?
What I'm trying to do is loop through each anchor tag and then update some content inside it, from there I want to use the ajaxstop event to fire a script to reorganize the anchors based on the updates
Thanks for any help
jQuery(document).ready(function($) {
function updateUsers() {
$(".twitch_user").each(function(index, user) {
$.ajax({ url: "https://api.twitch.tv/kraken/streams/" + $(user).attr("id") + "?callback=?", success: function(d) {
if(d.stream) {
$(user).addClass("online");
$(user).removeClass("offline");
$(user).children(".viewers").text(d.stream.viewers + " viewers");
} else {
$(user).addClass("offline");
$(user).removeClass("online");
$(user).children(".viewers").text("0 viewers");
}
console.log(d);
}, dataType: "json"});
});
}
//$(document).ajaxStart(function() {
// console.log("Event fired!");
// updateUsers().delay(2000);
//})
$(document).ajaxStop(function() {
console.log("Event fired!");
// updateUsers().delay(2000);
});
updateUsers();
});
Apparently the global handlers are turned off when doing JSONP requests, as explained in this ticket:
JSONP requests are not guaranteed to complete (because errors are not caught). jQuery 1.5 forces the global option to false in that case so that the internal ajax request counter is guaranteed to get back to zero at one point or another.
I'm not sure if JSONP is your intention or not, but the ?callback=? on the end of the URL makes jQuery handle it as such.
The solution was to set the following:
jQuery.ajaxPrefilter(function( options ) {
options.global = true;
});
Related
I am working on a web application for debtor management and I am refactoring the code and try to adhere to the principle of separation of concerns. But the async nature of AJAX is giving me headaches.
From a jQuery dialog the user can set a flag for a debtor which is then stored in a database. If that succeeds, the dialog shows a notification. Until now I handled everything inside the jQuery Ajax success callback function: validating input, doing the ajax request and updating the content of the dialog.
Of course this lead to spaghetti code.
Thus I created a class AjaxHandler with a static method for setting the flag, which is invoked by the dialog. I thought that the dialog could update itself according the the return value of the AjaxHandler but I did not have the asynchronity in mind.
The following question was helpful in tackling the return values.
How do I return the response from an asynchronous call?
But how can I update the dialog without violating the SoC principle?
EDIT
$("#button").on("click", function() {
var returnValue = AjaxHandler.setFlag();
if(returnValue) { $("#div").html("Flag set"); }
else { $('#div").html("Error setting flag");
});
class AjaxHandler {
static setFlag(){
$.ajax({
type: "POST",
url: "ajax/set_flag.php",
success: function(returndata){
return returndata; //I know this does not work because of
//ASYNC,but that is not the main point.
}
}
})
There is many ways to handle async responses, but the jQuery way is slightly different, so when you are already using jQuery, handle it this way:
$('#button').on('click', AjaxHandler.setFlag)
class AjaxHandler {
static setFlag () {
this.loading = true
this
.asyncReq('ajax/set_flag.php')
.done(function () {
$('#div').html('Flag set')
})
.fail(function (err) {
$('#div').html('Error setting flag. Reason: ' + err)
})
.always(function () {
this.loading = false
})
}
asyncReq (url) {
return $.ajax({
type: 'POST',
url: url
})
}
})
Consider using events perhaps here?
$("#button").on("click", function() {
$('body').trigger('getdata', ["", $('#div')]);
});
$('body').on('getdata', function(event, datasent, myelement) {
var attach = event.delegateTarget;// the body here
var getAjax = $.ajax({
type: "POST",
url: "ajax/set_flag.php",
data: datasent // in case you need to send something
})
.done(function(data) {
$(attach).trigger('gotdata', [data, myelement]);
});
getAjax.fail(function() {});
})
.on('gotdata', function(event, datathing, myelement) {
myelement.html(!!datathing ? "Flag set", "Error setting flag");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
Note that inside those event handlers you could also call some function, pass a namespace for the function, basically do it as you please for your design.
I have defined a general ajaxComplete function to be triggered after each ajax request as follow;
$(document).on('pfAjaxComplete', function(event, xhr, options) {
doStuff();
});
Note I use pfAjaxComplete instead of ajaxComplete to work under PrimeFaces
Now, on each ajaxcomplete the 'doStuff()' function is being called. Problem is that inside the 'doStuff()' function I trigger several ajax calls to be executed based on a PrimeFaces remoteCommand
function doStuff() {
var elements = $('#wrapper').find("[id*='elements']");
if (elements !== null && elements .length > 0) {
$.each(elements , function(index) {
newAjaxCallBack([{name: 'param', value: 'val'}]);
});
}
}
My remote command
<p:remoteCommand name="newAjaxCallBack" actionListener="#{backingBean.action}" />
This is working fine, the backing bean action method is being called. Problem is the new ajax callback on 'doStuff' triggers a new ajaxOnComplete event, which makes sense of course but then it gets me on an infinite loop. Had tried to work it out but couldn't find any solution to it.
Any ideas or suggestions? Would there be a way to send a parameter on the newAjaxCallBack and then detecting it on the ajaxComplete function so as to avoid the doStuff call? Thanks!
A quick solution would be to append additional parameters to your calls on which you don't want another action to be executed.
If you choose a "paremeter" that is not used on the target page, it won't care about it.
$(document).ajaxComplete(function(event, xhr, options) {
if (options.url.indexOf("noStuff=true") != -1){
alert("Ignoring Ajax Request from noStuff");
return;
}
doStuff();
});
function doStuff(){
alert("doing stuff");
//another fake ajax request
$.ajax({
url: "http://google.de",
data: [
{name: 'param', value: 'val'},
{name: 'noStuff', value: 'true'}
]
});
}
http://jsfiddle.net/3kwhn0kx/
Finally got it working, solution was similar to #dognose one, in my case I had to use the data primefaces handled, this way;
...
$.each(elements , function(index) {
newAjaxCallBack([{name: 'dontcall', value: 'true'}]);
});
...
and then:
$(document).on('pfAjaxComplete', function(event, xhr, options) {
if (xhr.pfSettings.data.indexOf('dontcall') !== -1) {
return;
}
doStuff();
});
As you may see, I'm using the pfSettings object, which has an attribute 'data' that is basically a string with info related to the request including params, so if parameter present, don't do anything.
I am making few ajax requests in my jQuery file. On success of these jQuery requests, I wrote few on click events which are not working.
This is my code
$(document).ready(function (){
$.ajax ({
type: "POST",
url: 'myServlet',
async: false,
success: function (response) {
id = parseInt(response);
setOutputEvents();
}
});
function setOutputEvents() {
for (var queryNumber = 0; queryNumber <= id; queryNumber++) {
$.ajax({
type: "POST",
url: 'myOtherServlet',
data: {queryNumber: queryNumber},
success: success,
async: false
});
var success = function (response) {
//some code here
generateTable();
}
}
}
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
});
I understand making multiple ajax requests is a bad programming practice but what could be the reason for on click events not getting triggered?
These are the onclick events which are not working.
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
I am using Google Chrome Version 39.0.2171.95 on Windows 7.
Please do let me know if any further information is necessary.
Since you use ajax to load even the initial content it seems, .class / #me html elements likely do not exist on initial page load of the DOM. As you didn't post html, i'm guessing this is the case.
Thus, you need to use a delegated event click handler to respond to it
so, you would change
$("#me").on("click", function(){
to
$(document).on("click", "#me", function(){
and so forth to link it to the parent element that does exist, the document itself.
This would work:
$(".class").on("click", function(){
alert("me is triggered");
});
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").trigger("click");
}
Some notes:
Event handler must be registered before triggering click.
Triggered click selector must match the class which has the click event registered.
Functions must be defined before the usage.
this is my first time using ajax. and i don't have an idea where the ajaxStop takes place. I am using the ajaxStart to show a loading image and need the ajaxStop to hide the loading image. Please help.
I have this code to call a popup from "PageOne"
function ShowFixSteps(path, title){
var winHeight = parseInt(jQuery(window).height() - 100);
var winWidth = parseInt(jQuery(window).width() - 600);
jQuery.ajax({
url: path,
success: function(data) {
jQuery("#divPopup").load(path).dialog({
modal: true,
width: winWidth,
height: winHeight,
title: title,
position: "center"
});
}
});
jQuery("#divPopup").bind("dialogbeforeclose", function(){
jQuery("#divPopup").empty('');
});
}
And on my Master page, I have this code to check the start and stop of ajax call:
$(document).ajaxStart(function() {
alert('start');
});
$(document).ajaxStop(function() {
alert('stop');
});
$(document).ajaxError(function() {
alert('error');
});
It alerts the START but not the STOP: no ERROR also.
NOTE: START and STOP alerts are working on Chrome but not IE.
ajaxStop is triggered after all current AJAX requests have completed.
You can read more about ajaxStop using the jQuery API documentation.
You can use .ajaxStop() in the following manner:
$(document).ajaxStop(function() {
$('#loading-spinner').hide();
});
Or you could add :complete callback to your AJAX function, like so:
jQuery.ajax({
url: path,
success: function(data) {
jQuery("#divPopup").load(path).dialog({
modal: true,
width: winWidth,
height: winHeight,
title: title,
position: "center"
});
},
complete: function() {
// do something here when ajax stops
// like hiding the spinner or calling another function
}
});
And as you mentioned how to stop an AJAX request in one of your comments, here's how:
var ajax1 = $.ajax({
type: "POST",
url: "some.php",
...
});
ajax1.abort()
You could check if a specific AJAX request is running before aborting by doing this:
if (ajax1) {
ajax1.abort();
}
Or you could check to see if any ajax requests are running before aborting by doing something like this:
var ajax_inprocess = false;
$(document).ajaxStart(function() {
ajax_inprocess = true;
});
$(document).ajaxStop(function() {
ajax_inprocess = false;
});
if (ajax_inprocess == true) {
request.abort();
}
Beware using .abort() though, as it only stops the client-side code from listening for a response, it wont actually stop the server from working. There are actually a few major caveats using this, so make sure you read about it first.
UPDATED ANSWER FOR UPDATED QUESTION
For IE problem, try using:
$(document).ajaxComplete(function() {
// do something
})
Instead of ajaxStop(). ajaxComplete() will fire each time an AJAX request finishes, rather than when ALL requests have finished using ajaxStop(). Maybe it will help, maybe not.
Hello guys here's my code:
var ajax={
chiamata:function(target,url,opzioni){
if (!tools.array_key_exists('caricamento',opzioni)){
opzioni['caricamento']=1;
}
var dati=url.split('?');
$.ajax({
type: opzioni['type'],
url: url,
contentType:"application/x-www-form-urlencoded; charset=UTF-8",
data: dati[1],
dataType: "html",
success: function(msg){
if (opzioni['caricamento']!=0){
ajax.printLoading();
}
$(target).html(msg);
},
error: function(){
alert("Chiamata fallita!");
}
})
},
printLoading:function(){
var body="#colonnaDX";
$(body).ajaxStart(function(){
$(body).append('<div id="loading"><img src="graphic/IMAGE/spinner.gif"/>Loading...</div>');
})
.ajaxStop(function(){
$('#loading').remove();
});
}
},
//Recursive function
var object={
checkAzione:function(target,url,opzioni,interval){
if (!interval)
interval=60000;
ajax.chiamata(target,url,opzioni);
setTimeout(function() {
this.checkAzione(target,url,opzioni,interval);
}, interval);
}
}
$(document).ready(function(){
object.checkAzione(
'#colonnaDX',
'someactions.php',{
'caricamento':0
},
10000
);
})
I'll try to explain the problem as better as i can, When the document is ready, the function "checkAzione" starts and it makes some stuff like DB calls etc, this kinds of ajax calls don't need any visual loading like spinner etc so in the array "opzioni" i set a flag 'caricamento':0 (same of 'loading':0) just check my ajax object to see what i mean, it works until i make some ajax calls that using 'caricamento':1, from that moment every ajax calls in my recursive function makes the "printLoading"... Any tips????
ajaxStart and ajaxStop are global, you add them to the body. You probably shouldn't use ajaxStart/Stop in this case, just add the functionality to your ajax listeners (success and error).