I need to override form's submit method to wait until the ajax request will be completed. At the same time, ajax request should be asynchronous to display a progress indicator, also default form handler must be continued after response receiving.
I can't use event.preventDefault() and then manual call form.submit() for this, because form sending results should be opened in the new tab of the browser. If form.submit() will be called from the code, then some browsers (i.e. chrome) will block the new tab/window.
Pseudocode for clarity:
$('#form').submit(function(e) {
var result;
startIndicator();
asyncAjaxCheckResults(); // ajax complete handler changed 'result' var
stopIndicator(); // stopping indicator after async ajax will be completed
// continue with default submit behavior if we received desired result
// else prevent executing
if (result !== 'desired result') {
e.preventDefault();
}
});
Can anything be done in this case? Maybe $.deferred can help or infinity loop?
I think you need a sync ajax call, so the script will wait for the respons and then continue running.
$.ajax({
...
async:false,
...
});
http://api.jquery.com/jQuery.ajax/
another way is to add click event to the submit button instead submit event to the form,
send the ajax and use event.prevenrDefault, on ajax success callback fire the form submit - $('#form').submit().
Related
I have a ajax.cs class and I am calling methods from javascript side. So for this I registered it on default.aspx page load like this.
Ajax.Utility.RegisterTypeForAjax(typeof(ajax));
Sometimes some methods taking a long time, At that time I want to abort this call. How can I abort this request?
I call method like this from js;
ajax.testMethod()
If you make your controller action return a Task, then you can have cancellation token as a parameter to the action. And this cancellation token is automatically triggered when the HTTP request is aborted. And in the action, you can handle the token however you like to cancel the long-running operation.
Not sure if it works, but instead of aborting the ajax from the C# side, why don't you cancel it from the js side? in your ajax configuration, you can add a timeout parameter which, when happens, triggers the .error() function you can define, or leave it blank if you just want it to stop executing.
For js:
var ajax = new XMLHttpRequest();
ajax.post('your url');
ajax.timeout(10000); //or any time in milliseconds to set a timeout.
ajax.ontimeout= function(){ }//optional, just if you want a callback when ajax times out
For jQuery:
$.ajax({
url:'yoururl',
timeout: 10000,
error: function(){
}
});
Suppose I have a page called form.php. I then clicked a button called "add button". This button triggers an event that got detected by a jquery function. The jquery function makes an ajax call to add.php.
Inside add.php, there is code that checks if a particular record exist in the database. If it does find that the record exists, I want to do the following.
Send a response string "exist" to ajax.
The ajax, inside the .done() function, will execute a prompt that says "This record already exist, do you wish to overright"?
If the user canceled the prompt, nothing more should happened and the ajax call should be done.
If the user clicks "ok", I would like the php script to be notified of this and execute an update statement using the data from form.php.
I suspect this is impossible because after receiving a response from php, AFAIK there is no way for ajax to respond back to the php script that is currently executing.
Am I correct or there is a way to do this?
You have to add a parameter to your ajax request, like override with true and false. By default/first request you set it to false. Then the add.php does it's default and returns exists.
The the user makes his decision. If he want to override, you send the ajax request again with the override parameter to true. Your add.php will notice the parameter and does whatever it has to do.
Wrap your ajax handler in an own function with a done callback. So you can reuse the request as often as you want. Pretty easy, no double code needed as well ...
The .done() function of your first ajax call executes when the ajax call has finished successfully, so when your php script has finished completely.
If you want to do something else, you would need to make a new ajax request. That could be to the same or another script, sending in different / new / additional parameters.
Note that you have to make sure that the second script cannot be called without the first one finishing, for example by setting and checking an expiring session variable.
you can do something like this.
$.post('add.php',$(this).serialize())
.done(function(result){
var r = confirm("This record already exist, do you wish to overright");
if(result == 'exist'){
if (r == true) {
$.post('update.php',$(this).serialize()).done(function(r){
console.log(r);
});
} else {
return false;
}
}else{
console.log(result)
}
});
If there is jquery ajax loading and I fire another ajax by quickly clicking the button, it kind of gets stuck. How can I handle multiple requests fired together?
How do I do following?
Discard/abort all previous requests and only process the latest one.
Do not allow new request until previous request completes (variation: can be same ajax request or any new ajax request from the page).
AJAX is Asynchronous. So you can fire them at the same time.
Or in the success callback (or .done() callback), you can call one request after another. So it will be easy to manage your issue (you click the button but get stucked), because you can control.
$.ajax({
url: "http://..."
})
.done(function( data ) {
// Other AJAX call
// or restore disabled elements
// while you were receiving the response.
});
If you want a work-around, just tell me.
you can use ajax "beforeSend" to lock the current request.So that user can send a new request only if the previous one is done. As for the process sequence, you can use a global value to store data and always assign it with the new response value.
function request(callback){
if(!$btn.hasClass('disabled')){
$.ajax({
type:'...',
url:'...',
beforeSend:function(){
$btn.addClass('disabled');//so that user cannot send a new request
},
success:function(data){
window.g_data = data;
callback && callback()//success callback
$btn.removeClass('disabled');
}
})
}
}
function callback(){
//process window.g_data
}
Have a look at this library:
Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript.
Async
I am usinh jquery form plugin with this code
$(".form1").live('submit', function(e){
$(".form1").ajaxSubmit(options);
});
Now i see that firebug console shows all ajax requests so that i can see the request and response.
But i have seen that when i use the above code then my ajax request is completed but i can't see any post request in console.
But if i use
$(".form1").live('submit', function(e){
var queryString = $('.form1').formSerialize();
$.post('/book/create/', queryString);
Then i can see the request response
i want to know why is that
Only ajax requests (XMLHttpRequest) are shown in the console. Use the net panel to debug all other requests.
But .ajaxSubmit() is indeed an ajax request as the docs say
ajaxSubmit
Immediately submits the form via AJAX.
In the most common use case this is
invoked in response to the user
clicking a submit button on the form.
ajaxSubmit takes zero or one argument.
The single argument can be either a
callback function or an Options
Object.
The problem may be that you're not preventing the actual form submission in your code .
$(".form1").live('submit', function(e){
$(".form1").ajaxSubmit(options);
return false; // this will prevent the actual form submission.
});
I have a php script that outputs json data. For the purposes of testing, i've put sleep(2) at the start.
I have a html page that requests that data when you click a button, and does $('.dataarea').append(data.html)
(php script returns a json encoded array. data.html has the html that i want to put at the end of <div class="dataarea">...HERE</div>.
The trouble is, if i click the button too fast (ie. more than once within two seconds (due to the sleep(2) in the php script)), it requests the php file again.
how can i make it only do one request at a time?
i've tried this (edited down to show the important parts):
amibusy=false;
$('#next').click('get_next');
function get_next() {
if (amibusy) {
alert('requesting already');
}
else {
amibusy=true;
// do the request, then do the append()
amibusy=false;
}
}
but this doesn't seem to work. i've even tried replacing the amibusy=true|false, with set_busy(), and set_not_busy(). (and made a function am_i_busy() { return amibusy; })
but none of this seems to work. what am i missing?
If you're in jQuery the amibusy would be jQuery.active which contains a count of currently active AJAX requests, like this:
if(jQuery.active > 0) { //or $.active
alert('Request in Progress');
}
Keep in mind that in jQuery 1.4.3 this becomes jQuery.ajax.active.
Disable the button in the click event and enable it again when the request is finished. Note that the request is asynchronous (i.e. "send request" returns immediately), so you must register a function that is called when the answer comes in.
In jQuery, see the load() function and the success method plus the various AJAX events which you can tap into with ajax().
I'm wondering about your "do request" logic. Whenever I've done calls like this they've always been asynchronous meaning I fire the request off and then when the response comes another function handles that. In this case it would finish going through that function after setting the callback handler and set your value of amibusy back to false again before the request actually comes back. You'd need to set that variable in the handler for your post callback.
Could you use the async variable?
http://api.jquery.com/jQuery.ajax/
asyncBoolean Default: true
By default, all requests are sent
asynchronous (i.e. this is set to true
by default). If you need synchronous
requests, set this option to false.
Cross-domain requests and dataType:
"jsonp" requests do not support
synchronous operation. Note that
synchronous requests may temporarily
lock the browser, disabling any
actions while the request is active.