延迟验证,直到用户选择输入组中的所有输入

Posted

技术标签:

【中文标题】延迟验证,直到用户选择输入组中的所有输入【英文标题】:Delay validation until user tabs out of all inputs in an input group 【发布时间】:2020-11-07 07:21:44 【问题描述】:

我的表单有一组三个复选框。用户必须至少选择三个选项之一:

<form id="myform" class="validated-form" novalidate="novalidate">
  <div id="fname" class="btn-group btn-group-toggle" data-toggle="buttons">
    <label>
      a
      <input type="checkbox" value="a" name="fname"/>
    </label>
    <label>
      b
      <input type="checkbox" value="b" name="fname"/>
    </label>
    <label>
      c
      <input type="checkbox" value="c" name="fname"/>
    </label>  
  </div>
</form>

我正在使用以下onfocusout 回调来验证复选框组:

onfocusout: function(element) 
  
  if($(element).prop('type') == 'checkbox') 
        this.element(element);
      

  

见JSFiddle。


问题:当用户选择选项卡时,我希望验证器等到他们完全退出组(即当所有三个复选框都失去焦点时)验证它。


我的第一次尝试是修改上述回调中的 if 语句,使其包含一个条件,该条件选择组内所有具有焦点的元素,然后检查结果对象数组的长度是否为 0,如下所示:

onfocusout: function(element) 
  
   if($(element).prop('type') == 'checkbox' && $(element).closest('.btn-group').find('label:focus').length == 0) 
        this.element(element);
      
  

但是由于一个元素失去焦点和另一个元素接收焦点之间存在延迟,因此上述方法不起作用。我认为这是由于一旦被验证的输入失去焦点并且 before 新元素获得焦点,回调就会触发。此时,没有元素处于焦点位置,因此 if 语句条件始终计算为 true。出于同样的原因,我无法检测到焦点已转移到哪个元素(因此我无法检查新获得焦点的元素是否是复选框组的一部分)。

所以我的下一个尝试是使用setTimeout

onfocusout: function(element) 
  
  setTimeout(function() 
    if($(element).prop('type') == 'checkbox' && $(element).closest('.btn-group').find('label:focus').length == 0) 
        this.element(element);
      
  , 1);
  

这似乎完全关闭了验证 - 从一个复选框切换到另一个不会触发验证,但也不会完全退出复选框组。我用错了吗? (在Fiddle中,好像没有效果。)

这个问题有更好的解决方案还是我试图解决错误的问题?

注意:我不能使用onclick 回调,因为它与我在实际表单中使用的小部件不兼容。无论如何,我更喜欢 onfocusout 的感觉而不是 onclick,因为它更符合 Validate 插件的默认行为。

【问题讨论】:

【参考方案1】:

我使用event.relatedTarget 来识别哪个元素获得了焦点并修改了if 语句以仅在relatedTarget 的名称与失去焦点的复选框的名称不匹配时触发验证:

onfocusout: function(element, event) 
  
    if($(element).prop('type') == 'checkbox' && $(event.relatedTarget).attr('name') != $(element).attr('name')) 
          $(element).valid();
        
    
  

见JSFiddle。

不确定这种方法是否有任何警告,并希望将帖子保持打开状态,以防有人有更好的解决方案。

【讨论】:

以上是关于延迟验证,直到用户选择输入组中的所有输入的主要内容,如果未能解决你的问题,请参考以下文章

wifi peer-2-peer组中的自动身份验证(wifi直接)

在组中的所有单元格中放置小计值

如何循环列表,直到列表中的所有项目都与用户输入匹配,然后在 python 中使用 Bingo 消息停止循环

Javascript 验证下拉菜单和文本输入

html 只选择一个组中的一个复选框

微服务中的输入验证取决于来自其他服务的数据