How to reset event.preventDefault() of a form submit event? - javascript

I have a form that submits shopping cart data to a payment gateway (WorldPay) payment processing page. I need to perform a couple of extra logic the moment the custom decides to proceed to the payment but before the form submission itself. Basically, I simply want to generate a unique reference to the order at the very last moment.
Here is the jQuery code for the submit event:
$(function(){
$('#checkout-form').submit(function(e){
var $form = $(this);
var $cartIdField = $('#cartId');
console.log($cartIdField.val());
if($cartIdField.val() == ''){
e.preventDefault();
$.ajax({
url: baseUrl + '/shop/ajax/retrieve-shopping-cart-reference/',
data: {}, type: 'post', dataType: 'json',
success: function(json){
if(json.error == 0){
$('#cartId').val(json.data.cart_reference_number);
$form.submit();
}else{
alert(json.message);
}
}
});
}else{
console.log('Submitting form...'); //Does not submit!
}
});
});
The problem is that during the second submit triggered within the success: clause, the form isn't submitted still. I am assuming event.preventDefault() persists beyond the current condition.
How can I get around this?

For performe the any operation before form submit i used the following menthod hope it wil help
$('#checkout-form').live("submit",function(event){
//handle Ajax request use variable response
var err =false;
var $form = $(this);
//alert($form);
var values = {};
$.each($form.serializeArray(), function(i, field) {
values[field.name] = field.value;
});
//here you get all the value access by its name [eg values.src_lname]
var $cartIdField = $('#cartId');
console.log($cartIdField.val());
if($cartIdField.val() == ''){
$.ajax({
// your code and condition if condition satisfy the return true
// else return false
// it submit your form
/*if(condition true)
{
var err =true;
}
else
{
var err = false;
}*/
})
}
else
{
return true;
}
if(err)
{
return false
}
else
{
return true;
}
})

e.preventDefault() remove default form submit attribute which can not be reverted if applied once.
Use below code instead to prevent a form before submitting. This can be reverted.
$('#formId').attr('onsubmit', 'return false;');
And below code to restore submit attribute.
$('#formId').attr('onsubmit', 'return true;');

Only call e.preventDefault() when you really need to:
if(not_finished_yet) {
e.preventDefault();
}

Related

Form is submitted even after using e.preventDefault()

I have a form which checks for the ifsc code of before form submission, The api returns "failure" if wrong ifsc is given. If the response is a failure, the form shouldn't be submitted. I used e.preventDefault(e) but it didn't help.
$('#corporate-signup').on('submit',function(e){
var ifsc_code = $('#ifsc-code').val();
var api_url = 'http://api.techm.co.in/api/v1/ifsc/'+ifsc_code;
$.get(api_url, function(data, status){
if (data.status === "failure") {
$('.bank-details').addClass('no-ifsc').text(data.message);
e.preventDefault(e);
}
else{
$('#corporate-signup').submit()
}
});
});
I don't know what is the mistake here. I have also tried to return false instead of preventDefault() but even it didn't work.
I think that because you use an async function and don't return false, it goes ahead and submits before waiting for an answer - it doesn't know to wait for the callback.
Since you manually submit inside the async callback, try to add e.preventDefault(e); after the $.get:
var shouldSubmit = false;
$('#corporate-signup').on('submit',function(e){
if (!shouldSubmit) {
// First time entering, this won't submit due to line below
e.preventDefault(e);
var ifsc_code = $('#ifsc-code').val();
var api_url = 'http://api.techm.co.in/api/v1/ifsc/'+ifsc_code;
$.get(api_url, function(data, status){
if (data.status === "failure") {
$('.bank-details').addClass('no-ifsc').text(data.message);
}
else{
shouldSubmit = true;
$('#corporate-signup').submit()
}
});
}
});
Edit: added shouldSubmit boolean, since otherwise it would keep hitting e.preventDefault(e) and never submitting. Upon a successful result from the async request, you can set it to true and resubmit.
Try this
$('#corporate-signup').on('submit',function(e){
e.preventDefault();
var ifsc_code = $('#ifsc-code').val();
var api_url = 'http://api.techm.co.in/api/v1/ifsc/'+ifsc_code;
$.get(api_url, function(data, status){
if (data.status === "failure") {
$('.bank-details').addClass('no-ifsc').text(data.message);
}
else{
$('#corporate-signup')[0].submit() // bypass jQuery bound event
}
});
});

