在调用 e.proventDefault()之后提交表单

我在这里做一些简单的表单验证,遇到了一个非常基本的问题。我有5个场地对的名字和主菜(晚餐注册)。用户可以输入1-5对,但是如果存在名称,则必须选择一个主菜。密码:

Http://jsfiddle.net/eectn/1/

<form>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
<input type="submit" value="Submit">
</form>
// Prevent form submit if any entrees are missing
$('form').submit(function(e){


e.preventDefault();


// Cycle through each Attendee Name
$('[name="atendeename[]"]', this).each(function(index, el){


// If there is a value
if ($(el).val()) {


// Find adjacent entree input
var entree = $(el).next('input');


// If entree is empty, don't submit form
if ( ! entree.val()) {
alert('Please select an entree');
entree.focus();
return false;
}
}
});


$('form').unbind('submit').submit();


});

错误消息正常工作,但每次都要提交表单。我知道这一行有问题:

$('form').unbind('submit').submit();

但我不知道该怎么做。

159789 次浏览

Use the native element.submit() to circumvent the preventDefault in the jQuery handler, and note that your return statement only returns from the each loop, it does not return from the event handler

$('form').submit(function(e){
e.preventDefault();


var valid = true;


$('[name="atendeename[]"]', this).each(function(index, el){


if ( $(el).val() ) {
var entree = $(el).next('input');


if ( ! entree.val()) {
entree.focus();
valid = false;
}
}
});


if (valid) this.submit();


});
$('form').submit(function(e){


var submitAllow = true;


// Cycle through each Attendee Name
$('[name="atendeename[]"]', this).each(function(index, el){


// If there is a value
if ($(el).val()) {


// Find adjacent entree input
var entree = $(el).next('input');


// If entree is empty, don't submit form
if ( ! entree.val()) {
alert('Please select an entree');
entree.focus();
submitAllow = false;
return false;
}
}
});


return submitAllow;


});

The problem is that, even if you see the error, your return false affects the callback of the .each() method ... so, even if there is an error, you reach the line

$('form').unbind('submit').submit();

and the form is submitted.

You should create a variable, validated, for example, and set it to true. Then, in the callback, instead of return false, set validated = false.

Finally...

if (validated) $('form').unbind('submit').submit();

This way, only if there are no errors will the form be submitted.

The simplest solution is just to not call e.preventDefault() unless validation actually fails. Move that line inside the inner if statement, and remove the last line of the function with the .unbind().submit().

Sorry for delay, but I will try to make perfect form :)

I will added Count validation steps and check every time not .val(). Check .length, because I think is better pattern in your case. Of course remove unbind function.

My jsFiddle

Of course source code:

// Prevent form submit if any entrees are missing
$('form').submit(function(e){


e.preventDefault();


var formIsValid = true;


// Count validation steps
var validationLoop = 0;


// Cycle through each Attendee Name
$('[name="atendeename[]"]', this).each(function(index, el){


// If there is a value
if ($(el).val().length > 0) {
validationLoop++;


// Find adjacent entree input
var entree = $(el).next('input');


var entreeValue = entree.val();


// If entree is empty, don't submit form
if (entreeValue.length === 0) {
alert('Please select an entree');
entree.focus();
formIsValid = false;
return false;
}


}


});


if (formIsValid && validationLoop > 0) {
alert("Correct Form");
return true;
} else {
return false;
}


});

Why not bind the submit button event than the form itself? it would really much easier and safer if you bind the buttons than the form itself as the form will mostly submit unless you will use preventDefault()

$("#btn-submit").on("click", function (e) {
var submitAllow = true;
$('[name="atendeename[]"]', this).each(function(index, el){
// If there is a value
if ($(el).val()) {
// Find adjacent entree input
var entree = $(el).next('input');


// If entree is empty, don't submit form
if ( ! entree.val()) {
alert('Please select an entree');
entree.focus();
submitAllow = false;
return false;
}
}
});
if (submitAllow) {
$("#form-attendee").submit();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form-attendee">
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
<button type="button" id="btn-submit">Submit<button>
</form>

Actually this seems to be the correct way:

$('form').submit(function(e){


//prevent default
e.preventDefault();


//do something here


//continue submitting
e.currentTarget.submit();


});

came across the same prob and found no straight solution to it on the forums etc. Finally the following solution worked perfectly for me: simply implement the following logic inside your event handler function for the form 'submit' Event:

document.getElementById('myForm').addEventListener('submit', handlerToTheSubmitEvent);


function handlerToTheSubmitEvent(e){
//DO NOT use e.preventDefault();
   

/*
your form validation logic goes here
*/


if(allInputsValidatedSuccessfully()){
return true;
}
else{
return false;
}
}

SIMPLE AS THAT; NOTE: when a 'false' is returned from the handler of the form 'submit' event, the form is not submitted to the URI specified in the action attribute of your html markup; until and unless a 'true' is returned by the handler; and as soon as all your input fields are validated a 'true' will be returned by the Event handler, and your form is gonna be submitted;

ALSO NOTE THAT: the function call inside the if() condition is basically your own implementation of ensuring that all the fields are validated and consequently a 'true' must be returned from there otherwise 'false'

Binding to the button would not resolve for submissions outside of pressing the button e.g. pressing enter

In my case there was a race, as I needed the ajax response to fill a hidden field and send the form after it's filled. I fixed it with putting e.preventDefault() into a condition.

var all_is_done=false;
$("form").submit(function(e){
if(all_is_done==false){
e.preventDefault();
do_the_stuff();
}
});
function do_the_stuf(){
//do stuff
all_is_done=true;
$("form").submit();
}
$(document).ready(function(){
$('#myform').on('submit',function(event){
// block form submit event
event.preventDefault();


// Do some stuff here
...


// Continue the form submit
event.currentTarget.submit();
});
});

Source