How to send post with jquery onsubmit but still send form - javascript

I want to trigger this function, which uses the jquery's post method, when a form is submitted:
function update_point_session(){
$.post('/update_point_session/',
{session: true},
function(data){}
);
return true;
}
I uses the onsubmit to trigger it.
The problem is that it won't send it when the form is submitted. But if I return false; it will (though the form itself, of course, will not). It looks as if the $.post is not send before the page is directed to another one by the form..
So I think I somehow have to return true; AFTER the $.post. I tried to do this by putting it inside function(data){} but it did not work..
How can I send BOTH the post from jquery and from the form?

There are a couple of things you can do.
Make the AJAX synchronous
Since $.post is, according to the documentation, equivalent to
$.ajax({
type: 'POST',
url: url,
data: data,
success: success
dataType: dataType
});
You can simply replace $.post with the equivalent $.ajax call, and also add async: false to the options. This will submit the form with AJAX and then, due to the return true; from the function, will also let the browser post the form normally.
Submit the form only after the AJAX completes
This involves some event handler juggling:
// attach submit event handler to the form
$("#myform").submit(function() {
// Handler immediately detaches itself, so that
// we don't have an infinite loop when we call
// $(this).submit() ourselves below
$(this).unbind('submit');
// Do the AJAX
$.post(
'/update_point_session/',
{session: true},
function(data){
// When the AJAX completes, tell the browser
// to re-submit the form
$(this).submit();
}
);
// Prevent the browser from submitting it NOW,
// because the AJAX is still running
return false;
});

You must wait for the asynchronous post to complete before unloading the page. You can send back a redirect url from the server as json something like this:
$('form').submit(function(e){
$.post(this.action || '/update_point_session/', $(this).serialize(), function(data){
// send back a redirect url from the server
if(data.url) location.href = data.url;
});
e.preventDefault()
});

I would do something like this.
$('form#myFormId').submit(function(evt){
var form = $(this);
evt.preventDefault(); // Prevents default submission
$.post('/update_point_session/', {session: true}, function(data){
form.unbind('submit'); //Unbind js submit event
form.get(0).submit(); //submit the form
});
});

Related

PHP $_POST not working as expected

In one of my form i have a dropdownlist control on whose "onchange" event i am populating two textbox controls as shown below:
function pop_mli_n_murl(){
var wd_pid = document.getElementById("ddlUnder").value;
var dataString = 'wdpid='+ wd_pid;
$.ajax({
type: "POST",
url: "ldd_pop_wd_pdata.php",
data: dataString,
cache: false,
success: function(result){
var v1= result.substring(0,result.indexOf('='));
var v2= result.substring(result.indexOf('=')+1);
$("#txtMLI").val(v1);
$("#txtMLIURL").val(v2);
}
});
}
Up until here everything works fine. However when i submit the form, $_POST['txtMLI'] and $_POST['txtMLIURL'] is not set while the others are. Can you tell what could be the problem??
You probably forgot to prevent the NORMAL form submission, so your ajax request gets terminated. If the ajax call was succeeding, the ONLY form value you should ever receive would be $_POST['wdpid'], because that's the only thing your ajax code tries to send.
Getting the OTHER form values means the normal form submission occurred, NOT the ajax call.
That means you need something like
<form ... onsubmit="return pop_mli_n_murl()">
...
function pop_mi_n_murl() {
... ajax stuff ...
return false; // return false to onsubmit handler, terminating the normal submit
}
When you submit the ajax you're not posting txtMLI or xtMLIURL, you're only sending wdpid.
The data in the ajax should be something like
{
'wdpid': 'value here',
'txtMLI': 'value here',
'xtMLIURL': 'value here',
}
Then on the server side you'll be able to access those variables from the ldd_pop_wd_pdata.php script.

event.preventDefault(); not working in ajax

