Validate date field on focusout with jquery-validation
Validate date field on focusout with jquery-validation
Date Input Field not valid, When first time selecting the date.
Its showing required error message, because of field have an empty value(check console log). But field will be valid on second change.
Notes: A cause is that date input field loses focus when picking the date (click event). But the date populates only later changed when the click event happens. But validator will validate field on focus out event.
I'm validating a form using Jquery Validation, using bootstrap-datepicker for Widget.
^^for Better UX Run code snippet on full-page ;)
or
jsfiddle
from @Sparky / @Vignesh ans: Yes, its a workaround for this, We can use change/hide/changeDate(module attribute) event handler. It gets triggered once the input values have been set.
But the problem is whenever we pick from year->month->date each clicks in the picker, removes focus from input and focusout event fired and showing the error message until choosing the date.
It's not flat like choice field. in choice field there is no focusout event triggered until choosing the option from field widget. Like this, How can we move around the year/month/date options without seeing error message?.
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>
@Sparky Yes, already I have gone through. But how can we move around year/month/date options without triggering the error message?
– ramganesh
Jul 3 at 12:06
@ramganesh Updated my answer. Pls have a look at it.
– Vignesh Raja
Jul 6 at 5:38
4 Answers
4
TL;DR : Click event moves the focus to the clicked element. Hence on clicking the date in the picker, removes focus from input and focusout
event fired. Before setting the input value, the picker performs various operations. Hence value remains empty on focusout
. Hence the alert remains in the UI.
focusout
focusout
Explanation : On clicking/focusing the date
field, datepicker
opens. The real problem occurs when you click on the date
in the datepicker
. Once it is clicked you can see the date field looses the focus (the blinking caret disappears) immediately. The picker closes immediately as we configured autoclose:true
. The following is the hide functionality written inside the datepicker.
date
datepicker
date
datepicker
autoclose:true
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()
So before setting the value in the input the onfocusout
event gets fired. And as there is no value present at that time, the error is shown.
onfocusout
To prevent this from happening, add a hide
event handler in the picker (as below), and handle the same validation from there. This custom event handler gets triggered once the input values has been set (as explained above).
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 : As already told, we cannot prevent focusout
event from firing. But the requirement can be achieved with a workaround.
focusout
On focus, ignore
the validation and on hide
, remove the ignored validation and validate.
ignore
hide
To be clear, ignore the validation for the specified element via
$("#editEventForm").data("validator").settings.ignore="#eventDate, :hidden";`
(:hidden
is the default value, so don't omit it). During validation, the plugin internally uses the jQuery not
selector to ignore elements. On hiding the datepicker (either by selecting date/clickoutside), remove the element from the config and apply validation.
:hidden
not
@ramganesh Updated the answer. Hope it helps.
– Vignesh Raja
Jul 5 at 19:26
:) yes Its working fine as expected, and I just simplifying your's stuff. see my ans.
– ramganesh
2 days ago
Question can not be closed as duplicate because of bounty.
The jQuery Validate plugin automatically triggers a validation test on focus out and key up of normal form input fields, and do not work well with the date picker.
You'll have to programmatically trigger validation whenever you pick a date:
$('#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')
});
Simplifying the @Vignesh workaround.
We can skip the field validation onfocusout
, and we do the validaion on hide
event
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();
});
Jsfiddle
Yeah.. it can be done like that too.... But I wanted to expose the method that does the same internally, should be known to you and whomever it may help.
– Vignesh Raja
2 days ago
accepted :) @vignesh
– ramganesh
2 days ago
You can set a date at first load in the date picker.
$('#eventDate').datepicker({
autoclose: true
}).datepicker("setDate", 'now');
it's for Set today's date as default date.
– ramganesh
Jun 30 at 14:08
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Duplicate of this: stackoverflow.com/q/22335120/594235
– Sparky
Jul 2 at 16:12