Reputation: 102735
I'm doing some simple form validation here and got stuck on a very basic issue. I have 5 field pairs for name and entree (for a dinner registration). The user can enter 1-5 pairs, but an entree must be selected if a name is present. Code:
<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();
});
The error message is working, but it's submitting the form every time. I know there's something wrong with this line:
$('form').unbind('submit').submit();
...but I'm not sure what I need to do.
Upvotes: 102
Views: 192486
Reputation: 435
$(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();
});
});
Upvotes: 3
Reputation: 1786
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();
}
Upvotes: 0
Reputation: 87
Binding to the button would not resolve for submissions outside of pressing the button e.g. pressing enter
Upvotes: -1
Reputation: 36
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'
Upvotes: 1
Reputation: 769
Actually this seems to be the correct way:
$('form').submit(function(e){
//prevent default
e.preventDefault();
//do something here
//continue submitting
e.currentTarget.submit();
});
Upvotes: 66
Reputation: 250
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>
Upvotes: -1
Reputation: 9800
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.
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;
}
});
Upvotes: 2
Reputation: 150020
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()
.
Upvotes: 119
Reputation: 18292
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.
Upvotes: 15
Reputation: 7428
$('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;
});
Upvotes: 6
Reputation: 318182
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();
});
Upvotes: 49