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.
This question is related to
javascript
jquery
html
forms
$('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;
});
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;
}
});
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();
});
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();
}
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) {_x000D_
var submitAllow = true;_x000D_
$('[name="atendeename[]"]', this).each(function(index, el){_x000D_
// If there is a value_x000D_
if ($(el).val()) {_x000D_
// Find adjacent entree input_x000D_
var entree = $(el).next('input');_x000D_
_x000D_
// If entree is empty, don't submit form_x000D_
if ( ! entree.val()) {_x000D_
alert('Please select an entree');_x000D_
entree.focus();_x000D_
submitAllow = false;_x000D_
return false;_x000D_
}_x000D_
}_x000D_
});_x000D_
if (submitAllow) {_x000D_
$("#form-attendee").submit();_x000D_
}_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<form id="form-attendee">_x000D_
Name: <input name="atendeename[]">_x000D_
Entree: <input name="entree[]"><br>_x000D_
Name: <input name="atendeename[]">_x000D_
Entree: <input name="entree[]"><br>_x000D_
Name: <input name="atendeename[]">_x000D_
Entree: <input name="entree[]"><br>_x000D_
Name: <input name="atendeename[]">_x000D_
Entree: <input name="entree[]"><br>_x000D_
Name: <input name="atendeename[]">_x000D_
Entree: <input name="entree[]"><br>_x000D_
<button type="button" id="btn-submit">Submit<button>_x000D_
</form>
_x000D_
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.
Actually this seems to be the correct way:
$('form').submit(function(e){
//prevent default
e.preventDefault();
//do something here
//continue submitting
e.currentTarget.submit();
});
Source: Stackoverflow.com