Tengo una clase de selector de datos (datepicker_nfd) que se adjunta a un campo de entrada que usa maxdate para limitar el widget de fecha solo a las fechas actuales. Tengo un enlace knockoutjs personalizado para mostrar un mensaje de error personalizado y restablecer la fecha en que los usuarios abandonan el campo (al cambiar). Mi problema es que si un usuario ingresa manualmente una fecha en el futuro y presiona Intro, el widget establece la fecha en la fecha actual antes de que se active el cambio y, por lo tanto, no puedo verificar para mostrar el mensaje. Probé el método onseect del selector de fecha y también intenté capturar la pulsación de la tecla "enter" sin éxito. ¿Alguna sugerencia sobre cómo capturar la fecha ingresada manualmente antes de que el widget selector de fecha se restablezca a la fecha actual?
Javascript (código aplicable solo por brevedad)
$(document).ready(function () { $(".datepicker_nfd").datepicker({maxDate: 0}); });Enlace KnockoutJS (código aplicable solo por brevedad)
ko.bindingHandlers.preventFutureDate = { init: function (element, valueAccessor, allBindingsAccessor, vm) { $(element).change(function () { var selectedDate = Date.parse(ko.unwrap(valueAccessor())); var curDate = Date.now(); if (selectedDate > curDate) { var value = valueAccessor(); var eMsg = ($(element).data("emessage") || "Date") + " can not be set to a future date. Defaulting to current day."; value(DateTime.fromMillis(Date.now()).toFormat('MM/dd/yyyy')); showToast("Invalid Date", eMsg.trim(), "exclamation-triangle", "yellow"); } }); } };HTML (código aplicable solo por brevedad)
<div class="form-group col-md-2"> <label for="someDate-datepicker_nfd">Some Date Label</label> <input type="text" class="form-control datepicker_nfd" id="someDate-datepicker_nfd" data-bind="value: model.SomeDate, preventFutureDate: model.SomeDate" data-emessage="Some Date Error Message" /> </div>Entonces, la solución que encontré es que, de hecho, debe usar la tecla presionada, que DEBE ser antes de que se inicialice el selector de fecha ... así que en mi caso, tenía el enlace inicializado en un archivo y el selector de fecha en otro. Esto estaba causando que el keydown no se activara (suponiendo que el selector de fecha evite el valor predeterminado. Por lo tanto, HTML sigue siendo el mismo y el js ahora es el siguiente (el orden es importante).
Javascript/KnockoutJS (código aplicable solo por brevedad)
let keyedDate; ko.bindingHandlers.preventFutureDate = { init: function (element, valueAccessor, allBindingsAccessor, vm) { $(element).keydown(function (e) { if (e.keyCode === 13) { checkForFutureDate(element, valueAccessor, keyedDate); } }); $(element).change(function () { checkForFutureDate(element, valueAccessor, ko.unwrap(valueAccessor())); }); } }; $($(".datepicker_nfd")).keydown(function (e) { if (e.keyCode === 13) { keyedDate = $(this).val(); } }); // NOTE: This needs to be placed after the Knockout Binding Handler for preventFutureDate to capture the keydown event. // The companion selector for $(".datepicker").datepicker(); in in site.js $(".datepicker_nfd").datepicker({maxDate: 0}); function checkForFutureDate(element, valueAccessor, dateToVerify) { var selectedDate = Date.parse(dateToVerify); var curDate = Date.now(); if (selectedDate > curDate) { var value = valueAccessor(); var eMsg = ($(element).data("emessage") || "Date") + " can not be set to a future date. Defaulting to current day."; value(DateTime.fromMillis(Date.now()).toFormat('MM/dd/yyyy')); showToast("Invalid Date", eMsg.trim(), "exclamation-triangle", "yellow"); } };HTML (código aplicable solo por brevedad)
<div class="form-group col-md-2"> <label for="someDate-datepicker_nfd">Some Date Label</label> <input type="text" class="form-control datepicker_nfd" id="someDate-datepicker_nfd" data-bind="value: model.SomeDate, preventFutureDate: model.SomeDate" data-emessage="Some Date Error Message" /> </div>Un poco peculiar, pero hace el trabajo. Noté el let con keyedDate para capturar la fecha antes de que el selector de fecha la cambie fuera del enlace. Que necesitan el enlace para acceder a los otros valores en el enlace HTML.