在 jquery 日期选择器重置为当前日期之前捕获手动输入的日期,同时限制最大日期

Capturing manually entered date before jquery datapicker resets to current date while restricting with Maxdate

我有一个附加到输入字段的数据选择器 class (datepicker_nfd),该输入字段使用 maxdate 将日期小部件限制为仅当前日期。我有一个自定义 knockoutjs 绑定来显示自定义错误消息并在用户离开该字段 (onchange) 时重置日期。我的问题是,如果用户手动输入将来的日期并按回车键,则小部件会在触发 onchange 之前将日期设置为当前日期,因此我无法检查以显示消息。我尝试了日期选择器的 onseect 方法,也尝试捕获“输入”按键无济于事。关于如何在日期选择器小部件重置为当前日期之前捕获手动输入的日期的任何建议?

Javascript(适用代码仅为简洁起见)

$(document).ready(function () {
     $(".datepicker_nfd").datepicker({maxDate: 0}); 
});

KnockoutJS 绑定(适用代码仅为简洁起见)

    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(适用代码仅为简洁起见)

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

所以我找到的解决方案是你确实必须使用按键按下,这必须在日期选择器初始化之前......所以在我的情况下,我将绑定初始化为一个文件和另一个日期选择器。这导致 keydown 不触发(假设日期选择器防止默认。所以 HTML 保持不变,js 现在如下(顺序很重要)。

Javascript/KnockoutJS(适用代码仅为简洁起见)

    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(适用代码仅为简洁起见)

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

有点古怪,但可以完成工作。注意到 let with keyedDate 在日期选择器在绑定之外更改它之前捕获日期。需要绑定才能访问 HTML 绑定中的其他值。