Submit form after calling e.preventDefault()

JavascriptJqueryHtmlForms

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

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

});

Solution 3 - Javascript

Actually this seems to be the correct way:

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

    //prevent default
    e.preventDefault();

    //do something here
   
    //continue submitting
    e.currentTarget.submit();

});

Solution 4 - Javascript

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.

Solution 5 - Javascript

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

});

Solution 6 - Javascript

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;
    }

});

Solution 7 - Javascript

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

Solution 8 - Javascript

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'

Solution 9 - Javascript

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

Solution 10 - Javascript

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>

Solution 11 - Javascript

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWesley MurchView Question on Stackoverflow
Solution 1 - JavascriptnnnnnnView Answer on Stackoverflow
Solution 2 - JavascriptadeneoView Answer on Stackoverflow
Solution 3 - JavascriptMike CottierView Answer on Stackoverflow
Solution 4 - JavascriptOscar PazView Answer on Stackoverflow
Solution 5 - JavascriptfalinskyView Answer on Stackoverflow
Solution 6 - Javascriptd.danailovView Answer on Stackoverflow
Solution 7 - JavascriptAdesanoye SamsonView Answer on Stackoverflow
Solution 8 - JavascripttherealilyaskhanView Answer on Stackoverflow
Solution 9 - JavascriptFankyView Answer on Stackoverflow
Solution 10 - JavascriptNorvert John AbellaView Answer on Stackoverflow
Solution 11 - JavascriptDavid LattyView Answer on Stackoverflow