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();
});
Related
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/
Is there a way to pause the rest of a function when you are waiting for a value to be returned from an asynchronous call with jQuery?
To achieve this "paused" behavior, you want to put the behavior inside the promise object. https://api.jquery.com/jQuery.ajax/
$.ajax({
url: "test.html",
data: myData
}).success(function() {
//put your code here this will only fire after it returns successfully
}).error(function() {
//This will fire if there is an error
});
What you are talking about would be a synchronous call, which is not recommended as it will freeze the UI.
Instead, use the callback provided in the jQuery call to perform the rest of your code:
function DoSomeCall()
{
$.post( "ajax/test.html", function( data ) {
//Do your follow on code in here, in the callback.
});
//Don't do any code here that relies on the AJAX being finished first.
}
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 need to check for a condition and run an AJAX call before sending other AJAX calls on my web app.
I was thinking about putting this AJAX call in a beforeSend on ajaxSetup with async: false (to prevent my initial call from running before this one has completed).
Something like this:
//I set an event that fires:
$.ajax({
type: "GET",
url: my_url,
beforeSend: function() {
//do something, like show a spinner loader gif
}
});
//Somehwere in my app I also have:
$.ajaxSetup({
beforeSend: function() {
if(x===1){
$.ajax({
type: "GET",
url: my_url/fetch_something,
async:false
});
}
}
});
Will my beforeSend on the first AJAX call overrun the one in the ajaxSetup? Is there a way to approach this better?
Better idea of my app:
I have a lot of Ajax calls through the app, each call sends a security hash on the headers to validate the user, these hashes have a time limit as well (both hash and time limit are saved in localStorage)
What I want from ajax setup (and the condition in it) is to check for the time limit - if time_limit < current_time than run an ajax call to refresh the users hash.
This isn't an exercise for 1 or 2 calls, I literally have 20+ growing Ajax calls on my app that make use of the users hash and it's very impractical to make this check in every single one of them.
UPDATED:
Have one method on an interval that sets up the 'session'/local-storage
var refreshing = false;
var intervalID;
$(document).ready(function(e){
var delay = 1234;
intervalID = window.setInterval(setupInterval, delay);
});
function setupInterval(){
refreshing = true;
$.ajax(URL).done(function(r) { //do stuff
setupStorage(r);
refreshing = false;
});
}
function setupStorage(info){
//setup whatever here
}
OLD:
Could you use some logic in your ready function to gate what you need to do?
So basically call one ajax call -> if false, just schedule your latter methods, otherwise run the setup one and on completion schedule the latter method.
Some pseudo-code:
var refresh = false;
$(document).ready(function(e){
$.ajax(URL).done( function(r) {
if(r) {
routeOne();
} else {
latter();
}
});
});
function routeOne(){
$.ajax(URL).done(function(r) { //do stuff
latter();
});
}
function latter(){
//All other ajax calls
}
I'll put some more thought into this let me finish my coffee first...
EDIT:
Based on your updated description could it be possible for you to schedule a setInterval to run the checking method/hash update on the time interval that you need, and is the time interval on your server static or variable? Facebook does this with a heartbeat, I've used this type of logic with some 'locking' functionality in a web-app. If you schedule the interval properly it should not interrupt any other ajax calls.
Try overriding $.ajax to make a "pre-call" before passing in your given query options:
var oldAjax = $.ajax;
$.ajax = function() {
var args = arguments;
oldAjax({
type: "GET",
url: "/echo/html/",
success: function(result){
// do something here to check result
// if result is good, do the request:
return oldAjax.apply($, args);
// if its bad, handle the error
}
});
}
Here's a fiddle to demonstrate: http://jsfiddle.net/NF76U/
I suggest the use of .done() ( $.Deferred object)
function AjaxCall() {
return //code of your ajax without async:false
}
function anotherAjaxCall{
return //code of you ajax call
}
AjaxCall.done(anotherAjaxCall);
Avoid using async:false it's a deprecated practice and it stucks browsers
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