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">

https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js



<form id="editEventForm">



Full Name *



Event Date *


</div>
<input type="submit" value="ClickMe">
</form>





Duplicate of this: stackoverflow.com/q/22335120/594235
– Sparky
Jul 2 at 16:12





@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">

https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js



<form id="editEventForm">



Full Name *



Event Date *


</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.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

How to set up datasource with Spring for HikariCP?

Display dokan vendor name on Woocommerce single product pages