I am firing an ajax call on a signup form wherein i am checking whether the email id entered by the user has already been used or not.
Ajax Function :
<script>
$( "#becomesignup" ).submit(function( event ) {
$.ajax({
url : 'login', // Your Servlet mapping or JSP(not suggested)
data : {"email":$("#becomeemail").val()},
type : 'GET',
dataType : 'html', // Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
success : function(response) {
if(response == "true"){
$('#emailerrorbecome').slideDown();
$('#become-submit').prop('disabled', true);
event.preventDefault();
}else{
$('#emailerrorbecome').slideUp();
$('#become-submit').prop('disabled', false);
}
$('.black-screen').hide();
},
error : function(request, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
</script>
In the above ajax function, if the response is true then the email id is already been used and i need to show an error div($('#emailerrorbecome').slideUp();) and then prevent the form to get submitted. But even event.preventDefault() is not working causing the emaild id to be registered again.
Please help me with this. TIA
You should submit the form programatically and always preventing default behaviour in jq submit handler. E.g, using context and calling submit() DOM API method:
$("#becomesignup").submit(function(event) {
event.preventDefault(); /* prevent form submiting here */
$.ajax({
context: this, /* setting context for ajax callbacks*/
url: 'login', // Your Servlet mapping or JSP(not suggested)
data: {
"email": $("#becomeemail").val()
},
type: 'GET',
dataType: 'html', // Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
success: function(response) {
if (response == "true") {
$('#emailerrorbecome').slideDown();
$('#become-submit').prop('disabled', true);
$('.black-screen').hide(); /* hide it here */
} else {
$('#emailerrorbecome').slideUp();
$('#become-submit').prop('disabled', false);
this.submit(); /* 'this' refers to the FORM, and calling submit() DOM native method doesn't fire again jq handler */
}
},
error: function(request, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
For explanation of the why, see Quentin's answer
You cannot prevent the submit long after the submit function has returned. The Ajax result occurs much later.
You can instead flag the submit (e.g. use a sentinel variable) and cancel it unless allowed. Then trigger a submit from code in the Ajax callback.
Example:
var allowSubmit = false;
$( "#becomesignup" ).submit(function( event ) {
if (!allowSubmit){
$.ajax({
url : 'login', // Your Servlet mapping or JSP(not suggested)
data : {"email":$("#becomeemail").val()},
type : 'GET',
dataType : 'html', // Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
success : function(response) {
if(response == "true"){
$('#emailerrorbecome').slideDown();
$('#become-submit').prop('disabled', true);
// Enable next submit to proceed
allowSubmit = true;
// And trigger a submit
$( "#becomesignup" ).submit();
}else{
$('#emailerrorbecome').slideUp();
$('#become-submit').prop('disabled', false);
}
$('.black-screen').hide();
},
error : function(request, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
// return false does e.preventDefault(), and true allows it to proceed
return allowSubmit;
});
You are calling preventDefault to late.
Order of execution is this:
Event handler fires
HTTP request is sent
Event handler finishes
Prevent Default was not called so the default behaviour occurs
HTTP response is recieved
Success handler fires
Prevent Default is called … too late to have any effect
You can't wait for the HTTP response to come back before preventing the default behaviour.
You either need to always prevent the default behaviour and then conditionally resubmit the form with JS in the submit handler, or move the logic for when you use Ajax to perform your tests so it doesn't depend on the form submission event in the first place (e.g. run it as soon as the data has been entered and be prepared for the possibility that the form might get submitted before your JS has finished running).
you can make use of return false instead of eventPreventDefault.
I had been using the location.reload() as a dirty hack to refresh the page to prevent submission, but return false works well even without a refresh, it doesn't submit the form.

Javascript jQuery run ajax, get response before POST

Is there anyway to run an ajax script and have it get a response before running a form POST.
I don't want to post the main form via ajax. I just want it to work whereas when the user hits submit I want ajax to make a call and check a value then when the response comes back then the form will POST via the browser if the response is successful.
Thanks!
you need to intercept the submit event with preventDefault(), then make your ajax call and decide if you should submit the form or not (either traditional POST, or another ajax call)
sample code:
$('.form-selector').on('submit', function(e) {
e.preventDefault();
$.ajax({
// some call you want to make
}).done(function() {
e.target.submit(); // this submits the form without generating the event again
}).fail(function() {
// validation failed, do someting here
});
});
Why do not you try two Ajax call. On success of first ajax call you can POST your data.
So here I mean to say do validation on first Ajax call call and on Success of it do another Ajax call and POST your data to server.
var ajax=false; // form has not been submitted, AJAX not responded
$("form").submit( function(e){
if ( ajax == true ) return true; // if AJAX response, process form normally
// if no AJAX response, prevent form from submitting
e.preventDefault();
// talk to server
$.ajax({
....,
success: function(){
// AJAX successful! change value of variable, and submit form
ajax = true;
$("form").trigger("submit");
})
});
return false;
});
Use onSubmit method of your element, as in <form .... onSubmit="fetchData()">
Now, make your own function:
function fetchData(){
// send your ajax data and validate.
return true; // true or false depending on what you validated
}

Execute ajax request on form submit and don't wait for response

I want to make an AJAX request when the user attempts to submit a form. However, I don't want to wait for the response (I just want to trigger a script) and still submit the form immediately (or redirect the user).
I tried to to it this way (via jQuery):
$(document).ready(function()
{
$("#form").submit(function(e)
{
// save object reference
var form = this;
// prevent form submit
e.preventDefault();
// trigger ajax request
$.ajax({
url: 'ajax.php',
data: { ... },
cache: false
});
// submit form
form.submit();
// return false just in case
return false;
});
});
But this won't work, because the AJAX request will in fact not be sent by the browser, if the form is submitted immediately afterwards (via form.submit() ).
I am a bit puzzled here... is there really no way to fire an AJAX request and redirect the browser immediately afterwards?
It seems you create an infinite loop here. You are preventing the submit event and submitting it again at the end, but when you bind your function to the form's submission it will be called over and over. Instead, try to use Ajax states like success and complete; on success you submit data and on complete you redirect the page.

How to continue form submission after an AJAX call?

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(){
}
});

Categories