How to submit this form without get into an infinite loop?

I have tried everything. I find other questions but no answer solves my problem:
$(document).on('submit', 'form#formNuevoContacto', function(event) {
var $form = $(this);
var $accionActual = $form.find('#action');
$form.find('#action').val('validate');
$.post($form.attr("action"), $form.serialize(), function(response) {
if (response.resultValidation == "true") {
$form.submit(); // ==> INFINITE LOOP!
} else {
alert('Form is not valid!');
}
});
event.preventDefault();
});
I tried: $form.unbind().submit() but didn't work.
You could use a toggle to selectivelly pre-process the submit or otherwise let the browser do its job; In the edit bellow, just before issuing the second submit I place a variable in the form object called "isPreProcessing". As you can see, the first thing the code does is to check if this value is present, and if so, delegate the submit to the browser.
$(document).on('submit', 'form#formNuevoContacto', function(event) {
if(this.isPreProcessing) {
//allow for actual submit to run
this.isPreProcessing = false;
return;
}
var $form = $(this);
var $accionActual = $form.find('#action');
$form.find('#action').val('validate');
$.post($form.attr("action"), $form.serialize(), function(response) {
if (response.resultValidation == "true") {
//prevent the loop
this.isPreProcessing = true;
$form.submit();
} else {
alert('Form is not valid!');
}
});
event.preventDefault();
});
You should just do a single ajax call, and handle the error if it doesn't validate. If the server validates it, the server should then store it. It is messy code as you have it now, and it is also a waste of an ajax call/waste of time. You're posting the exact same data twice
$.ajax({
type: {most like put 'POST' here},
url: {action url},
data: {your form},
success: success_function(),
error: error_function()
});

Only send post/get if form values has changed

I want to prevent multiple ajax calls (user holds enter key down or multi presses submit or other)
I'm thinking, the best way is to use a var with the previous form post values and compare them at each click/submit.. Is it the same? : Then do nothing
But I don't know how to go about it
Here is my javascript/jquery:
$('form').submit(function() {
$theform = $(this);
$.ajax({
url: 'validate.php',
type: 'POST',
cache: false,
timeout: 5000,
data: $theform.serialize(),
success: function(data) {
if (data=='' || !data || data=='-' || data=='ok') {
// something went wrong (ajax/response) or everything is ok, submit and continue to php validation
$('input[type=submit]',$theform).attr('disabled', 'disabled');
$theform.unbind('submit').submit();
} else {
// ajax/response is ok, but user input did not validate, so don't submit
console.log('test');
$('#jserrors').html('<p class="error">' + data + '</p>');
}
},
error: function(e) {
// something went wrong (ajax), submit and continue to php validation
$('input[type=submit]',$theform).attr('disabled', 'disabled');
$theform.unbind('submit').submit();
}
});
return false;
});
Not very creative with naming vars here:
var serial_token = '';
$('form').submit(function() {
$theform = $(this);
if ($(this).serialize() === serial_token) {
console.log('multiple ajax call detected');
return false;
}
else {
serial_token = $(this).serialize();
}
$.ajax({
url: 'validate.php',
type: 'POST',
cache: false,
timeout: 5000,
data: $theform.serialize(),
success: function(data) {
if (data=='' || !data || data=='-' || data=='ok') {
// something went wrong (ajax/response) or everything is ok, submit and continue to php validation
$('input[type=submit]',$theform).attr('disabled', 'disabled');
$theform.unbind('submit').submit();
} else {
// ajax/response is ok, but user input did not validate, so don't submit
console.log('test');
$('#jserrors').html('<p class="error">' + data + '</p>');
}
},
error: function(e) {
// something went wrong (ajax), submit and continue to php validation
$('input[type=submit]',$theform).attr('disabled', 'disabled');
$theform.unbind('submit').submit();
}
});
return false;
});
You could combine this with a timeout/interval function which aborts the submit, but the code above should just compare the data in the form
If you have some kind of submit button, just add a class 'disabled' to it when you start the ajax call, and check if it is present before trying to make the call. Remove the class when the server gives a response. Something like:
...
$theform = $(this);
$button = $theform.find('input[type=submit]');
if ($button.hasClass('disabled')) {
return false;
}
$button.addClass('disabled');
$.ajax({
....
},
complete: function () {
$button.removeClass('disabled');
}
});
...

