I have a form I am submitting with $.post() in jquery..
$.post("testpage.php", $("#payment-form").serialize())
The post works fine itself, but when the post is done and successful the page will do other stuff such as display a thank you message and stuff. I just need to where to put to call to display the message.I do not understand where it goes in terms of the success being returned from the post.
You can specify a 3rd argument to .post() that is the "success" callback. It is a function to call when the .post execution is successful.
$.post("testpage.php", $("#payment-form").serialize(), function() { alert('post was successful!')})
Source: http://api.jquery.com/jquery.post/
In short, like this:
$.post("testpage.php", $("#payment-form").serialize(), function () {
// Start partying here.
}).fail(function() {
// Handle the bad news here.
})
Alternatively, you can use deferred objects, like as follow:
// Create POST request
var paymentPost = $.post("testpage.php", $("#payment-form").serialize());
// Assigned deferred objects
// "data" refers to the data, preferably in JSON format, returned by testpage.php
paymentPost
.done(function(data) {
// Success
// e.g. display thank you message, redirect to a payment successful page...
})
.fail(function(data) {
// If error
// e.g. display error message(s)
})
.always(function() {
// Will always fire as long as POST request is submitted and completed
});
p/s: It is important to note that jqXHR methods like .success() and .error() are deprecated. To prepare for their eventual removal, you should abide to the new nomenclature for deferred objects ;)
Related
I am learning to use jQuery Ajax. What does function(response) mean and what is the meaning of response == 1 and response == 2?
jQuery.post(ajaxurl, data, function(response) {
if (response == 1) {
$saveAlert.addClass('is-success').delay(900).fadeOut(700);
setTimeout(function() {
$tieBody.removeClass('has-overlay');
}, 1200);
} else if (response == 2) {
location.reload();
} else {
$saveAlert.addClass('is-failed').delay(900).fadeOut(700);
setTimeout(function() {
$tieBody.removeClass('has-overlay');
}, 1200);
}
});
I'll explain the basics:
jQuery.post = You want to post some data to your endpoint
ajaxurl = your endpoint address. Typically a API
data = the data you want to send to your endpoint along with the request.
function(response) is where you handle the response from the endpoint.
So lets go through the code. First you call post to your endpoint / API with the data you want to post. Then you provide a callback (in your case a function) to handle the response the endpoint / API provides you.
In your case it looks like if the endpoint responds with 1, you have successfully posted your data. If the endpoint responds with 2, you have posted data and want to reload the site. If the endpoint does NOT respond with either 1 or 2, it failed to post.
To help you understand the basics of jQuery post:
A well-written API / endpoint should respond with the correct HTTP status codes and status messages and it should be fairly easy to notice when data was posted correctly and when an error occurred.
I don't think your endpoint responds any good. response == 1 or response == 2is not by any means clear and easy to understand.
A better way of handling success and errors is to use the done and fail handlers of jquery post (more on this below).
$.post( "test.php" );
This will completely ignore the response from calling the endpoint. I.e. you don't want to handle either success or error. PLEASE DO NOT USE THIS. You should handle success and error!
$.post( "test.php", function( data ) {
//Do something now
});
This will do whatever you provide in the function when the endpoint has sent its response.
$.post( "example.php", function() {
//You successfully reached the endpoint
console.log( "success" );
})
.done(function() {
//Handle success here!
})
.fail(function() {
//Handle error here
})
This is probably the preferred way of handling both success and errors. It's pretty clear that if you reach the fail, it has failed. Both easy to read the code and easy to understand jquery post!
The examples above is copied from the jquery documentation.
Note that the previous handlers for done and fail was success and error, but success and error is deprecated and removed in jQuery 3.0!
So if you have jQuery version < 3.0 you need to find out if you need to use the new or old syntax, or if you need to update jQuery maybe?
Hope this explains enough to make you understand the basics, and to help you get further. I highly suggest you read the jQuery.post documentation here. I think you should also read the w3schools documentation here.
I have various function with the ajax and $.post syntax which gives call to the server function. But when session gets expired and page is not refreshed my ajax code wont work. In this I want to redirect the page to login controller.
As it this is ajax call my redirection code is not working.
Is there any code or JavaScript/jQuery function which gets executed before any other jquery ajax and post function.
I am using PHP(Yii framework) on server side.
Please let me know. Thank you.
You can use the "beforeSend" ajax event where you can check you session and if it's expired you can do something else:
$.ajax({
beforeSend: function(){
// Handle the beforeSend event
},
complete: function(){
// Handle the complete event
}
// ......
});
Check this for more info: http://api.jquery.com/Ajax_Events/
jQuery provides a set of AJAX events you can listen during request lifecycle. In your case you can subscribe to ajaxError event triggered on document to react when requests failed as unauthorized:
$(document).on('ajaxError', function(el, xhr) {
if (xhr.status == 401) {
alert('Unauthorized');
}
});
This code can solve your problem.
$(document).bind("ajaxSend", function(){
//DO Someting..
});
Note beforeSend is local event and ajaxSend is global event
/***
* Global Ajax call which gets excuted before each $.ajax and $.post function
* at server side chk session is set or destroy
***/
$(document).on('ajaxStart', function()
{
$.post( BASEURL+"/login/chkLogin",
{},
function(data)
{
if (data == 'login') {
window.location = BASE_URL+'/login'; //Load the login page
}
else
{
//alert('all okay! go and execute!');
//No need to write anything in else part
//or can say no need of else block
//if all okay normal ajax action is processed
}
});
});
This is what I want. working perfectly for my functionality. Thank you for all answers and comments. I got a big reference from you.
use ajaxComplete event.
$( document ).ajaxComplete(function() {
window.location.href = "/login";
});
So I have a jquery ajax call like so:
$.ajax({
url: 'delete.php',
data : {
'prd_id': <prd-id-number>
},
success: function(data) {
//show success here
},
error : function(error) {
//show error here
}
});
My doubt is about the success and error handlers. Is the error handler only used for "ajax level" error? I mean - my application can have its own error, for.e.g. the passed product id does not exist or is incorrect. Now, currently what I am passing a message back, which goes into success() then I have to do some internal logic to see if the message is an application error or truly success - and based on that I show the message.
is there any way I can send the message to error() - is that the proper way to trap and handle ajax errors?
Ajax error can be triggered several different ways. The most common ones are , http status not being 200, timeout and data parsing errors such as incorrectly formatted json.
You can trigger the error yourself from server by returning an http response code header.
For example assume you have an API that looks up users by ID and you send an invalid ID. You can return a 404 response code header with data included that can be used in your app from within the error callback.
This allows you to set up the application code to handle both types of errors using the error callback
Well i think you need to recall some concepts.
ajax success and error handlers are called depending upon the success or failure of the axaj call send.
success handler is called whenever the ajax call has successfully completed while error handler is called whenever the ajax call could not be completed due to any sort of error.
For your case you will have to manipulate the success handler and show the required message.
There is no way to call error handler when your ajax call has been successfully completed.
I want to validate user entries on a WordPress post upon hitting the submit button, display an error message is there are problems, and submit the form if everything is OK. I have a PHP function that does the checking, returning true if data in form_data is OK, some error code otherwise. The following JavaScript issues the AJAX request, and was supposed to continue submitting the form upon successful checking, but it doesn't:
jQuery(document).ready(function() {
jQuery('#post').submit(function() {
var form_data = jQuery('#post').serializeArray();
var data = {
action: 'ep_pre_submit_validation',
security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
form_data: jQuery.param(form_data),
};
var proceed = false;
jQuery.post(ajaxurl, data, function(response) {
if (response.indexOf('true') > -1 || response == true) {
proceed = true;
} else {
alert("Error: " + response);
proceed = false;
}
});
jQuery('#ajax-loading').hide();
jQuery('#publish').removeClass('button-primary-disabled');
return proceed; //breakpoint here makes the code run
});
});
The code is adapted from a WPSE question, which originally didn't work for me as the form didn't get submitted. I found out that if the jQuery function bound to .submit() returns true, the form should be submitted, so that's what I tried to implement. With the code above, it doesn't seem to work at first (form doesn't get submitted when there are no errors), but upon close inspection with Firebug proceed seems to get the right result if a breakpoint is inserted at the return proceed line. It works as intended with valid data only if I wait it out a bit upon hitting the breakpoint, and then continue execution. If there are errors, the alert is issued without a problem.
What is the best way to handle this?
EDIT
Based on #Linus answer below, the following code works with both valid and invalid data:
jQuery(document).ready(function() {
jQuery('#post').submit(function() {
if(jQuery(this).data("valid")) {
return true;
}
var form_data = jQuery('#post').serializeArray();
var data = {
action: 'ep_pre_submit_validation',
security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
form_data: jQuery.param(form_data),
};
jQuery.post(ajaxurl, data, function(response) {
if (response.indexOf('true') > -1 || response == true) {
jQuery("#post").data("valid", true).submit();
} else {
alert("Error: " + response);
jQuery("#post").data("valid", false);
}
//hide loading icon, return Publish button to normal
jQuery('#ajax-loading').hide();
jQuery('#publish').removeClass('button-primary-disabled');
});
return false;
});
});
Short answer: You can't - not in this manner.
Some background: The callbacks you supply as arguments to functions such as $.post are executed asynchronously. This means that you will return proceed before your success callback has been executed, and proceed will always be false. With your breakpoint, if you wait until the success callback has executed, proceed will be true and all will be well.
So, if you want to submit the form after your ajax request has finished, you must submit it using javascript. This is pretty easy with jQuery, just do a jQuery $.post with data: $("yourForm").serialize() and url: yourForm.action.
This is basically what you already are doing, you just have to repeat that call to the URL to which you actually want to post the data.
EDIT:
Another way would be to set an attribute on your form, say valid, and in your submit handler check that:
jQuery("#post").submit(function() {
if($(this).data("valid")) {
return true;
}
// Rest of your code
});
And in the success callback for your validation ajax request you would set/clear that attribute, and then submit:
$("#post").data("valid", true).submit();
EDIT:
You also want to do your "ajax-loading"/button enabling inside the callback for $.post for the same reasons stated above - as it is, they will happen immediately, before your ajax call returns.
Bind your button to a validation function instead of submit. If it passes validation, call submit().
Wordpress has its own mechanism to process Ajax requests, using wp-admin/wp-ajax.php. This allows you to run arbitrary code on either side of the Ajax boundary without having to write the back and forth status-checking code and all that. Set up your callbacks and go....
The real question is - why are you doing validation server-side? Why can't you load in the validation criteria before - as the post is being written? Then your validation can happen real-time and not on-submit.
jquery.post is performed asynchronously, which means the JS will continue before it gets the reply. You're stuck with Diodeus's answer - bind the button to validtion which then submits the form (which makes it not degrade well), or change your $.post to ajax and turn off async, which will force it to wait for response before proceeding...possibly locking up JS on your page until it times out.
$.ajax({
type: 'POST',
url: ajaxurl,
async:false,
data: data,
timeout:3000,
success: function(){
}
});
I have multiple ajax requests some request data every minute others are initiated by the user through a ui.
$.get('/myurl', data).done(function( data ){
// do stuff..
});
The request might fail due to an authentication failure.
I've setup a global .ajaxError() method for catching any failed requests.
$(document).ajaxError(function( e, jqxhr ){
// Correct error..
});
After I catch the error I reset authorization.
Resetting the authorization works but the user has to manually re initiate the ajax call (through the ui).
How do I resend the failed request using the jqxhr originally sent?
(I'm using jQuery for the ajax)
Found this post that suggests a good solution to this problem.
The main thing is to use $.ajaxPrefilter and replace your error handler with a custom one that checks for retries and performs a retry by using the closure's 'originalOptions'.
I'm posting the code just in case it will be offline in the future. Again, the credit belongs to the original author.
// register AJAX prefilter : options, original options
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
originalOptions._error = originalOptions.error;
// overwrite error handler for current request
options.error = function( _jqXHR, _textStatus, _errorThrown ){
if (... it should not retry ...){
if( originalOptions._error ) originalOptions._error( _jqXHR, _textStatus, _errorThrown );
return;
};
// else... Call AJAX again with original options
$.ajax( originalOptions);
};
});
In this case, I would write a specific handler for the 403 status code, which means unauthorized (my server would return a 403 too). From the jquery ajax docs, you can do
$.ajax({
statusCode: {
403: function() {
relogin(onSuccess);
}
}
});
to achieve that.
In that handler, I would call a relogin method, passing a function that captures what to do when login succeeds. In this case, you could pass in the method that contains the call you want to run again.
In the code above, relogin should call the login code, and onSuccess should be a function that wraps the code you execute every minute.
EDIT- based on your clarification in comment, that this scenario happens for multiple requests, I personally would create an API for your app that captures the interactions with the server.
app = {};
app.api = {};
// now define all your requests AND request callbacks, that way you can reuse them
app.api.makeRequest1 = function(..){..} // make request 1
app.api._request1Success = function(...){...}// success handler for request 1
app.api._request1Fail = function(...){...}// general fail handler for request 1
/**
A method that will construct a function that is intended to be executed
on auth failure.
#param attempted The method you were trying to execute
#param args The args you want to pass to the method on retry
#return function A function that will retry the attempted method
**/
app.api.generalAuthFail = function(attempted, args){
return function(paramsForFail){ // whatever jquery returns on fail should be the args
if (attempted) attempted(args);
}
}
so with that structure, in your request1 method you would do something like
$().ajax({
....
statusCode: {
403: app.api.generalAuthFail(app.api.request1, someArgs);
}
}}
the generalAuthFailure will return a callback that executes the method you pass in.
The code below will keep the original request and it will try to success 3 times.
var tries = 0;
$( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
if(tries < 3){
tries++;
$.ajax(this).done(function(){tries=0;});
}
});
You could possibly go by the option of naming each one of your functions and then recalling them as stated in hvgotcodes' answers.
Or
You can use a reusable function to setup a request while extending the defaults:
function getRequest( options ){
var // always get json
defaults = { dataType: 'json' },
settings = $.extend( defaults, options );
return // send initial ajax, if it's all good return the jqxhr object
$.ajax( settings )
// on error
.fail(function( jqxhr, e ){
// if the users autherization has failed out server responds with a 401
if( jqxhr.status === 401 ){
// Authenticate user again
resetAuthentication()
.done(function(){
// resend original ajax also triggering initial callback
$.ajax( settings );
});
}
});
};
To use the above function you would write something like this:
getRequest({
url: 'http://www.example.com/auth.php',
data: {user: 'Mike', pass: '12345'},
success: function(){ // do stuff }
});
The getRequest() could probably be made recursive and/or converted into a jQuery plugin but this was sufficient for my needs.
Note: If the resetAutentication function might faile, getRequest() would have to be recursive.