Я использую плагин проверки JQuery Jörn Zaefferer рядом с jQuery UI datepicker. Я создал набор настраиваемых правил для проверки того, что дата начала до даты окончания.Проверка диапазона дат с помощью jQuery UI datepicker: порядок событий
Проблема заключается в том, что когда у меня есть недопустимый диапазон и используйте пользовательский интерфейс datepicker для изменения даты, чтобы сделать допустимый диапазон действительным, я вижу, что проверка выполняется со старыми значениями (и, таким образом, недействительными полями) до активировать обратный вызов onSelect для datepicker.
Я ожидал бы, что датапикер обновит значение ввода при выборе пользователем и что любой код проверки будет работать, когда это произойдет, и увидит новое значение. Но это, похоже, не происходит.
Я попытался инициализировать datepicker перед инициализацией проверки в надежде на то, что порядок, в котором были связаны события, изменит ситуацию, но вы можете видеть, что это не помогло.
Чтобы воспроизвести проблему, введите 15-го числа данного месяца в начале, а 7-го того же месяца, в конце концов. Нажмите поле «Пуск», а затем нажмите или вкладку, чтобы активировать проверку. Поля корректно недействительны. Теперь щелкните поле «Пуск» и выберите 1-е число того же месяца. Обратите внимание на то, что выводится в этот момент на консоли.
Код для ссылки:
HTML
<form id="daterange-form">
<div class="form-group">
<label for="startDate">Start Date</label>
<input type="text" id="startDate" name="startDate" class="validDate form-control" />
</div>
<div class="form-group">
<label for="endDate">End Date</label>
<input type="text" id="endDate" name="endDate" class="validDate form-control" />
</div>
<button type="submit" class="btn">Submit</button>
</form>
JavaScript
// Custom Rules
$.validator.addMethod('dateBefore', function(value, element, params) {
// if end date is valid, validate it as well
console.log('dateBefore', value, element, params)
var end = $(params);
if (!end.data('validation.running')) {
$(element).data('validation.running', true);
// The validator internally keeps track of which element is being validated currently. This ensures that validating 'end' will not trample 'start'
// see http://stackoverflow.com/questions/22107742/jquery-validation-date-range-issue
setTimeout($.proxy(
function() {
this.element(end);
}, this), 0);
// Ensure clearing the 'flag' happens after the validation of 'end' to prevent endless looping
setTimeout(function(){
$(element).data('validation.running', false);
}, 0);
}
return this.optional(element) || this.optional(end[0]) || new Date(value) < new Date(end.val());
}, 'Must be before its end date');
$.validator.addMethod('dateAfter', function(value, element, params) {
// if start date is valid, validate it as well
console.log('dateAfter', value, element, params)
var start = $(params);
if (!start.data('validation.running')) {
$(element).data('validation.running', true);
// The validator internally keeps track of which element is being validated currently. This ensures that validating 'end' will not trample 'start'
// see http://stackoverflow.com/questions/22107742/jquery-validation-date-range-issue
setTimeout($.proxy(
function() {
this.element(start);
}, this), 0);
// Ensure clearing the 'flag' happens after the validation of 'end' to prevent endless looping
setTimeout(function() {
$(element).data('validation.running', false);
}, 0);
}
return this.optional(element) || this.optional(start[0]) || new Date(value) > new Date($(params).val());
}, 'Must be after its start date');
// Code setting up datepicker and validation
$('#startDate, #endDate').datepicker({
onSelect: function(dateText, inst) {
console.log('onSelect', dateText, inst)
}
});
$('#daterange-form').validate({
debug: true,
rules: {
startDate: {dateBefore: '#endDate'},
endDate: {dateAfter: '#startDate'}
}
});
Боковая примечание: таймауты и прокси-вызовы в правила, потому что эта версия библиотека внутренне предполагает последовательную проверку. Если вы попытаетесь проверить другое поле в середине правила, произойдет Bad Things. Код семафора validation.running
предназначен для предотвращения бесконечного цикла.
Я хотел бы отметить, что в нашем коде, мы в настоящее время используют этот фокус-то размытости обходной путь http://stackoverflow.com/ а/19838943/749227. В основном мне любопытно, почему датпикер, похоже, вызывает какое-либо событие, которое требуется для проверки, до фактического обновления значения, и как обойти его, не задумываясь о том, чтобы скопировать-вставить одно и то же обходное решение каждый раз, когда у нас есть допустимый диапазон дат. – jinglesthula