JQuery prevent form from being submitted inside ajax [duplicate] - javascript

This question already has answers here:
How to stop form submit during ajax call
(7 answers)
Closed 2 years ago.
I am new to JQuery and ajax in general and I want to disable form submit after I get data from my controller back (I am using Asp.net core MVC). Thing is that even tho I cancel submit it submits anyways as shown bellow:
$("form").submit(function (e) {
var link = '#Url.Action("Action", "Controller")';
var args = {
arg1: Elem1.val(),
arg2: Elem2.val()
};
$.ajax({
type: "GET",
url: link,
data: args,
dataType: "json",
success: function (data) {
alert(data.canacess); //Shows False
if (data.canacess== true) {
AllEnable();
}
else { //Goes here
e.preventDefault(); //Dont do this
alert(data.erromessage); //Do this
}
},
error: function () {
alert("Error. Kontaktujte správce.");
return;
}
});
});
I think it has to do something with ajax because anywhere else in code it works.
Thanks for any help!

e.preventDefault() needs to be invoked within the scope of the submit function handler. Right now you're invoking it in the AJAX callback handler which is far too late to have any effect.
Is there any way that I can stop form from being submitted until I decide whether I submit it or not?
Yes. To do that you need to always call e.preventDefault() in order to stop the form submission so that you give the AJAX request time to execute and return a response. Then, based on that response, you can directly submit the HTMLFormElement object, note not the jQuery object, and send the form data to the specified action. Try this:
$("form").submit(function(e) {
e.preventDefault();
var form = this;
$.ajax({
type: "GET",
url: '#Url.Action("Action", "Controller")',
data: {
arg1: Elem1.val(),
arg2: Elem2.val()
},
dataType: "json",
success: function(data) {
if (data.canacess) {
AllEnable();
form.submit();
}
},
error: function() {
alert("Error. Kontaktujte správce.");
}
});
});
Also note that when using boolean values in conditions it's redundant to compare them to true/false. Similarly, the return in the error handler is redundant as it's the last statement in the function anyway.

Related

Ajax ignores html validation

$('#addProduct').click(function (e) {
$('#qty').attr('required', 'required');
$('#product_id').attr('required', 'required');
e.preventDefault();
var product_id = $('#product_id').val();
var data = $("#editOrderContent").serializeArray();
data.push(addProduct);
$.ajax({
type: 'POST',
dataType: 'JSON',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: $('#editOrderContent').attr('action'),
data: data,
success: function (html) {
if (html.error) {
$('.wrap_result')
.text(html.error)
.fadeIn(500).delay(3000).fadeOut(500);
}
else if (html.success) {
$('#summary').before(html.tdProduct);
$('#summary_qty').text(html.summaries['qty']);
$('#summary_price').text(html.summaries['price'] + ' $.');
$('#summary_sum').text(html.summaries['sum'] + ' $.');
$('#product_id').val('');
$('#qty').val(1);
}
}
});
});
These 2 fields has required attributes but ajax still completing even with empty values in these fields, also ajax ignores min value of #qty field
Why is this happening?
Use $('#formid').valid() method before making ajax request read more about .valid()
e.preventDefault tells the event NOT to perform it's default action of submitting the form.
You're then making the fields required. That's fine - but they'll only be checked on submit. The form isn't actually being submitted at any point, you've told it to prevent that action.
You need to add a $('#form').submit(); Or add required directly to the html markup.
EDIT: Much more code added to the question. This may no longer apply.

Ajax after ajax request, submit form normal way

