jQuery验证和屏蔽输入之间的冲突
我有一个表单,对电话号码和美国邮政编码字段使用and 例如,对于美国邮政编码,屏蔽输入只允许输入数字,并强制使用格式“99999”或“99999-9999”(其中9可以是任何数字)。Validate规则需要相同的参数。但在某些情况下,Validate会在字段实际有效时将其标记为无效 代码细节 jQuery Validate在邮政编码字段上使用的正则表达式是jQuery验证和屏蔽输入之间的冲突,jquery,validation,maskedinput,Jquery,Validation,Maskedinput,我有一个表单,对电话号码和美国邮政编码字段使用and 例如,对于美国邮政编码,屏蔽输入只允许输入数字,并强制使用格式“99999”或“99999-9999”(其中9可以是任何数字)。Validate规则需要相同的参数。但在某些情况下,Validate会在字段实际有效时将其标记为无效 代码细节 jQuery Validate在邮政编码字段上使用的正则表达式是^\d{5}$|^\d{5}\-\d{4}$ 我用屏蔽输入应用的屏蔽是.mask('99999?'9999') 复制步骤 当我执行以下操作时,
^\d{5}$|^\d{5}\-\d{4}$
我用屏蔽输入应用的屏蔽是.mask('99999?'9999')
复制步骤
当我执行以下操作时,它们之间会产生冲突:
- 填写无效的邮政编码(例如,三位数)
- 选项卡远离字段。屏蔽输入会删除输入(预期行为),jQuery Validate会将其标记为无效,因为它是空的(也是预期的)
- 返回zip字段并填写有效的5位数的zip
- 选项卡远离字段它仍被标记为无效。这是出乎意料的
- 通过提交表格;单击submit按钮、zip字段通过并提交表单时,所有字段都将重新验证
- 通过设置重新验证特定字段的
事件。例如: $(“#zipcode”).blur(function(){$(this).closest('form').validate().element($(this));})blur
$appDiv.delegate('input,select,textarea','blur',function(){
$(this).closest('form').validate().element($(this));
});
……这也不是:
$('input,select,textarea').live('blur',function(){
$(this).closest('form').validate().element($(this));
});
……但这确实:
$('input,select,textarea').each(function(){
$(this).blur(function(){
$(this).closest('form').validate().element($(this));
});
});
由于这些元素是由AJAX加载的,
。每次加载表单节时都必须运行每个版本。绑定的顺序是否重要?例如,两者之间有区别吗
$(function() {
var $form = $("#myForm"), $zip = $("#zip");
$zip.mask("99999?-9999");
$form.validate();
});
及
我认为绑定应该按顺序启动。我实际上是在寻找这个确切问题的答案。最终找到了一个更可靠的解决方法
因为我正在为zipcode定义自己的验证器方法,所以我修改了它,以便在我从值中删除占位符后,如果zipcode的长度为6,它将删除连字符
看起来是这样的:
$.validator.addMethod("zipcode", function(postalcode, element) {
//removes placeholder from string
postalcode = postalcode.split("_").join("");
//Checks the length of the zipcode now that placeholder characters are removed.
if (postalcode.length === 6) {
//Removes hyphen
postalcode = postalcode.replace("-", "");
}
//validates postalcode.
return this.optional(element) || postalcode.match(/^\d{5}$|^\d{5}\-\d{4}$/);
}, "Please specify a valid zip code");
<input type="text" class="form-control" id="telefone" placeholder="(__) ____-_____" name="telefone" required>
$(document).ready(function() {
var telefone = $('#telefone'), //THAT'S MY INPUT WITH MASK
form = telefone.parents("form"), //THAT'S MY FORM WITH THE VALIDATE
alteredField = false; //THAT'S A FLAG TO SSE IF THE INPUT WAS ALTERED
// APPLY MY MASK
telefone.mask('(99) 9999-9999?9');
// FOCUS ON ANY INPUT
form.find('input[type=text]').focus(function(){
// REMOVE THE VALIDATION STATUS
$(form).data('bootstrapValidator').updateStatus($(this).attr('name'), 'NOT_VALIDATED');
// ENABLE THE SUBMIT BUTTON
$(form).data('bootstrapValidator').disableSubmitButtons(false);
});
// FOCUS ON THE MASKED INPUT
telefone.focus(function(){
// DISABLE THE VALIDATE
$(form).data('bootstrapValidator').enableFieldValidators('telefone', false);
// ENABLE THE SUBMIT BUTTON
$(form).data('bootstrapValidator').disableSubmitButtons(false);
}).blur(function(){ // BLUR ON THE MASKED INPUT
// GET THE INPUT VALUE
var value = telefone.val();
// ENABLE THE VALIDATE
$(form).data('bootstrapValidator').enableFieldValidators('telefone', true);
// CHECK IF THE VALUE IS EMPTY
if(value != ""){
// CHANGE THE STATUS OF THE INPUT TO VALID
$(form).data('bootstrapValidator').updateStatus('telefone', 'VALID')
// ACTIVE THE FLAG
alteredField = true;
}else if (alteredField) { // IF THE INPUT WAS ALTERED BEFORE AND DON'T HAVE VALUE
// CHANGE THE STATUS OF THE INPUT TO INVALID
$(form).data('bootstrapValidator').updateStatus('telefone', 'INVALID')
};
});
});
因此,我正在验证的postalcode将由输入插件添加占位符,如果输入的zipcode只有5个数字(6个包括连字符),则删除连字符。因此,它将正确地验证它。我遇到了一个类似的问题,并设法解决了它,将默认占位符字符更改为空字符串
我使用了一个.mask('9?99')代码>并使用简单的“数字”规则进行验证,并且存在相同类型的冲突
我将掩码声明更改为.mask('9?99',{占位符:'})代码>和。。。不再有冲突。:)
您的情况可能存在问题,因为邮政编码中的-
,它总是由mask插件插入表单中。我认为您可以将regexp更改为^\d{5}-$^\d{5}-\d{4}$
(在两种情况下都与破折号匹配),然后应该进行验证
不管怎么说,您不久前发布过,可能不再需要此功能,但它可能会帮助其他人。:) 我尝试了以下解决方案,效果很好
$(“[数据输入类型=电话],“正文”)
.面具(“(999)999 99”)
.bind(“模糊”,函数(){
//在模糊上强制重新验证。
var frm=$(此).parents(“表格”);
//如果表单有验证器
if($.data(frm[0],“验证器”)){
var validator=$(this.parents(“表单”).validate();
validator.settings.onfocusout.apply(validator[this]);
}
});
触发问题的是事件顺序。
当一个元素被屏蔽时,它由blur
上的maskedinput插件进行验证,但同一元素由focusout
事件(非ie浏览器上的blur包装)上的validator插件进行验证,该事件在maskedinput的blur之前调用
在这种情况下,当验证器检查值时,输入元素的值为”(___________)
。当代码到达maskedinput的blur事件时,插件会测试并清除该值,因为它不是有效的输入
每个验证案例的验证结果可能不同。例如,required
规则将成功通过,因为元素有一个值。非必需的number
字段将失败,即使我们将输入留空,因为像“999”
这样的掩码可能被测试为12
上面的代码测试屏蔽输入的形式是否附加了验证,并调用focusout事件处理程序。由于我们的处理程序是最新的,希望它最终会被调用
警告,代码只是复制验证插件的行为。它可能会工作十年,但如果验证插件决定做与现在不同的事情,它可能会失败
真诚地
//Function to detect if a jQuery elements exists. i.e.:
// var $element = $(selector);
// if($element.exists()) do something...
$.fn.exists = function () {
return this.length !== 0;
}
<input type="text" class="form-control" id="telefone" placeholder="(__) ____-_____" name="telefone" required>
$(document).ready(function() {
var telefone = $('#telefone'), //THAT'S MY INPUT WITH MASK
form = telefone.parents("form"), //THAT'S MY FORM WITH THE VALIDATE
alteredField = false; //THAT'S A FLAG TO SSE IF THE INPUT WAS ALTERED
// APPLY MY MASK
telefone.mask('(99) 9999-9999?9');
// FOCUS ON ANY INPUT
form.find('input[type=text]').focus(function(){
// REMOVE THE VALIDATION STATUS
$(form).data('bootstrapValidator').updateStatus($(this).attr('name'), 'NOT_VALIDATED');
// ENABLE THE SUBMIT BUTTON
$(form).data('bootstrapValidator').disableSubmitButtons(false);
});
// FOCUS ON THE MASKED INPUT
telefone.focus(function(){
// DISABLE THE VALIDATE
$(form).data('bootstrapValidator').enableFieldValidators('telefone', false);
// ENABLE THE SUBMIT BUTTON
$(form).data('bootstrapValidator').disableSubmitButtons(false);
}).blur(function(){ // BLUR ON THE MASKED INPUT
// GET THE INPUT VALUE
var value = telefone.val();
// ENABLE THE VALIDATE
$(form).data('bootstrapValidator').enableFieldValidators('telefone', true);
// CHECK IF THE VALUE IS EMPTY
if(value != ""){
// CHANGE THE STATUS OF THE INPUT TO VALID
$(form).data('bootstrapValidator').updateStatus('telefone', 'VALID')
// ACTIVE THE FLAG
alteredField = true;
}else if (alteredField) { // IF THE INPUT WAS ALTERED BEFORE AND DON'T HAVE VALUE
// CHANGE THE STATUS OF THE INPUT TO INVALID
$(form).data('bootstrapValidator').updateStatus('telefone', 'INVALID')
};
});
});
$.validator.addMethod("zipcode", function(postalcode, element) {
//removes placeholder from string
postalcode = postalcode.replace(/[^0-9]/g, "");
//validates postalcode.
return this.optional(element) || postalcode.match(/^\d{5}$|^\d{5}\-\d{4}$/);
}, "Please specify a valid zip code");
$.validator.addMethod("phone_length", function(phoneno, element) {
//removes all special characters
phoneno= phoneno.replace(/[^0-9]/g, "");
return this.optional(element) || phoneno.match(/^\d{10}$|^\d{10}\-\d{9}$/);
}, "Please enter a valid phone");