Submit form after calling e.preventDefault()

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:

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();

});

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.


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().


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();

});

Actually this seems to be the correct way:

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

    //prevent default
    e.preventDefault();

    //do something here

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

});

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.


$('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;

});