I have ajax request:
<script>
$("#abc_form_submit").click(function(e) {
e.preventDefault();
//........
$.ajax({
type: "POST",
url: url,
dataType: 'json',
data: $("#abc_form").serialize(), // serializes the form's elements.
success: function(data)
{
if(data.success == 'false') {
// show errors
} else {
// SUBMIT NORMAL WAY. $("#abc_from").submit() doesnt work.
}
}
});
return false; // avoid to execute the actual submit of the form.
});
</script>
And php
.....
return $this->paypalController(params, etc...) // which should redirect to other page
.....
How should i make that ajax request if success, submit form normal way, because now if I redirect (at PHP) its only return response, but i need that this ajax request would handle php code as normal form submit (if success)
Dont suggest "window.location" please.
I would add a class to the form to test if your ajax has already occured. if it has just use the normal click funciton.
Something like:
$('form .submit').click(function(e) {
if (!$('form').hasClass('validated'))
{
e.preventDefault();
//Your code here
$.post(url, values, function(data) {
if (success)
{
$('form').addClass('validated');
$('form .submit').click();
}
});
}
}
Why don't you use a result variable that you update after a succesful AJAX request?
<script>
$("#abc_form_submit").click(function(e) {
e.preventDefault();
// avoid to execute the actual submit of the form if not succeded
var result = false;
//........
$.ajax({
type: "POST",
url: url,
dataType: 'json',
async: false,
data: $("#abc_form").serialize(), // serializes the form's elements.
success: function(data)
{
if(data.success == 'false') {
// show errors
} else {
// SUBMIT NORMAL WAY. $("#abc_from").submit() doesnt work.
result = true;
}
}
});
return result;
});
</script>
I've had this issue before where I needed the form to submit to two places, one for tracking and another to the actual form action.
It only worked by submitting it programatically when you put the form.submit() behind a setTimeout. 500ms seems to have done the trick for me. I'm not sure why browsers have trouble submitting the form programatically when they are attempting to submit them traditionally, but this seems to sort it out.
setTimeout(function(){ $("#abc_from").submit(); }, 500);
One thing to keep in mind though once it submits, that's it for the page, it's gone. If you still want whatever processes are running on the page to run, you will need to set the target of the form to _blank so that it will submit in a new tab.

validating form before it submit

WHAT IM DOING
I'm using jquery to validate form before it is send to server.
I'm validating every input, and if any of them return false i call event.preventDefault() and show the errors.(if it returns true I do nothing...)
THE PROBLEM
It was working fine, the script always run before the form send itself, but now I'm validating email, using ajax - checking if email isnt already in db or if the domain exists... but when the ajax starts, the the form wont wait until its finished and sends itself before the ajax finish and the input validates.
SOME SOLUTIONS MAYBE
I could call event.preventDefault() and after the validation is completed and it returns true I could try to undo the preventDefault perhabs by unbind and then submit through jquery submit the form again.
Or perhabs I could do onsubmit="checkInputs();" and it should wait until it returns true or false...
Solution - Adapted from the accepted answer by user Mirage
function validate(){
$.ajax({
url: 'http://google.nl',
async: false,
type: "POST",
data: {test:'request'},
success: function(data){
console.log(data);
}
});
return data; // important
}
try to add
async: false
example:
$.ajax({
url: 'http://google.nl',
async: false,
type: "POST",
data: {test:'request'},
success: function(data){
console.log(data);
}
});
you want:
onsubmit="checkInputs(); return false;"
Then you would grab the form e.g:
var frm = document.getElementById("myfrm");
frm.submit();
You would place the above in the else condition of your validation logic. Hope this helps.
Your script flow should be something like this:
Bind onsubmit handler
Send vars to server with ajax
Check results
When validates: remove handler and post form
When false: show error messages and start over again.
And in code:
var handleValidationResponse = function(data) {
if(data.errors != 0) {
alert('Sorry my dear user, but you made a mistake');
return false;
}
// aight, so it's all fine
$('#myForm').off('submit').trigger('submit'); // unbind custom submit handler and post the form
};
$('#myForm').on('submit', function(e) {
e.preventDefault();
var $this = $(this);
var serializedFormData = $this.serializeArray();
$.post($this.attr('action'), serializedFormData, function(data) {
handleValidationResponse(data);
});
});
That should be it!

Stop an ajax request from posting data until a response is received?

i have written a basic commenting system which is a simple write to database form and it uses ajax as well.
The issue is that if i enter my message, and then spam send / the enter key it seems to stack up and then everything is written to the database multiple times.
My ajax is like so:
$(document).ready(function(){
$(document).on('submit', '.addcomment', function() {
var $targetForm = $(this);
$.ajax({
type: "POST",
url: "process/addcomment.php",
data: $targetForm.serialize(),
dataType: "json",
success: function(response){
if (response.databaseSuccess == true) {
$("#container").load("#container");
$targetForm.find('#addcommentbutton').attr("disabled", true);
}
else {
$ckEditor.after('<div class="error">Something went wrong!</div>');
}
}
});
return false;
});
});
The submit button does become disabled, but the form can still be entered via the enter keyboard button or even still with a mass spam of the submit button (which is supposed to be disabled)
Is there a way to 100% disable this form with jquery, until the success JSON message is received?
Anymore code just let me know!
In this case, i would not use delegation. I would instead bind the event directly to the form using .one since each form should submit only once (if that's the case.) If you instead only have one addComment form, then i question why you are using delegation in the first place.
$(commentForm).appendTo(selector).one("submit",function(e){
e.preventDefault(); // prevent this submit
$(this).submit(false); // prevent future submits
// submit data to server
})
Just keep track of if a request is in progress:
$(document).ready(function(){
var isSubmitting = false;
$(document).on('submit', '.addcomment', function() {
var $targetForm = $(this);
if (!isSubmitting) {
isSubmitting = true;
$.ajax({
...
success: function(response){
...
},
complete: function() { isSubmitting = false; }
});
}
});
There are lots of ways to handle this, but the best involves validating the data on the server end. You want to prevent people from overloading the database inadvertently (the "fat finger" problem) or deliberately (the bored script kiddie who decides to crash your server or fill your database with garbage).
The best solution:
Generate a one-time token when the page is requested (called a "nonce")
Post that nonce when you post the data
Only accept it on the server side if the nonce has never been used
This obviously requires you to keep track of a list of valid nonces, but it prevents any glitches or abuse of the send button.
Also, as others have pointed out, disable the button much earlier and only run the submit action handler once. That will help with the inadvertent double-clicks and so on, but you also need the nonce to prevent compulsive clickers or intentional misuse.
Can you do it like below:
$(document).ready(function(){
var isAjaxInProgress = null;
$(document).on('submit', '.addcomment', function() {
var $targetForm = $(this);
if(isAjaxInProgress === null || !$isAjaxInProgress ){
isAjaxInProgress = true;
$.ajax({
type: "POST",
url: "process/addcomment.php",
data: $targetForm.serialize(),
dataType: "json",
success: function(response){
if (response.databaseSuccess == true) {
$("#container").load("#container");
$targetForm.find('#addcommentbutton').attr("disabled", true);
}
else {
$ckEditor.after('<div class="error">Something went wrong!</div>');
}
isAjaxInProgress = false;
}
});
}
return false;
});
});
// declare a global ajax request variable
var is_request_sent = false;
function send_msg()
{
if(is_request_sent == false)
{
$.ajax({
type: "POST",
url: "process/addcomment.php",
data: $targetForm.serialize(),
dataType: "json",
success: function(result){
//alert(result);
is_request_sent = false;
},
error: function(a,b,c)
{
is_request_sent = false;
},
beforeSend: function(jqXHR, plain_jqXHR){
// set request object
is_request_sent = jqXHR;
// Handle the beforeSend event
},
complete: function(){
// update global request variable
is_request_sent = false;
// Handle the complete event
}
});
}
}

jQuery override event.preventDefault()

I have a form that, when submitted, goes through the usual e.preventDefault() and sends an ajax request instead. However, if this ajax request returns a certain condition, I want the form to be submitted normally. How do I achieve this?
// Submit handler
$(".reserveer_form").submit(function(event){
event.preventDefault();
$.ajax({
url: $(this).attr("action"),
data: $(this).serialize(),
success: function(data) {
if($(".messagered",data).length > 0){
var errors = $(".messagered",data);
$(".gegevens").before(errors);
} else {
// SUBMIT THE FORM!
}
}
});
})
Invoke the native submit method on the form, so that it doesn't trigger the jQuery handler.
$.ajax({
context: this, // <-- set the context.
url: $(this).attr("action"),
data: $(this).serialize(),
success: function (data) {
if ($(".messagered", data).length > 0) {
var errors = $(".messagered", data);
$(".gegevens").before(errors);
} else {
this.submit(); // <-- submit the form
}
}
});
Since your comment says you change a form variable, you could start your submit handler by checking that same form variable. If it is changed, just return true. If not, continue with the current handler.
You can use the submit() method or forms:
$(".reserveer_form").submit(function(event){
event.preventDefault();
var form = this,
$form = $(form);
$.ajax({
url: $form.attr("action"),
data: $form.serialize(),
success: function(data) {
var errors = $(".messagered", data);
if (errors.length > 0){
$(".gegevens").before(errors);
} else {
form.submit();
}
}
});
})
However, this seems to be a strange ajax request. First, you send the form (serialized, via ajax) to the server, and when the response contains no errors you send it again? The server would process it twice (and act twice, depending on your form). Also, the user does not get a message that his input is already processed - he clicks "submit", and it always takes a time until it is visibly submitted (where he even could change some input).

Categories