I have a form with an input field for dates. The dates should be validated: only dates from today + maximum 3 years are allowed. If the date is valid, a modal will show, else there will be an alert with an error message.
Assuming somone changes the date to 26.10.2099:
Everything works as expected, if one leaves the input field (by clicking somewhere else with the mouse):
BUT if one presses Enter instead of just leaving the input field, the following happens:
My thought is that changing the date back to its initial value causees the onchange event to be triggered again, and then the date is valid and the modal will show. But this is not the case for the first scenario. In the second scenario the event triggers twice SOMETIMES but not always.
You can tryout yourself here: https://jsfiddle.net/6x9n53fx/3/
Or read the code below:
HTML:
<div class="container">
<form method="post" action="" enctype="multipart/form-data">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="review_date">Valid until *</label>
<input id="review_date" type="text" name="review_date" value="26.10.2016" class="form-control">
<p>Please set a validation date. (max 3 years)</p>
</div>
</div>
</div>
</form>
</div>
<!-- Modal -->
<div class="modal fade" id="info_modal" tabindex="-1" role="dialog" aria-labelledby="modal_title">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="modal_title">Dialog</h4>
</div>
<div class="modal-body">
<div class="form-group mbn">
<p class="mb10">Date successfully changed.</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
Javascript:
var datumfeld = $("#review_date");
var initialdatum = datumfeld.val();
var i = 0;
datumfeld.datepicker({
minDate: 0,
maxDate: "3y",
dateFormat: 'dd.mm.yy'
});
datumfeld.change(function() {
i++;
console.log('onchange triggered: ' + i);
if (validateDatum()) {
$("#info_modal").modal({
backdrop: "static",
keyboard: false
});
}
});
function validateDatum() {
var dateParts = datumfeld.val().split(".");
var review_date = new Date(dateParts[2], (dateParts[1] - 1), (parseInt(dateParts[0]) + 1));
if (((new Date(review_date - (new Date()))).getFullYear() - 1970) > 2) {
alert("Error: The date must not exceed 3 years from now.");
datumfeld.val(initialdatum);
return false;
}
if ((review_date - (new Date)) < 0) {
alert("Error: The date must not be in the past.");
datumfeld.val(initialdatum);
return false;
}
return true;
}
EDIT:
Here is the final solution I went with:
datumfeld.on('keydown', function(e) {
// when keydown is ENTER (13)
if (e.keyCode == 13) {
// Hide the datepicker
$(this).datepicker('hide');
// Trigger a change event to trigger the validation
$(this).trigger('change');
}
})
The problem from your code is when you press Enter your value != when you click else where. You can see it when you debug dateParts
When you enter example: 28.10.2099 and click away dateParts
is ["28", "10", "2099"]
But when enter example: 28.10.2099 and press ENTER dateParts
is ["28", "10", "2019"] Here datepicker is validate the input field and set automaticly date to 28.10.2019 because you set maxDate
to 3y
.
So my solution is to bind keydown
and bypass datepicker before it change the value automaticly.
Here is a link with working code: https://jsfiddle.net/95qbs86x/2/
Update: added code
var datumfeld = $("#review_date");
var initialdatum = datumfeld.val();
var i = 0;
// bind keydown event
datumfeld.on('keydown', function(e) {
// when keydown is ENTER (13)
if (e.keyCode == 13) {
// trigger tab to hide datepicker
var e = $.Event("keydown");
e.which = 9; //tab
e.keyCode = 9;
e.key = 'Tab';
$(this).trigger(e);
return false;
}
}).datepicker({
minDate: 0,
maxDate: "3y",
dateFormat: 'dd.mm.yy',
onClose: function(){
this.blur();
}
}).on('change', function(e) {
i++;
console.log('onchange triggered: ' + i);
if (validateDatum()) {
$("#info_modal").modal({
backdrop: "static",
keyboard: false
});
}
});
function validateDatum() {
var dateParts = datumfeld.val().split(".");
console.log(dateParts);
var review_date = new Date(dateParts[2], (dateParts[1] - 1), (parseInt(dateParts[0]) + 1));
if (((new Date(review_date - (new Date()))).getFullYear() - 1970) > 2) {
alert("Error: The date must not exceed 3 years from now.");
datumfeld.val(initialdatum);
return false;
}
if ((review_date - (new Date)) < 0) {
alert("Error: The date must not be in the past.");
datumfeld.val(initialdatum);
return false;
}
return true;
}
Notice: Some code could be remove like: e.which = 9;
e.key = 'Tab';
return false;
However to applying the same effect as click away, this line of code should be added:
onClose: function(){
this.blur();
}
Some code was taken from this answere: Disable enter key in JQuery ui datepicker
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With