How can I disable/enable form submit in an ajax request

I'm trying first disabling form submission before the request starts and then on success enable again the form submit
this is my code:
$.ajax({
beforeSend:function(){
//disable form
$('form').on('submit',function(){
return false;
});
},
success:function(){
//enable form
$('form').on('submit',function(){
return true;
});
},
complete:function(){
//enable form
$('form').on('submit',function(){
return true;
});
,
});
it seems not working on success and complete, the form is disabled but not enabled then.
I'm using latest jQuery version.
Better use different strategy: Set a global variable to decide whether or not to submit the form. Then check it while submitting the form.
var canSubmit = 1;
$.ajax({
beforeSend:function(){
//disable form
canSubmit = 0;
},
success:function(){
//enable form
canSubmit = 1;
},
complete:function(){
//disable form
canSubmit = 1;
});
$('form').on('submit',function() {
if (!canSubmit) {
return false;
}
});
jQuery events normally support multiple handlers so you would need to turn the previous event handlers off before attaching a new one.
To use off you need to keep a reference to your handler e.g.
var myForm = $("form"),
enableSubmit = function(event) { return true; },
disableSubmit = function(event) { return false; },
ajaxCompleteHandler = function() {
myForm.off(disableSubmit);
myForm.on(enableSubmit);
};
myForm.on(enableSubmit);
$.ajax({
beforeSend: function() {
myForm.off(enableSubmit);
myForm.on(disableSubmit);
},
success: ajaxCompleteHandler,
error: ajaxCompleteHandler,
complete: ajaxCompleteHandler //you might get away with just this as I believe it's called for success and failure
});
Alternatively you could just disable the submit button ($("mybutton").prop("disabled", true))which should be more intuitive to the user.
Instead of doing a return false in beforeSend try this
$('form').on('submit',function(e){
e.preventDefault();
return false;
});
Once you return false on the submit button,it is obvious that you cannot again invoke submit operation, because the form is not now able to submit info.
The another solution is that use onclick function,like below :
Javascript file
function savecustomquestion(){
$.ajax({
type : 'POST',
url : 'customquestion.php',
data:{tablename:$('#productname').val(),name:$('#uname').val(),email_address:$('#email').val(),voucher_code:$('#voucher_code').val(),question:$('#customquestion').val()},
success: function(response){
console.log("yes");
},
error : function(response){
console.log(response);
}
});
}
HTML code
<button type="button" id="customquestionbutton" class="span2" onclick="savecustomquestion()">Verstuur</button>
PHP code
mysql_select_db('mydatabase',$connect);
if(!isset($_POST['voucher_code'])){
$voucher_code = "";
}
else{
$voucher_code = $_POST['voucher_code'];
}
$email_address = $_POST['email_address'];
$name = $_POST['name'];
$question = $_POST['question'];
$tablename = $_POST['tablename'];
mysql_query("insert into customquestion (voucher_code,email_address,name,question) VALUES('$voucher_code','$email_address','$name','$question') ");

jQuery ajax: how to destroy submit if ajax validation fails?

I have email field in user's settings area. All emails are unique, of course, so I need to check is email not used already by someone else before submitting the form.
Here is the code:
var email = $("input#email-id").val();
$("#form-id").submit(function(){
$.ajax({
url: "/ajax/email?email=" + email,
success: function(data){
if(data != 'ok'){
alert("Email is used already");
return false;
}
}
});
});
So, if data is not 'ok' it must destroy submitting the form because if() returns false, but it doesn't and the form submits as usual and even alert doesn't appear!
I've checked ajax answer and it works fine (returns 'user_already' if email is used).
So what I did wrong?
Thanks!
Since ajax is async by nature you cannot do that. If you really want to do that you can submit the form inside the success handler. Try this.
function submitHandler(){
var email = $("input#email-id").val();
$.ajax({
url: "/ajax/email?email=" + email,
success: function(data){
if(data != 'ok'){
alert("Email is used already");
return false;
}
else{
//Once the data is ok you can unbind the submit handler and
//then submit the form so that the handler is not called this time
$("#form-id").unbind('submit').submit();
}
}
});
return false;//This will prevent the form to submit
}
$("#form-id").submit(submitHandler);
It's because the Ajax request to check the email is asynchronous. It will not complete before the submit event handler is finished. You'd have to do something like this:
$('#form-id').submit(function() {
if($(this).data('valid')) {
//you've already validated, allow the form to submit
return true;
} else {
//send an ajax request and wait for the response to really submit
$.ajax({
url: "/ajax/email?email=" + email,
success: function(data){
if(data == 'ok') {
//submit the form again, but set valid data so you don't do another Ajax request
$('#form-id').data('valid', true);
$('#form-id').submit();
} else {
alert("Email is used already");
}
}
});
return false;
}
//clear the validation flat
$(this).data('valid', false);
});
There's an accepted answer but I thought I'd share another way to do this.
You can use an extra parameter with the .trigger() function to first test the user's email, and if it comes back available then re-trigger the submit event but set a flag to not check the username:
$("#form-id").submit(function(event, forceSubmit){
//the normal submit will not have the extra parameter so we need to initialize it to not throw any errors,
//typeof is great for this since it always returns a string
if (typeof(forceSubmit) == 'undefined') { forceSubmit = false; }
//now check if this is a normal submit or flagged to allow submission
if (forceSubmit === false) {
var $form = $(this);
$.ajax({
url: "/ajax/email?email=" + email,
success: function(data){
if(data != 'ok'){
alert("Email is used already");
} else {
$form.trigger('submit', true);
}
}
});
//since this submit event is for checking the username's availability we return false to basically: event.preventDefault(); event.stopPropagation();
return false;
}
});
.trigger(): http://api.jquery.com/trigger
In your code you have two functions. One is the function passed to submit:
$("#form-id").submit(function() {
// code
});
The other is the function passed to the success handler of the AJAX call:
success: function(data) {
// code
}
You are returning false from the second function. This means that when the first function returns, it is not returning false. But the form submission is stopped, only if the first function returns false.
What you should do is to make the function passed to submit always return false and handle submission programmatically.
This code helps you to achieve this:
var submitHandler = function() {
$.ajax({
url: "/ajax/email?email=" + email,
success: function(data) {
if (data != 'ok') {
alert("Email is used already");
// no need to do anything here
} else {
// success, we should submit the form programmatically
// first we de-attach the handler, so that submitHandler won't be called again
// and then we submit
$("#form-id").unbind('submit').submit();
// now we reattach the handler, so that submit handler is executed if the user
// submits the form again
$("#form-id").submit(submitHandler);
}
}
});
// always return false, because if validation succeeds, we will submit the
// form using JavaScript
return false;
};
$("#form-id").submit(submitHandler);
I already +1 #ShankarSangoli because he got it right however, I don't feel its 100% complete as there is also an error state that can occur upon network issues or server fault.
$('#form-id').submit(function(ev) {
ev.preventDefault(); // cancels event in jQuery typical fashion
$.ajax({
url: "/ajax/email",
data : { email: $("input#email-id").val()},
success : function(d) {
if (d !== 'ok') {
alert('email in use');
}
},
error : function(a,b,c) {
// put your error handling here
alert('a connection error occured');
}
});
});
There are even better ways to handle this as I've written some great form plugins for jQuery that are HTML5 compliant and rival jQuery tools for ease of use.
You can see an example here -> http://www.zipstory.com/signup
Happy coding.
If JSON is involved, the returned data is in data.d - see http://encosia.com/a-breaking-change-between-versions-of-aspnet-ajax/ for an explanation.

Categories