延迟验证,直到用户选择输入组中的所有输入
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直接)