can't seem to get the ajaxSend and Stop to work... These are global variables no? .. but I should be able to use like this... but I never get an alert??
I wanted to use these events to display an ajax animation.. although in my code I wish to position the ajax animation depending on what I am doing a what element it is.
$.ajax({
type: "POST",
url: "MyService.aspx/TestMe",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
ajaxSend: function (r, s) {
alert('i am starting');
}
,
ajaxStop: function (r, s) {
alert('i am stopping');
}
,
success: function (msg) {
}
});
Those are globals, and the way I typically see them assigned is:
$('element').ajaxStart(function() {
... do something ...
}
Assigning them to a specific ajax request, I'm not sure if that will do what you want it to do.
So you don't use this functionality properly. ajaxStop, ajaxComplete and etc. is not a parameters of $.ajax function. Let say you have an ajax icon which you want to remove on request completion.
$("#ajax_icon").ajaxStop(function(){
$(this).hide();
});
You have a good reference here
PS. With other function is the same.
Related
I've got a dashboard page, and am using jQuery to update each graph with a single ajax call.
If it run AJAX with async:false then everything works, but it's obviously slow as the calls are made one after another.
When I run async:true, the queries execute but they all output to the same element and overwrite each other.
How can I ensure that the jQuery selector in the success and error functions remain pointed to their original desintation and do not all point to the final box?
My code:
//update sparklines on dashboard page
$(".convobox7").each(function() {
id = $(this).attr('id');
$("#convobox-7-"+id).prepend("<img src='img/ajax_loader.gif'/>");
$.ajaxQueue({
url: '_ajax/getFunnelReport',
type: "POST",
dataType: "json",
async: true,
data: {funnel:$(this).attr('id'), dimension:'date'},
timeout: 50000,
success: function(json) {
var data = json;
if (data.success=='true') {
$("#convobox-7-"+id).html(data.htmlconv+"<br/><small>Past week</small>");
gebo_peity.init();
}
},
error: function(x, t, m) {
$("#convobox-7-"+id).html("");
}
})
});
Note I'm using the ajaxQueue plugin here but the same thing happens without it.
You need to localise id :
var id = $(this).attr('id');
There may be other things to fix but that one is a certainty.
EDIT
Try this :
$(".convobox7").each(function() {
var id = $(this).attr('id');
var $el = $("#convobox-7-"+id).prepend("<img src='img/ajax_loader.gif'/>");
$.ajaxQueue({
url: '_ajax/getFunnelReport',
type: "POST",
dataType: "json",
data: {funnel:id, dimension:'date'},
timeout: 50000,
success: function(data) {
if (data.success == 'true') {
$el.html(data.htmlconv+"<br/><small>Past week</small>");
gebo_peity.init();
}
},
error: function(x, t, m) {
$el.html("");
}
});
});
This has to do with function closures because you declared the variable outside the success/error function. A better approach is to use the $(this) reference in the error/success functions instead of assigning it outside the handlers.
Edit: In the context of the error/success handler for ajaxQueue, I'm not absolutely certain what $(this) refers to, you may need to navigate to a parent element. I didn't see any definitive documentation offhand. This is one of my biggest pet peeves with javascript documentation, $(this) is sometimes not what you would think it'd be and isn't documented :/
silly question, but since you already send the element id to the service, is there a reason it cannot send it back? then you can simply use that as a selector, ensuring that you have the item you need.
I am using .ajaxStart() and .ajaxStop() to show a modal while an ajax request is being made. (between start and stop)
Now I'd like to add a longpoll function that keeps waiting for notifications, similar to the one on the left upper corner of this site.
My problem now lies in disabling this modal only for the longpolling request..
Registering "loading screen" on and off handlers:
$(document).ajaxStart(handleAjaxStart);
$(document).ajaxStop(handleAjaxStop);
My longpoll function:
$.ajax({
timeout: 35000,
url: longPollUrl,
success: function(data){
if(data.queCount) $('#numQueCount').html(data.queCount);
if(data.queAccept) $('#numQueAccept').html(data.queAccept);
},
dataType: 'json',
complete: longpoll
});
I tried:
$().off('ajaxStart');
$().off('ajaxStop');
..and reattaching the handlers after starting the polling, but no joy.
I also tried introducing a global variable into handleAjaxStart() that would return at the first line of the function, but that seems to completely kill the loading screen.
Any ideas how this can be achieved?
I figured it out..
There is an attribute in the options object .ajax() takes called global.
If set to false, it will not trigger the ajaxStart event for the call.
$.ajax({
timeout: 35000,
url: longPollUrl,
success: function(data){
if(data.queCount) $('#numQueCount').html(data.queCount);
if(data.queAccept) $('#numQueAccept').html(data.queAccept);
},
global: false, // this makes sure ajaxStart is not triggered
dataType: 'json',
complete: longpoll
});
After reading all possible solutions, I want to combine answers.
Solution 1: Bind/Unbind
//binding
$(document).bind("ajaxStart.mine", function() {
$('#ajaxProgress').show();
});
$(document).bind("ajaxStop.mine", function() {
$('#ajaxProgress').hide();
});
//Unbinding
$(document).unbind(".mine");
It is a depreciated solution. Before jQuery 1.9, global events of ajax like ajaxStart, ajaxStop, ajaxError etc. can be binded to any element. After jQuery 1.9:
As of jQuery 1.9, all the handlers for the jQuery global Ajax events,
including those added with the .ajaxStart() method, must be attached
to document.
Therefore we cannot bind/unbind these events to custom namespaces.
Solution 2: Set the property global to false
$.ajax({
url: "google.com",
type: "GET",
dataType: "json",
global: false, //This is the key property.
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
}
});
This solution works to disable ajaxStart()/ajaxStop() event(s). However, it also makes disable ajaxComplete(), ajaxError(), ajaxSend(), ajaxSuccess(). If you don't use these global events, it seems ok, but when it is needed, you have to come back and change your solution for all pages where you set global: false.
Solution 3: Use global variable
var showLoadingEnabled = true;
$(document).ready(function () {
$('#loading')
.hide() // at first, just hide it
.ajaxStart(function () {
if (showLoadingEnabled) {
$(this).show();
}
})
.ajaxStop(function () {
if (showLoadingEnabled) {
$(this).hide();
}
});
});
function justAnotherFunction() {
window.showLoadingEnabled = false;
$.ajax({
url: 'www.google.com',
type: 'GET',
complete: function (data) {
window.showLoadingEnabled = true;
console.log(data);
}
});
}
Global variables should not be used in javascript files. However, this is the simplest solution, I can find.
I prefered the third solution for my project.
function bindALLFunctions() {
..all triggers functions related go here
};
$.ajax({
type: 'POST',
url: myURL,
data: { thisParamIdNo: thisIdNo },
success: function(data){
$(".incContainer").html(data);
bindALLFunctions();
},
dataType: 'html'
});
I am new to ajax and JQuery.
I have the above ajax call in my js-jquery code. bindALLFunctions(); is used to re-call all the triggers and functions after the ajax call. It works all fine and good as expected. However, I have read somewhere that is better to load something after the initial action is finished, so I have tried to add/edit the following two without any success.
Any ideas?
1) -> $(".incContainer").html(data, function(){
bindALLFunctions();
});
2) -> $(".incContainer").html(data).bindALLFunctions();
Perhaps you should have a look to the live and delegate functions. You can set a unique event handler at the beggining of your app and all your loaded ajax code will be automatically binded:
$("table").delegate("td", "hover", function(){
$(this).toggleClass("hover");
});
But if you prefer to use Jquery.ajax call you have to do something like this:
$.ajax({
type: 'POST',
url: myURL,
data: { thisParamIdNo: thisIdNo },
success: function(data){
$(".incContainer").html(data);
bindALLFunctions(".incContainer");
},
dataType: 'html'
});
and transform bindALLFunctions as:
function bindALLFunctions(selector) {
..all triggers functions related go here. Example:
$('#foo', selector).bind('click', function() {
alert('User clicked on "foo."');
});
};
that will only bind events "under" the given selector.
Your initial code was fine. The new version does not work because html() function does not have a callback function.
It's hard to tell from your question just what you intend to ask, but my guess is that you want to know about the ready function. It would let you call your bindALLFunctions after the document was available; just do $(document).ready(bindALLFunctions) or $(document).ready(function() { bindALLFunctions(); }).
If I call a function to load my grid data, loadComplete does not fire. I need to handle this event so I can manually update multiselect checkbox correctly. If I update in gridComplete, I have to click the checkbox twice to uncheck it.
In your previous question you wrote that you use WCF on the server side. In the case you don't need to use datatype as function. Instead of that you can just use the following parameters:
datatype: "json",
ajaxGridOptions: { contentType: "application/json" },
serializeGridData: function (data) {
return JSON.stringify(data);
}
To be sure that JSON.stringify are supported in old web browsers you should include json2.js which you can load from here.
In the old answer you can find more code examples (and download the demo) which shows how you can use WCF with jqGrid.
Now I will answer on your original question: "Why loadComplete does not fire" if you use datatype as function. The short answer is: if you use datatype as function your code is responsible for calling of loadComplete.
If you use datatype as function your code is responsible to some things which jqGrid do typically. So first of all you have to understand what should the datatype function do. An example from the documentation (see here) shows the simplest, but not full, implementation of datatype as function. More full code example looks like the following:
$("#list").jqGrid({
url: "example.php",
mtype: "GET",
datatype: function (postdata, loadDivSelector) {
var ts = this, // cache 'this' to use later in the complete callback
p = this.p; // cache the grid parameters
$.ajax({
url: p.url,
type: p.mtype,
dataType: "json",
contentType: "application/json",
data: JSON.stringify(postdata),
cache: p.mtype.toUpperCase() !== "GET",
beforeSend: function (jqXHR) {
// show the loading div
$($.jgrid.jqID(loadDivSelector)).show();
// if loadBeforeSend defined in the jqGrid call it
if ($.isFunction(p.loadBeforeSend)) {
p.loadBeforeSend.call(ts, jqXHR);
}
},
complete: function () {
// hide the loading div
$($.jgrid.jqID(loadDivSelector)).hide();
},
success: function (data, textStatus, jqXHR) {
ts.addJSONData(data);
// call loadComplete
if ($.isFunction(p.loadComplete)) {
p.loadComplete.call(ts, data);
}
// change datatype to "local" to support
// "loadonce: true" or "treeGrid: true" parameters
if (p.loadonce || p.treeGrid) {
p.datatype = "local";
}
},
error: function (jqXHR, textStatus, errorThrown) {
if ($.isFunction(p.loadError)) {
p.loadError.call(ts, jqXHR, textStatus, errorThrown);
}
});
},
... // other parameters
});
You can see that the code in not so short. In the above example we still not support some jqGrid options like virtual scrolling (scroll: 1 or scroll: true).
Nevertheless I hope that I cleared now why I don't recommend to use datatype as function. If you use it you have to understand many things how jqGrid work internally. You should examine it's source code to be sure that you do all things correctly. If you skip somethings, than your code will works incorrect in some situations or in some combination of jqGrid parameters.
If you look at the code which I included at the beginning of my answer (the usage of ajaxGridOptions and serializeGridData) you will see that the code is very easy. Moreover it works with all other legal combination of jqGrid parameters. For example you can use loadonce: true, loadComplete, loadError or even virtual scrolling (scroll: 1 or scroll: true). All things needed depend on the parameters do jqGrid for you.
Basically I am trying to call a function (function 1), that get the results from another function (function 2). And this function 2 is making an ajax call.
So the code would be like this:
function f1 () {
var results = f2();
}
function f2() {
$.ajax({
type: 'POST',
url: '/test.php',
success: function(msg){
}
});
}
I know that is I display an alert in the success function, I get the results. But how can we make this result be sended back?
I tryed to do something like this inside function 2 without success:
return msg;
thanks for your help
In theory, this is possible using jQuery's async: false setting. That setting makes the call synchronous, i.e. the browser waits until it's done.
This is considered bad practice, though, because it can freeze the browser. You should re-structure your script so you can do the relevant things in the success callback instead of f1. I know this is less convenient than what you do in f1(), but it's the right way to deal with Ajax's asynchronous nature.
You can forcefully make the request synchronous ( kinda losing the benefit of ajax ) but making your code work:
function f2() {
var ret = false;
$.ajax({
type: 'POST',
url: '/test.php',
async:false,
success: function(msg){
ret = msg
}
});
return ret;
}
Otherwise, you have to add a callback in your success function if you want to keep it asynchronous..
function f2() {
$.ajax({
type: 'POST',
url: '/test.php',
async:false,
success: function(msg){
doSomething(msg);
}
});
}