Using jQuery (v2.1.4), is there any difference between these two methods?
1) $.ajaxSetup(beforeSend)
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
// whatever you need to do before
// any jQuery Ajax request is sent
}
});
2) $(document).ajaxSend
$(document).ajaxSend(function (event, jqXHR, settings) {
// whatever you need to do before
// any jQuery Ajax request is sent
});
Is there any reason to prefer one over the other?
Thanks!
From jQuery $.ajaxSetup() documentation:
All subsequent Ajax calls using any function will use the new settings, unless overridden by the individual calls, until the next invocation of $.ajaxSetup().
The $.ajaxSetup() does something like this:
ajaxExtend(jQuery.ajaxSettings, target);
From $.ajaxSend() documentation:
Whenever an Ajax request is about to be sent, jQuery triggers the ajaxSend event. Any and all handlers that have been registered with the .ajaxSend() method are executed at this time.
And the jQuery source for $.ajaxSend():
function (fn) {
return this.on(type, fn);
}
So, basically the $(document).ajaxSend() adds an event listener to all the document where you can make any handler to execute anytime a jQuery Ajax call is about to be sent (the handler intercepts it, but XMLHttpRequest.readyState value is already 1 - "Opened").
This means that if $.ajax() is called with the global option set to false, the ajaxSend() method will not fire.
While on the $.ajaxSetup() you are in fact creating defaults for every single jQuery Ajax call's settings, and the callback defined through the beforeSend option will always be called (XMLHttpRequest.readyState value is 0 - "Unsent").
From JQuery's documentation:
There are two types of events:
Local Events
These are callbacks that you can subscribe to within the Ajax request
object, like so:
$.ajax({
beforeSend: function(){
// Handle the beforeSend event
},
complete: function(){
// Handle the complete event
}
// ......
});
Global Events
These events are triggered on the document, calling any handlers which
may be listening. You can listen for these events like so:
$(document).bind("ajaxSend", function(){
$("#loading").show();
}).bind("ajaxComplete", function(){
$("#loading").hide();
});
Global events can be disabled for a particular Ajax request by passing in the global option, like so:
$.ajax({
url: "test.html",
global: false,
// ...
});
for more information
Both do very similar function , but it always depend on the need
There are some key points , on which you may focus
ajaxSend() method, must be attached to document only.
if $.ajax() is called with the global option set to false, the ajaxSend() method will not fire.
the beforeSend option will be called regardless of the type of request.
From the perspective of priority, you can use in such a manner, do all setup options in ajaxSend and for custom or specific ajax request override it with beforeSend in $.ajax().
HTML
<body>
<div><h2>Let AJAX change this text</h2></div>
<button id="btn1">Change Content</button>
<button id="btn2">Change Content Override</button>
</body>
JS
$(document).ajaxSend(function(e, xhr, opt){
$("div").append("<p>Requesting " + opt.url + "</p>");
});
$("#btn1").click(function(){
$("div").load("yourpage.html");
});
$("#btn2").click(function(){
$.ajax({
global: false,
beforeSend:function(){$("div").append("<p>Overriding</p>");}
});
$("div").load("yourpage.html");
});
LIVE http://jsfiddle.net/mailmerohit5/w8t44247/
Related
I several HTML elements that initiate ajax when clicked. How can I check which element was clicked inside the ajaxComplete event?
I tried event.target but it returns the entire document.
$( document ).ajaxComplete(function( event, xhr, settings ) {
if ( settings.url.indexOf("somelink/hello") > -1) {
console.log("return here element that initiated ajax")
}
});
Note: The tricky part - I don't have access to the ajax request that is sent on click. I can't configure the code that makes the request. I can only check when the ajax is complete.
I first need to run the ajaxComplete event then check which element initiated ajax because I need to add some html to that element. For this reason I'm trying to check in the ajaxComplete event.
The $.ajaxComplete() handler is not an object-specific handler; you attach it to the document to be notified whenever any AJAX request completes. From the jQuery docs:
If you must differentiate between the requests, use the parameters passed to the handler. Each time an ajaxComplete handler is executed, it is passed the event object, the XMLHttpRequest object, and the settings object that was used in the creation of the request.
So, since settings is a plain Object, you can extend it with a property that will then be passed to the handler, as you can see below with requestingObjectId. DEMO
var onComplete = function(event, jqXHR, ajaxOptions) {
alert("Requested with " + ajaxOptions.requestingObjectId);
};
var makeRequest = function() {
var id = $(this).attr('id');
$.ajax({
url: '/path/to/server',
data: { foo: 1 },
requestingObjectId: id
});
};
$('button').click(makeRequest);
$(document).ajaxComplete(onComplete);
Best and easiest way is to store the element in a global variable when you send the ajax call. Set it to the event.target.activeElement. Then in your ajaxComplete you can just access that var to change CSS etc.
Upon further consideration, if you use my solution you would have to limit it to one ajax request at a time. Otherwise a new ajax request would overwrite variable if the initial ajax request hadn't completed yet. I'd take Palpatime's answer.
An jQuery AjaxRequests is NOT send by an control itself. It is send by the code that the developer wrotes as event function onto this Dom element.
Means the best thing you can get is the callee of $.ajax() by overwriting and wrapping it. And only if the callee is not written in strict mode.
I would prefer to read the documentation of that framework who is building your controls or if it is built by another company/guy contact them.
As the element is not the direct caller of the $.ajax, I see no other way.
so we have this ajax option beforeSend
$.ajax({
beforeSend: function(){
// to do
}
});
is there a way to override this globally?
for example, i want to insert a function on all ajax and I want to do this by creating a single function rather than going all $.ajax calls one by one.
You can check the .ajaxStart() - it's global for all AJAX calls.
Whenever an Ajax request is about to be sent, jQuery checks whether
there are any other outstanding Ajax requests. If none are in
progress, jQuery triggers the ajaxStart event. Any and all handlers
that have been registered with the .ajaxStart() method are executed at
this time.
More info # https://api.jquery.com/ajaxStart/
Currently I am translating my ajax calls to regular $.pjax() call. Everything works fine but ajax success function. I can't manage how to call pjax success function with given parameters.
The only thing I can use is defining pjax global success function to be called on each pjax call:
$(document).on('pjax:success', function(event, data, status, xhr, options) {
});
But unfortunately I would like to define per call specific success function.
Ajax call example:
$.ajax({
url:"/myPage/myFunction",
type:"POST",
data:giveMeData(),
success:function(data){$('#right_form').html(data);console.log('Success works!')}
});
Pjax call example:
$.pjax({
url:"/myPage/myFunction",
type:"POST",
container:'#right_form',
data:giveMeData(),
success:function(){console.log('Success works!')}
});
I don't believe that the jQuery PJAX library supports passing a "success" function directly in to a $.pjax call, although I suspect you could work around this using the $(document).on('pjax:success') callback & its options attribute in order to achieve the same functionality.
For example, say your request is like the above, but you want to have a custom success callback you could use something like this:
$.pjax({
url:"/myPage/myFunction",
type:"POST",
container:'#right_form',
data:giveMeData(),
custom_success:function(){console.log('Custom success works!')}
});
Then, in order to run the custom_success method you could hook up the standard pjax success listener, and given that all the parameters provided to $.pjax are made available in options, you can then grab custom_success function and run it. So your listener may look something like example
$('#right_form').on('pjax:success', function(event, data, status, xhr, options) {
// run "custom_success" method passed to PJAX if it exists
if(typeof options.custom_success === 'function'){
options.custom_success();
}
});
Which i *think* would provide the sort of functionality your after?
A late answer but I found the solution here.
$.pjax({
url:"/myPage/myFunction",
type:"POST",
container:'#right_form',
data:giveMeData(),
}).done(function() { console.log('Success works!') });
I'm using the selectText function from here https://stackoverflow.com/a/987376/784637
However when I called this function immediately after an ajax request on the newly created element:
selectText('some-newly-added-element')
I get the following error in firebug
NS_ERROR_DOM_NOT_OBJECT_ERR: Parameter is not an object
[Break On This Error]
range.selectNodeContents(text);
Note that I am able to call this function after the ajax request on the same element like so
$('#container').on('click', '#some-newly-added-element', function(){
selectText('some-newly-added-element');
});
Is there a way to call this function immediately after the ajax request is done?
Re: Is there a way to call this function immediately after the ajax request is done?
Do you mean after success of the ajax success. or http://api.jquery.com/jQuery.ajax/
or This should help: Execute function after all ajax .load() requests are finished
Hope this fits the cause :)
Sample
$.ajax({
url: this.html_url,
cache: false,
success: function(html){
doSomething();
return true;
}
});
use complete callback which will trigger after ajax call
$.ajax({
complete: function(){
selectText('some-newly-added-element');
}
});
Documentation for ajax event: http://docs.jquery.com/Ajax_Events
I have a problem, that I have several pages in my project and I used a lot of ajax requests in my project, but now I think that whenever an ajax request is called a function will called and whenever that request ends another function will call. How can I do this globally I know I can put this in every ajax request but I need a solution which I do in one place and it works all over the project.
$(document).read(function(){
// Suppose this document load function is written on layout page and every page is inherited from this page
});
Use ajaxSetup, for example
$.ajaxSetup({
beforeSend: function() {
console.log('test');
},
complete: function() {
console.log('completed');
}
});
will setup beforeSend handler for every ajax request. Note that ajaxSetup can take any option that $.ajax can.
You should create a wrapper function for your ajax, then use that function. that way, you have "central" control over the ajax call. something like:
//fast and crude way to extend jQuery
$.fn.customAjax = function(params){
//contains defaults and predefined functions
var defaults = {
complete : function(){...default complete hander...},
beforeSend : function (){...default beforeSend handler}
...
}
//merge settings
var finalParams = $.extend({},defaults,params);
//call ajax and return the deferred
return $.ajax(finalParams);
}
//use it like
$.customAjax({
url : ...,
method : ...,
data: ...,
complete : function(){...} //redefining in the call will override the defaults
});
.ajaxStart
Register a handler to be called when the first Ajax request begins.
.ajaxSucess
Attach a function to be executed whenever an Ajax request completes successfully.
for Detail doc:
http://api.jquery.com/category/ajax/
Try something like this:
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
$.ajax({
url: "anotherMethod.html",
context: document.body
});
});
});
That means whenever ajax call completed successfully call your desire call.
It doesn't have a bug when complete. Click on Like, if work for you
$(document).ajaxSend(function(event, jqXHR, settings) {
$('#general-ajax-load ').fadeIn();
});
$(document).ajaxComplete(function(event, jqXHR, settings) {
$('#general-ajax-load ').fadeOut();
});