event.preventDefault(); not working in ajax - javascript

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.

Related

How to break ajax requests with mouse click

First ajax request is triggered after mouse click of Button A. Based on response received another ajax request is fired. This another request is fired in ajaxComplete event handler.
So my continuous ajax request chain works well.
Now I have a condition, if Button B is clicked, I need to break ajax chain.
Code worked in Chrome browser. In case of Firefox, Button B's onclick is not getting triggered. Also generic $(document).on('click'.. event is not getting catched.
$.ajax({
url: url,
async: false,
type: post,
dataType: dataType,
data: data,
success: xyz,
error: abc
});
...
xyz = function() { binded = true }
...
$(document).ajaxComplete(function() {
if(binded || binded=='true') {
//fire ajax requests again and again till server gives timeout
}
});
$(document).on('click', 'input[id=openApplication]', function(event) {
binded = false;
alert('Breaking ajax loop');
// do form submit using Input - Sumbit type
});

ajaxSubmit calls the success callback even when there is an error

I'm using jquery.form.js and ajax to submit my forms. The problem I have is even when it's not on success (when there is an error) also the ajax is resetting the form no matter it is in code only to do it on after success.
Here is the code:
<script>
$(document).ready(function()
{
$('#FileUploader').on('submit', function(e)
{
e.preventDefault();
$('#submit').attr('disabled', ''); // disable upload button
//show uploading message
$("#loadding").html('<div class="loader"><img src="images/ajax-loader.gif" alt="Please Wait"/> <br/><span>Submiting...</span></div>');
$(this).ajaxSubmit({
target: '#output',
success: afterSuccess //call function after success
});
});
});
function afterSuccess()
{
$('#FileUploader').resetForm(); // reset form
$('#submit').removeAttr('disabled'); //enable submit button
$('#loadding').html('');
}
</script>
Can someone point out where is the problem. Thanks in advance.
$(this).ajaxSubmit({
target: '#output',
success: afterSuccess,
error:error
});
function error(response,status,xhr){
alert("error");}
will work as i had implemented same concept in my project and it works fine.
Did you change the http status code of the server response if an error occuring ?
For jQuery, success = 2xx http status code return in the response and error = 4xx
If you didn't change the header of response, for your jQuery code, it's always a success!!!
So 2 solutions :
You can change the http header code status if it's an error.
You can return a different content in response and check it in your success function.
Other point: change the definition of the success property like behind.
success: function () { afterSuccess(); } //call function after success
Why ? Because, if you declare directly the function, it will be execute during the ajaxSubmit() configuration, maybe it's solve your problem, because before the response of the server, afterSuccess() will be called.
The success event will always fire if the HTTP response code is in the 200-299 range (or === 304), anything else and it won't fire. So I'm guessing that your server side code responds with 200 OK even when there is a problem.
If the server outputs a value such as true you can test the response text for that:
$(this).ajaxSubmit({
target: '#output',
success: function(response) {
if(response == "true") {
afterSuccess();
}
}
});

Ajax with Jquery - Callback not executing

I have tried so many things, cannot figure this out, I am using this code, and I know that the start is working, because the script it connects to sticks some info in the db, but the callback never runs.
<script type="text/javascript">
$(document).ready(function() {
$(document.body).on('click', "#reply_submit", function() {
var formData = $('#reply').serialize();
$.post("newpost.php",formData, function(data){
alert("hi");
}, "json");
});
});
My form's id is "reply" and the button I am using to submit it is "reply-submit", just to make sure those things are clear.
It also doesn't work if I remove that last "json" thing btw.
If you read the docs for jQuery.post(), it says this about the callback:
success(data, textStatus, jqXHR)
A callback function that is executed if the request succeeds.
If it's not getting called, it means that request did not succeed. There is probably an error in newpost.php (sometime after the data insert, but before it would normally exit).
You can also catch error conditions by using the long-form jQuery.ajax() instead of the post shorthand:
$.ajax({
url: 'newpost.php',
data: formData,
type: 'post',
dataType: 'json',
success: function(data, textStatus, jqXHR) {
alert('success');
},
error: function(jqXHR, textStatus, errorThrown) {
alert('error!');
}
});
When you click, the form is also being submitted the standard way. Modify your click handler like this:
$(document).on('click', "#reply_submit", function(e) {
e.preventDefault(); // prevent the default submit event
var formData = $('#reply').serialize();
// ...
});
Although I think document.body should be a valid node to wrap in jQuery, I've also modified it to the more commonly used document.
On that note, if the form is never destroyed by an Ajax event or other DOM modification, you could bind to #reply instead of document (or body).
I'm simply assuming that you want to submit a form without reloading the whole page.
Based on that assumption, following code will serve the purpose.
$(document).ready(function(){
//on form submit event
$('form#reply').submit(function(){
$.post('newpost.php',$(this).serialize(),function(){
alert("Message or do something with the response data if you are expecting one");
});
//prevent default action
return false;
});
});
Please ignore the post if this is not the functionality you are looking for in your project.

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

How to send post with jquery onsubmit but still send form

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

Categories