2014-03-12 50 views
34

我正在做一些简单的表单验证,并陷入了一个非常基本的问题。我有5个字段对名称和主菜(用于晚餐注册)。用户可以输入1-5对,但如果存在名称,则必须选择主菜单。代码:在调用e.preventDefault()后提交表单

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

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

+0

为什么你让拆散你的提交表单??? –

+0

我见过这篇文章,但解决方案看起来可疑,并使用'setTimeout':http://stackoverflow.com/questions/14866626/submitting-form-after-using-e-preventdefault?rq=1 –

+0

@ d.danailov所以它不会再次运行验证。请帮助我 - 我需要做什么? –

回答

51

最简单的解决方案是而不是请致电e.preventDefault(),除非验证实际上失败。在内部if语句内移动该行,并使用.unbind().submit()删除该函数的最后一行。

+8

出于某种原因,我认为我需要在任何其他事情之前调用'e.preventDefault()'或冒险某种竞争条件。感谢启发。 –

+2

不,整个功能将在默认操作继续之前完成(或者如果您已取消它,则不会继续)。如果你知道你从来不想要某个特定事件的默认行为,那么将它作为第一行显而易见(例如,如果你想通过Ajax提交数据而不是通过表单提交,或点击处理器在一个链接上触发JS而不是做标准导航)。否则,把它放在条件逻辑中是没问题的。 – nnnnnn

+0

我在过去积极ajax驱动的网站竞争条件是一个问题,所以第一行总是e.preventDefault()。你是否100%确定你的建议是安全的? – JamesNZ

18

使用本地element.submit()规避的preventDefault在jQuery的处理程序,并注意您的return语句只是从每个环路返回,它不会从事件处理程序

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

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

}); 
11

问题返回是的,即使你看到错误,你return false影响.each()方法的回调......所以,即使有错误,你到达行

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

并提交表单。

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

最后...

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

这样一来,只有当没有将形式提交错误。

2

对不起拖延,但我会努力让完美的形式:)

我会加计数验证步骤,检查每一次不.val()。检查.length,因为我认为你的情况是更好的模式。当然删除unbind功能。

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

});