调用e.preventDefault()后提交表单


68

我在这里进行一些简单的表单验证,并且陷入了一个非常基本的问题。我有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();

...但是我不确定我需要做什么。


为什么取消绑定您的提交表单?
d.danailov 2014年

我已经看到了这个职位,但解决方案看起来是可疑和使用setTimeoutstackoverflow.com/questions/14866626/...
韦斯利默奇

@ d.danailov因此,它不会再次运行验证。请帮帮我-我该怎么办?
Wesley Murch 2014年

1
您为什么不更改它,以便e.preventDefault()仅在验证失败时才调用?然后,您可以使用删除该行.unbind().submit()
nnnnnn 2014年

1
好的,其他人也可以,但是这里也有想法jsfiddle.net/eecTN/9谢谢您的耐心
Stormdrain,2014年

Answers:


90

最简单的解决方案是不进行调用,e.preventDefault()除非验证实际上失败了。将那行移动到内部if语句中,然后使用删除函数的最后一行.unbind().submit()


16
由于某些原因,我认为我需要先打电话给e.preventDefault()其他人,否则会冒某种比赛状况的风险。感谢您的启发。
Wesley Murch 2014年

2
不,整个功能将在默认操作继续执行之前完成(或者如果您取消了该操作,则不会继续执行)。如果您知道自己从未想要过特定事件的默认操作,则可以将其作为显而易见的第一行(例如,如果您希望通过Ajax而不是表单提交或单击提交数据)触发JS而不是执行标准导航的链接上的处理程序)。否则,将其置于条件逻辑中就可以了。
nnnnnn 2014年

过去,我对某些受大量Ajax驱动的网站的竞争状况感到乐观,因此竞争状况一直是一个问题,因此第一行始终是e.preventDefault()。您是否100%确定执行建议的操作是安全的?
JamesNZ 2014年

1
@JamesNZ-我很肯定它是安全的。在很大程度上基于Ajax的网站的竞争条件可能是一个问题,如果有多个AJAX请求作出响应回来之前,因为没有保证的响应将在任何特定的顺序回来-但即使如此,你仍然不需要e.preventDefault()为第一行,因为当前的同步代码块在触发任何Ajax回调之前完成。也就是说,JS不会中断当前正在运行的函数来调用Ajax回调-或第二个事件处理程序或超时回调或任何其他函数。
nnnnnn 2014年

@nnnnnn好的。我会仔细检查下一个项目,但是如果这不是问题,那太好了。感谢您的回复。
JamesNZ 2014年

40

使用本机element.submit()绕过jQuery处理程序中的preventDefault,请注意,您的return语句仅从each循环返回,而不从事件处理程序返回

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

});

谢啦!这应该是公认的答案👍
萨米特·乔希

24

实际上,这似乎是正确的方法:

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

    //prevent default
    e.preventDefault();

    //do something here

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

});

15

问题是,即使看到错误,也会return false影响.each()方法的回调...因此,即使出现错误,也可以到达该行

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

并提交表格。

validated例如,您应该创建一个变量,并将其设置为true。然后,在回调中,而不是return falseset validated = false

最后...

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

这样,只有在没有错误的情况下才会提交表格。


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

});

2

抱歉延迟,但我会尽力制作出完美的表格:)

我将添加“计数”验证步骤,并且每次都不检查.val()。检查.length,因为我认为您的情况更好。当然删除unbind功能。

我的jsFiddle

当然是源代码:

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

});

1

遇到了相同的问题,在论坛等上找不到直接的解决方案。最后,以下解决方案对我来说是完美的:只需在事件处理程序函数中以“提交”事件的形式实现以下逻辑即可:

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

就那么简单; 注意:当表单'submit'事件的处理程序返回'false'时,表单不会提交到html标记的action属性中指定的URI;直到且除非处理程序返回“ true”;一旦所有输入字段都经过验证,事件处理程序将返回“ true”,并将提交您的表格;

还应注意:if()条件内的函数调用基本上是您自己的实现,以确保所有字段都经过验证,因此必须从那里返回“ true”,否则返回“ false”


0

为什么不将提交按钮事件与表单本身绑定在一起?如果绑定按钮比表单本身更容易和安全得多,因为除非您使用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>


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.