使用 jquery-validation 验证 focusout 上的日期字段
Validate date field on focusout with jquery-validation
日期输入字段无效,第一次选择日期时。
它显示所需的错误消息,因为字段具有空值(检查控制台日志)。但字段将在第二次更改时有效。
注意:一个原因是日期输入字段在选择日期(点击事件)时失去焦点。但是日期只会在点击事件发生时才发生变化。但是验证器将验证聚焦事件的字段。
我正在使用 Jquery Validation, using bootstrap-datepicker for Widget 验证表单。
^^为了更好的用户体验 运行 全页代码片段 ;)
要么
jsfiddle
来自@Sparky / @Vignesh ans:是的,这是一个解决方法,我们可以使用change/hide/changeDate(模块属性)事件处理程序。一旦设置了输入值,它就会被触发。
但问题是每当我们从年->月->日期中选择选择器中的每次点击时,都会从输入中移除焦点并触发 focusout 事件并显示错误消息,直到选择日期。
它不像选择字段那样平坦。在选择字段中,在从字段小部件中选择选项之前不会触发 focusout 事件。像这样,我们如何在不看到错误消息的情况下移动 year/month/date 选项?
jQuery: & HTML
$(function() {
$("#editEventForm").validate({
rules: {
full_name: {
required: true,
},
event_date: {
required: true,
},
},
messages: {
full_name: "Please enter your full name!",
event_date: "Please enter valid date!",
},
highlight: function(element, errorClass) {
var e = $(element);
e.closest('.has-feedback').removeClass('has-success').addClass('has-error');
},
unhighlight: function(element, errorClass) {
var e = $(element);
e.closest('.has-feedback').removeClass('has-error').addClass('has-success');
},
onfocusout: function(element) {
console.log("element value --> ", $(element).val());
return $(element).valid();
},
});
$('#eventDate').datepicker({
autoclose: true,
}).on('change', function() {
$(this).valid(); // triggers a validation test
// $(this) refers to $('#eventDate')
});
});
.has-error :focus {
border-color: #f84545 !important;
}
.error {
color: #f84545;
}
<link id="bs-css" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<link id="bsdp-css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js"></script>
<form id="editEventForm">
<div class="form-group">
<div class="has-feedback">
<label for="eventDate">Full Name * </label>
<input class="form-control" id="fullName" name="full_name" type="text">
</div>
<div class="has-feedback">
<label for="eventDate">Event Date * </label>
<input class="form-control" id="eventDate" name="event_date" placeholder="MM/DD/YYYY" type="text">
</div>
</div>
<input type="submit" value="ClickMe">
</form>
您可以在日期选择器中设置首次加载的日期。
$('#eventDate').datepicker({
autoclose: true
}).datepicker("setDate", 'now');
问题不能 closed as duplicate 因为赏金。
jQuery Validate 插件会自动触发对正常表单输入字段的焦点移开和键合的验证测试,并且不能很好地与日期选择器一起使用。
无论何时选择日期,您都必须以编程方式触发验证:
$('#eventDate').datepicker({
autoclose: true,
// endDate: '+45d', // show current date - next 45 days
}).on('change', function() {
$(this).valid(); // triggers a validation test
// $(this) refers to $('#eventDate')
});
TL;DR :点击事件将焦点移动到被点击的元素。因此,在选择器中单击日期时,会从输入中移除焦点并触发 focusout
事件。在设置输入值之前,选择器执行各种操作。因此 focusout
上的值仍然为空。因此警报保留在 UI.
说明:在clicking/focusing date
字段上,datepicker
打开。当您单击 datepicker
中的 date
时,真正的问题出现了。单击后,您可以看到日期字段立即失去焦点(闪烁的插入符号消失)。当我们配置 autoclose:true
时,选择器会立即关闭。下面是datepicker里面写的隐藏功能
hide: function() {
return this.isInline || !this.picker.is(":visible") ? this : (this.focusDate = null,
this.picker.hide().detach(),
this._detachSecondaryEvents(),
this.setViewMode(this.o.startView),
this.o.forceParse && this.inputField.val() && this.setValue(),
this._trigger("hide"),
this)
- 使选择器隐藏。
detach()
使关联的元素被删除,保持元素细节不变,以防再次重新插入元素。
- 从日期选择器中删除附加的次要事件。
- 将视图模式设置为配置的模式(因为在我们的问题中没有配置,它设置为默认模式)。
- 解析选中的值,并将解析结果设置到输入框。
- 运行在选项中配置的自定义回调(如果有)
因此,在输入中设置值之前,onfocusout
事件被触发。由于当时不存在任何值,因此显示错误。
为防止这种情况发生,请在选择器中添加一个 hide
事件处理程序(如下所示),并从那里处理相同的验证。一旦设置了输入值(如上所述),就会触发此自定义事件处理程序。
$(function() {
$("#editEventForm").validate({
rules: {
full_name: {
required: true,
},
event_date: {
required: true,
},
},
messages: {
full_name: "Please enter your full name!",
event_date: "Please enter valid date!",
},
onfocusout: function(element) {
$(element).valid();
},
});
$('#eventDate').datepicker({
autoclose: true,
orientation: "bottom right"
}).on("hide",function(){
$("#editEventForm").data("validator").settings.ignore="";
$(this).valid();
}).on("focus",function(){
$("#editEventForm").data("validator").settings.ignore="#eventDate, :hidden";
});
});
<link id="bs-css" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<link id="bsdp-css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js"></script>
<form id="editEventForm">
<div class="form-group">
<div>
<label for="eventDate">Full Name * </label>
<input class="form-control" id="fullName" name="full_name" type="text">
</div>
<div>
<label for="eventDate">Event Date * </label>
<input class="form-control" id="eventDate" name="event_date" placeholder="MM/DD/YYYY" type="text">
</div>
</div>
<input type="submit" value="ClickMe">
</form>
Edit :如前所述,我们无法阻止 focusout
事件触发。但是这个要求可以通过变通方法来实现。
关注,ignore
验证,hide
,删除忽略的验证并验证。
为了清楚起见,通过
忽略对指定元素的验证
$("#editEventForm").data("validator").settings.ignore="#eventDate, :hidden";`
(:hidden
为默认值,请勿省略)。在验证期间,插件在内部使用 jQuery not
选择器来忽略元素。在隐藏日期选择器时(通过选择 date/clickoutside),从配置中删除该元素并应用验证。
简化@Vignesh 解决方法。
我们可以跳过字段验证 onfocusout
,我们在 hide
事件
上进行验证
// here we can skip the validation
onfocusout: function(element) {
var elementId = element.getAttribute('id');
if (elementId === "eventDate") {
// datepicker widget - don't do validation on focusout event
return false;
}
return $(element).valid();
},
// here we can do the validation
$('#eventDate').datepicker({
autoclose: true,
}).on('hide', function() {
// datepicker - on hide do the field validation
$('#eventDate').valid();
});
日期输入字段无效,第一次选择日期时。
它显示所需的错误消息,因为字段具有空值(检查控制台日志)。但字段将在第二次更改时有效。
注意:一个原因是日期输入字段在选择日期(点击事件)时失去焦点。但是日期只会在点击事件发生时才发生变化。但是验证器将验证聚焦事件的字段。
我正在使用 Jquery Validation, using bootstrap-datepicker for Widget 验证表单。
^^为了更好的用户体验 运行 全页代码片段 ;) 要么 jsfiddle
来自@Sparky / @Vignesh ans:是的,这是一个解决方法,我们可以使用change/hide/changeDate(模块属性)事件处理程序。一旦设置了输入值,它就会被触发。 但问题是每当我们从年->月->日期中选择选择器中的每次点击时,都会从输入中移除焦点并触发 focusout 事件并显示错误消息,直到选择日期。
它不像选择字段那样平坦。在选择字段中,在从字段小部件中选择选项之前不会触发 focusout 事件。像这样,我们如何在不看到错误消息的情况下移动 year/month/date 选项?
jQuery: & HTML
$(function() {
$("#editEventForm").validate({
rules: {
full_name: {
required: true,
},
event_date: {
required: true,
},
},
messages: {
full_name: "Please enter your full name!",
event_date: "Please enter valid date!",
},
highlight: function(element, errorClass) {
var e = $(element);
e.closest('.has-feedback').removeClass('has-success').addClass('has-error');
},
unhighlight: function(element, errorClass) {
var e = $(element);
e.closest('.has-feedback').removeClass('has-error').addClass('has-success');
},
onfocusout: function(element) {
console.log("element value --> ", $(element).val());
return $(element).valid();
},
});
$('#eventDate').datepicker({
autoclose: true,
}).on('change', function() {
$(this).valid(); // triggers a validation test
// $(this) refers to $('#eventDate')
});
});
.has-error :focus {
border-color: #f84545 !important;
}
.error {
color: #f84545;
}
<link id="bs-css" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<link id="bsdp-css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js"></script>
<form id="editEventForm">
<div class="form-group">
<div class="has-feedback">
<label for="eventDate">Full Name * </label>
<input class="form-control" id="fullName" name="full_name" type="text">
</div>
<div class="has-feedback">
<label for="eventDate">Event Date * </label>
<input class="form-control" id="eventDate" name="event_date" placeholder="MM/DD/YYYY" type="text">
</div>
</div>
<input type="submit" value="ClickMe">
</form>
您可以在日期选择器中设置首次加载的日期。
$('#eventDate').datepicker({
autoclose: true
}).datepicker("setDate", 'now');
问题不能 closed as duplicate 因为赏金。
jQuery Validate 插件会自动触发对正常表单输入字段的焦点移开和键合的验证测试,并且不能很好地与日期选择器一起使用。
无论何时选择日期,您都必须以编程方式触发验证:
$('#eventDate').datepicker({
autoclose: true,
// endDate: '+45d', // show current date - next 45 days
}).on('change', function() {
$(this).valid(); // triggers a validation test
// $(this) refers to $('#eventDate')
});
TL;DR :点击事件将焦点移动到被点击的元素。因此,在选择器中单击日期时,会从输入中移除焦点并触发 focusout
事件。在设置输入值之前,选择器执行各种操作。因此 focusout
上的值仍然为空。因此警报保留在 UI.
说明:在clicking/focusing date
字段上,datepicker
打开。当您单击 datepicker
中的 date
时,真正的问题出现了。单击后,您可以看到日期字段立即失去焦点(闪烁的插入符号消失)。当我们配置 autoclose:true
时,选择器会立即关闭。下面是datepicker里面写的隐藏功能
hide: function() {
return this.isInline || !this.picker.is(":visible") ? this : (this.focusDate = null,
this.picker.hide().detach(),
this._detachSecondaryEvents(),
this.setViewMode(this.o.startView),
this.o.forceParse && this.inputField.val() && this.setValue(),
this._trigger("hide"),
this)
- 使选择器隐藏。
detach()
使关联的元素被删除,保持元素细节不变,以防再次重新插入元素。- 从日期选择器中删除附加的次要事件。
- 将视图模式设置为配置的模式(因为在我们的问题中没有配置,它设置为默认模式)。
- 解析选中的值,并将解析结果设置到输入框。
- 运行在选项中配置的自定义回调(如果有)
因此,在输入中设置值之前,onfocusout
事件被触发。由于当时不存在任何值,因此显示错误。
为防止这种情况发生,请在选择器中添加一个 hide
事件处理程序(如下所示),并从那里处理相同的验证。一旦设置了输入值(如上所述),就会触发此自定义事件处理程序。
$(function() {
$("#editEventForm").validate({
rules: {
full_name: {
required: true,
},
event_date: {
required: true,
},
},
messages: {
full_name: "Please enter your full name!",
event_date: "Please enter valid date!",
},
onfocusout: function(element) {
$(element).valid();
},
});
$('#eventDate').datepicker({
autoclose: true,
orientation: "bottom right"
}).on("hide",function(){
$("#editEventForm").data("validator").settings.ignore="";
$(this).valid();
}).on("focus",function(){
$("#editEventForm").data("validator").settings.ignore="#eventDate, :hidden";
});
});
<link id="bs-css" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<link id="bsdp-css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js"></script>
<form id="editEventForm">
<div class="form-group">
<div>
<label for="eventDate">Full Name * </label>
<input class="form-control" id="fullName" name="full_name" type="text">
</div>
<div>
<label for="eventDate">Event Date * </label>
<input class="form-control" id="eventDate" name="event_date" placeholder="MM/DD/YYYY" type="text">
</div>
</div>
<input type="submit" value="ClickMe">
</form>
Edit :如前所述,我们无法阻止 focusout
事件触发。但是这个要求可以通过变通方法来实现。
关注,ignore
验证,hide
,删除忽略的验证并验证。
为了清楚起见,通过
忽略对指定元素的验证$("#editEventForm").data("validator").settings.ignore="#eventDate, :hidden";`
(:hidden
为默认值,请勿省略)。在验证期间,插件在内部使用 jQuery not
选择器来忽略元素。在隐藏日期选择器时(通过选择 date/clickoutside),从配置中删除该元素并应用验证。
简化@Vignesh 解决方法。
我们可以跳过字段验证 onfocusout
,我们在 hide
事件
// here we can skip the validation
onfocusout: function(element) {
var elementId = element.getAttribute('id');
if (elementId === "eventDate") {
// datepicker widget - don't do validation on focusout event
return false;
}
return $(element).valid();
},
// here we can do the validation
$('#eventDate').datepicker({
autoclose: true,
}).on('hide', function() {
// datepicker - on hide do the field validation
$('#eventDate').valid();
});