jQuery UI 具有手动输入和动态最小日期的日期选择器
jQuery UI datepicker with manual entry and dynamic min-date
我的页面上有几个日期选择器,可以通过选择器或手动输入来填充。有一些规则适用于这些日期选择器,但我不知道如何动态解决这个问题。
问题 1
日期 2 不应早于日期 1。日期 3 不应早于日期 1 和 2。
这目前适用于日期选择器,但不适用于手动输入。如果日期是手动输入的并且早于最小日期,则该字段应留空。
问题 2
如果第一个日期发生变化(像以前一样更早的日期),第二个日期的最小日期也应该更新。
这同样适用于第三个日期选择器。
该页面上可以有 1-x 个日期选择器!
let d = new Date();
let nextValidDate = d.getDate() + "." + (d.getMonth() + 1) + "." + d.getFullYear();
$(document).on("blur change", ".datepicker", function () {
nextValidDate = $(this).datepicker("getDate");
});
$(document).on('focus', '.datepicker',
function () {
$(this).datepicker({
numberOfMonths: 1,
firstDay: 1,
changeMonth: true,
changeYear: true,
dateFormat: 'dd.mm.yy',
minDate: nextValidDate
});
$(this).datepicker('show');
});
$(document).on('blur', '.datepicker', function () {
if ($(this).val().length >= 2) {
parseInputDate(this);
}
});
function parseInputDate(elm) {
var currDate = new Date(),
monDt = (('0' + currDate.getMonth() + 1).slice(-2) + ('0' + currDate.getDate()).slice(-2)), // get current month+date to compare
inputVal = $(elm).val().match(/\d{2}/gi); // split date components into array of [dd,mm,yy,yy]
// another date validation, by comparing parameters and date object result
var isValidDate = function (yyyy, mm, dd) {
var dt = new Date(yyyy, parseInt(mm, 10) - 1, dd);
return (dt.getFullYear() + '-' + ('0' + (dt.getMonth() + 1)).slice(-2) + '-' + ('0' + dt.getDate()).slice(-2)) == yyyy + '-' + mm + '-' + dd;
}
if (inputVal != null && inputVal.length >= 2) {
var year = currDate.getFullYear();
if (monDt > (inputVal[1] + inputVal[0])) year++;
// generate formatted text based on date component count
// add date validation to catch invalid dates using (new Date('yyyy-mm-dd')).getTime() which will return NaN on invalid date
var result = (inputVal.length == 2 && isValidDate(year, inputVal[1], inputVal[0]) && inputVal[0] + '.' + inputVal[1] + '.' + year) ||
(inputVal.length == 3 && isValidDate('20' + inputVal[2], inputVal[1], inputVal[0]) && inputVal[0] + '.' + inputVal[1] + '.20' + inputVal[2]) ||
(inputVal.length == 4 && isValidDate(inputVal[2] + inputVal[3], inputVal[1], inputVal[0]) && inputVal[0] + '.' + inputVal[1] + '.' + inputVal[2] + inputVal[3]) ||
''; // set empty on invalid dates
$(elm).val(result);
nextValidDate = result;
} else {
$(elm).val('')
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<div>
<label for="date1">Date 1:</label>
<input type="text" class="datepicker" id="date1">
</div>
<div>
<label for="date2">Date 2:</label>
<input type="text" class="datepicker" id="date2">
</div>
<div>
<label for="date3">Date 3:</label>
<input type="text" class="datepicker" id="date3">
</div>
考虑这个例子:http://jqueryui.com/datepicker/#date-range
我们可以像这样设置您的代码:
$(function() {
var dateFormat = 'dd.mm.yy';
function getDate(el) {
var date;
try {
date = $.datepicker.parseDate(dateFormat, el.value);
} catch (error) {
date = null;
}
return date;
}
function checkMinDate(el) {
var date = getDate(el);
var minDate = $(el).datepicker("option", "minDate");
var test;
try {
test = (date >= minDate);
} catch (error) {
test = false;
}
return test;
}
$(".datepicker").datepicker({
numberOfMonths: 1,
firstDay: 1,
changeMonth: true,
changeYear: true,
dateFormat: dateFormat,
minDate: 0
}).on("change", function(e) {
e.preventDefault();
var td = getDate(this);
var dpid = $(this).attr("id");
var dpi = parseInt(dpid.slice(dpid.indexOf("-") + 1));
$("#date-" + (dpi + 1)).prop("disabled", false).datepicker("option", {
minDate: td,
defaultDate: td
});
if (!checkMinDate(this)) {
this.value = "";
return false;
}
return true;
});
$(".datepicker:not(:eq(0))").prop("disabled", true);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<div class="date-wrapper">
<div>
<label for="date1">Date 1:</label>
<input type="text" class="datepicker" id="date-1">
</div>
<div>
<label for="date2">Date 2:</label>
<input type="text" class="datepicker" id="date-2">
</div>
<div>
<label for="date3">Date 3:</label>
<input type="text" class="datepicker" id="date-3">
</div>
<div>
<label for="date3">Date 4:</label>
<input type="text" class="datepicker" id="date-4">
</div>
<div>
<label for="date3">Date 5:</label>
<input type="text" class="datepicker" id="date-5">
</div>
</div>
我认为这符合您的标准:
- 以前的日期字段应小于或 "before" 当前日期字段。
- 所有以前的日期都应小于此日期字段。
- 如果日期发生变化,则后续日期的最小日期也应更新。
函数 getDate()
接收一个元素并检测它是否包含字符串格式的日期(基于日期格式)和 return 等于该日期的日期对象或 null
.
函数checkMinDate()
是帮我们检测一个手动输入的日期。它根据 minDate 值检查手动输入的日期。如果它大于或等于 minDate
,它将 return 为真。如果小于 minDate
它将 return false.
在我们的 change
回调中,我们使用 .preventDefault()
来停止当前操作。这对于我们想要测试输入内容的类型事件很有帮助。我们稍后可以 return true
或 false
让事件继续进行。如果 checkMinDate
不是 true,我们可以清除值和 return false。
希望对您有所帮助!
我的页面上有几个日期选择器,可以通过选择器或手动输入来填充。有一些规则适用于这些日期选择器,但我不知道如何动态解决这个问题。
问题 1
日期 2 不应早于日期 1。日期 3 不应早于日期 1 和 2。
这目前适用于日期选择器,但不适用于手动输入。如果日期是手动输入的并且早于最小日期,则该字段应留空。
问题 2
如果第一个日期发生变化(像以前一样更早的日期),第二个日期的最小日期也应该更新。
这同样适用于第三个日期选择器。
该页面上可以有 1-x 个日期选择器!
let d = new Date();
let nextValidDate = d.getDate() + "." + (d.getMonth() + 1) + "." + d.getFullYear();
$(document).on("blur change", ".datepicker", function () {
nextValidDate = $(this).datepicker("getDate");
});
$(document).on('focus', '.datepicker',
function () {
$(this).datepicker({
numberOfMonths: 1,
firstDay: 1,
changeMonth: true,
changeYear: true,
dateFormat: 'dd.mm.yy',
minDate: nextValidDate
});
$(this).datepicker('show');
});
$(document).on('blur', '.datepicker', function () {
if ($(this).val().length >= 2) {
parseInputDate(this);
}
});
function parseInputDate(elm) {
var currDate = new Date(),
monDt = (('0' + currDate.getMonth() + 1).slice(-2) + ('0' + currDate.getDate()).slice(-2)), // get current month+date to compare
inputVal = $(elm).val().match(/\d{2}/gi); // split date components into array of [dd,mm,yy,yy]
// another date validation, by comparing parameters and date object result
var isValidDate = function (yyyy, mm, dd) {
var dt = new Date(yyyy, parseInt(mm, 10) - 1, dd);
return (dt.getFullYear() + '-' + ('0' + (dt.getMonth() + 1)).slice(-2) + '-' + ('0' + dt.getDate()).slice(-2)) == yyyy + '-' + mm + '-' + dd;
}
if (inputVal != null && inputVal.length >= 2) {
var year = currDate.getFullYear();
if (monDt > (inputVal[1] + inputVal[0])) year++;
// generate formatted text based on date component count
// add date validation to catch invalid dates using (new Date('yyyy-mm-dd')).getTime() which will return NaN on invalid date
var result = (inputVal.length == 2 && isValidDate(year, inputVal[1], inputVal[0]) && inputVal[0] + '.' + inputVal[1] + '.' + year) ||
(inputVal.length == 3 && isValidDate('20' + inputVal[2], inputVal[1], inputVal[0]) && inputVal[0] + '.' + inputVal[1] + '.20' + inputVal[2]) ||
(inputVal.length == 4 && isValidDate(inputVal[2] + inputVal[3], inputVal[1], inputVal[0]) && inputVal[0] + '.' + inputVal[1] + '.' + inputVal[2] + inputVal[3]) ||
''; // set empty on invalid dates
$(elm).val(result);
nextValidDate = result;
} else {
$(elm).val('')
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<div>
<label for="date1">Date 1:</label>
<input type="text" class="datepicker" id="date1">
</div>
<div>
<label for="date2">Date 2:</label>
<input type="text" class="datepicker" id="date2">
</div>
<div>
<label for="date3">Date 3:</label>
<input type="text" class="datepicker" id="date3">
</div>
考虑这个例子:http://jqueryui.com/datepicker/#date-range
我们可以像这样设置您的代码:
$(function() {
var dateFormat = 'dd.mm.yy';
function getDate(el) {
var date;
try {
date = $.datepicker.parseDate(dateFormat, el.value);
} catch (error) {
date = null;
}
return date;
}
function checkMinDate(el) {
var date = getDate(el);
var minDate = $(el).datepicker("option", "minDate");
var test;
try {
test = (date >= minDate);
} catch (error) {
test = false;
}
return test;
}
$(".datepicker").datepicker({
numberOfMonths: 1,
firstDay: 1,
changeMonth: true,
changeYear: true,
dateFormat: dateFormat,
minDate: 0
}).on("change", function(e) {
e.preventDefault();
var td = getDate(this);
var dpid = $(this).attr("id");
var dpi = parseInt(dpid.slice(dpid.indexOf("-") + 1));
$("#date-" + (dpi + 1)).prop("disabled", false).datepicker("option", {
minDate: td,
defaultDate: td
});
if (!checkMinDate(this)) {
this.value = "";
return false;
}
return true;
});
$(".datepicker:not(:eq(0))").prop("disabled", true);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<div class="date-wrapper">
<div>
<label for="date1">Date 1:</label>
<input type="text" class="datepicker" id="date-1">
</div>
<div>
<label for="date2">Date 2:</label>
<input type="text" class="datepicker" id="date-2">
</div>
<div>
<label for="date3">Date 3:</label>
<input type="text" class="datepicker" id="date-3">
</div>
<div>
<label for="date3">Date 4:</label>
<input type="text" class="datepicker" id="date-4">
</div>
<div>
<label for="date3">Date 5:</label>
<input type="text" class="datepicker" id="date-5">
</div>
</div>
我认为这符合您的标准:
- 以前的日期字段应小于或 "before" 当前日期字段。
- 所有以前的日期都应小于此日期字段。
- 如果日期发生变化,则后续日期的最小日期也应更新。
函数 getDate()
接收一个元素并检测它是否包含字符串格式的日期(基于日期格式)和 return 等于该日期的日期对象或 null
.
函数checkMinDate()
是帮我们检测一个手动输入的日期。它根据 minDate 值检查手动输入的日期。如果它大于或等于 minDate
,它将 return 为真。如果小于 minDate
它将 return false.
在我们的 change
回调中,我们使用 .preventDefault()
来停止当前操作。这对于我们想要测试输入内容的类型事件很有帮助。我们稍后可以 return true
或 false
让事件继续进行。如果 checkMinDate
不是 true,我们可以清除值和 return false。
希望对您有所帮助!