如何解决 jQuery UI Datepicker 的手动日期输入问题?
How to resolve manual date entry for jQuery UI Datepicker?
我的页面上有一个 jQuery UI 日期选择器,应该可以手动输入日期。为了让用户更容易,还应该可以输入日期的简短形式(仅限日和月),一旦焦点离开该字段,就会用下一个可能的日期来解决。
示例(德语日期格式):
29092019 应解析为 29.09.2019
2909 应解析为 29.09.2019
当今年 3 月 1 日已经结束时,0103 应该解决为 01.03.2020。
遇到这样的问题如何开始?
$( function() {
$("#myDate").datepicker({
dateFormat : "dd.mm.yy"
});
});
<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>
<input type="text" id="myDate" />
这是一种方法 - 请在下方评论:
// Some sample dates
let userDates = [
"29092019",
"2909",
"0103",
"1303",
"1403"
];
// Run the sample dates through parseUserDate()
for (let userDate of userDates) {
console.log(userDate + ":");
console.log(parseUserDate(userDate));
}
function parseUserDate(dateStr) {
let parsedDate;
// If it's 8 characters long, slice into YYYY-MM-DD
if (dateStr.length === 8) {
let dateSplit = [
dateStr.slice(4),
dateStr.slice(2, 4),
dateStr.slice(0, 2)
];
parsedDate = new Date(dateSplit.join("-"));
}
// 4 characters long - slice into MM-DD and prefix with YYYY later.
else if (dateStr.length === 4) {
let monthDay = [
dateStr.slice(2, 4),
dateStr.slice(0, 2)
].join("-");
// The current date - this is used to check if the user date should be next year.
let now = new Date();
// MM-DD with the current year.
let userDateCurrentYear = new Date(now.getFullYear() + "-" + monthDay);
// MM-DD with next year.
let userDateNextYear = new Date((now.getFullYear() + 1) + "-" + monthDay);
// If the current date is past the MM-DD this year, set parsedDate to next year's date.
if (now > userDateCurrentYear) {
parsedDate = userDateNextYear;
} else {
parsedDate = userDateCurrentYear;
}
}
return parsedDate;
}
试试这个..
与jQuery的日期选择器集成,你可以像下面那样做
编辑:
- 添加无效日期验证,&return无效日期的空字符串
- 修复日期验证:添加闰日验证
- 修复 monDt 变量(添加 getMonth+1,因为 JS 中的月份以 0 开头)
$(function(){
$('.datepicker').datepicker({
dateFormat:'dd.mm.yy'
});
$('.datepicker').on('blur',function(){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);
} else $(elm).val('');
}
</script>
<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>
<input type="text" id="myDate" class="datepicker" />
这是一个带有一些约束的多个日期选择器的示例。您可以根据需要进行调整:)
& return 基于日期选择器格式的日期字符串
$(function(){
initDatePicker();
})
function initDatePicker(){
// do a loop for custom property on each element
$('.datepicker').each(function(){
// you can find available formats here : http://api.jqueryui.com/datepicker/#utility-formatDate
$(this).datepicker({
dateFormat:'yy.mm.dd'
});
// set minimum date from data attribute.
if (typeof $(this).data('mindate') != 'undefined') {
$(this).datepicker('option','minDate',$(this).data('mindate'));
}
// set maximum date from data attribute.
if (typeof $(this).data('maxdate') != 'undefined') {
$(this).datepicker('option','maxDate',$(this).data('maxdate'));
}
$(this).on('change',function(){
parseInputDate(this);
// now, set date relations :)
if (typeof $(this).data('nextelem') != 'undefined') {
$($(this).data('nextelem')).datepicker( "option", "minDate", getDate( this ) );
}
if (typeof $(this).data('prevelem') != 'undefined') {
$($(this).data('prevelem')).datepicker( "option", "maxDate", getDate( this ) );
}
});
});
}
// get date function taken from : http://jqueryui.com/datepicker/#date-range
function getDate( element ) {
var date;
try {
date = $.datepicker.parseDate( $(element).datepicker('option','dateFormat'), element.value );
} catch( error ) {
date = null;
}
return date;
}
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]
format = $(elm).datepicker("option", "dateFormat"); // get current element's datepicker format
// check if it's already a valid entry, then do nothing
if ($(elm).val() == $.datepicker.formatDate(format,$(elm).datepicker('getDate'))) return;
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;
}
var getDateString = function(yyyy,mm,dd) {
var dt = new Date(yyyy,parseInt(mm,10)-1,dd);
// get datepicker format & get date string using datepicker's formatDate function
return $.datepicker.formatDate($(elm).datepicker("option", "dateFormat"),dt);
}
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, & generate date string according to datepicker format
var result = (inputVal.length==2 && isValidDate(year,inputVal[1],inputVal[0]) && getDateString(year,inputVal[1],inputVal[0])) ||
(inputVal.length==3 && isValidDate('20'+inputVal[2],inputVal[1],inputVal[0]) && getDateString('20'+inputVal[2],inputVal[1],inputVal[0])) ||
(inputVal.length==4 && isValidDate(inputVal[2]+inputVal[3],inputVal[1],inputVal[0]) && getDateString(inputVal[2]+inputVal[3],inputVal[1],inputVal[0])) ||
''; // set empty on invalid dates
$(elm).val(result);
} else $(elm).val('');
// add validation to invalidate out-of-range value
// get selected/entered date
var cdate = $(elm).datepicker('getDate');
// get range
var minDateAttr = $(elm).datepicker("option", "minDate");
var maxDateAttr = $(elm).datepicker("option", "maxDate");
// get datepicker instance
var inst = $('#myDate').data("datepicker");
var isValid = false;
if (minDateAttr!=null) {
// get range as date object
var minDateObj = $.datepicker._determineDate(inst, minDateAttr, new Date());
if (minDateObj<=cdate) isValid = true
}
if (isValid && maxDateAttr!=null) {
// get range as date object
var maxDateObj = $.datepicker._determineDate(inst, maxDateAttr, new Date());
if (maxDateObj>=cdate) isValid = true
}
if (!isValid) $(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 rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
Dates :
<input type="text" id="myDate" class="datepicker" data-nextelem="#myDate2" data-mindate="-20" maxlength="10" style="width:80px" /> -
<input type="text" id="myDate2" class="datepicker" data-prevelem="#myDate" data-nextelem="#myDate3" maxlength="10" style="width:80px"/> -
<input type="text" id="myDate3" class="datepicker" data-prevelem="#myDate2" data-maxdate="+2y" maxlength="10" style="width:80px"/>
我的页面上有一个 jQuery UI 日期选择器,应该可以手动输入日期。为了让用户更容易,还应该可以输入日期的简短形式(仅限日和月),一旦焦点离开该字段,就会用下一个可能的日期来解决。
示例(德语日期格式):
29092019 应解析为 29.09.2019
2909 应解析为 29.09.2019
当今年 3 月 1 日已经结束时,0103 应该解决为 01.03.2020。
遇到这样的问题如何开始?
$( function() {
$("#myDate").datepicker({
dateFormat : "dd.mm.yy"
});
});
<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>
<input type="text" id="myDate" />
这是一种方法 - 请在下方评论:
// Some sample dates
let userDates = [
"29092019",
"2909",
"0103",
"1303",
"1403"
];
// Run the sample dates through parseUserDate()
for (let userDate of userDates) {
console.log(userDate + ":");
console.log(parseUserDate(userDate));
}
function parseUserDate(dateStr) {
let parsedDate;
// If it's 8 characters long, slice into YYYY-MM-DD
if (dateStr.length === 8) {
let dateSplit = [
dateStr.slice(4),
dateStr.slice(2, 4),
dateStr.slice(0, 2)
];
parsedDate = new Date(dateSplit.join("-"));
}
// 4 characters long - slice into MM-DD and prefix with YYYY later.
else if (dateStr.length === 4) {
let monthDay = [
dateStr.slice(2, 4),
dateStr.slice(0, 2)
].join("-");
// The current date - this is used to check if the user date should be next year.
let now = new Date();
// MM-DD with the current year.
let userDateCurrentYear = new Date(now.getFullYear() + "-" + monthDay);
// MM-DD with next year.
let userDateNextYear = new Date((now.getFullYear() + 1) + "-" + monthDay);
// If the current date is past the MM-DD this year, set parsedDate to next year's date.
if (now > userDateCurrentYear) {
parsedDate = userDateNextYear;
} else {
parsedDate = userDateCurrentYear;
}
}
return parsedDate;
}
试试这个..
与jQuery的日期选择器集成,你可以像下面那样做
编辑:
- 添加无效日期验证,&return无效日期的空字符串
- 修复日期验证:添加闰日验证
- 修复 monDt 变量(添加 getMonth+1,因为 JS 中的月份以 0 开头)
$(function(){
$('.datepicker').datepicker({
dateFormat:'dd.mm.yy'
});
$('.datepicker').on('blur',function(){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);
} else $(elm).val('');
}
</script>
<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>
<input type="text" id="myDate" class="datepicker" />
这是一个带有一些约束的多个日期选择器的示例。您可以根据需要进行调整:)
& return 基于日期选择器格式的日期字符串
$(function(){
initDatePicker();
})
function initDatePicker(){
// do a loop for custom property on each element
$('.datepicker').each(function(){
// you can find available formats here : http://api.jqueryui.com/datepicker/#utility-formatDate
$(this).datepicker({
dateFormat:'yy.mm.dd'
});
// set minimum date from data attribute.
if (typeof $(this).data('mindate') != 'undefined') {
$(this).datepicker('option','minDate',$(this).data('mindate'));
}
// set maximum date from data attribute.
if (typeof $(this).data('maxdate') != 'undefined') {
$(this).datepicker('option','maxDate',$(this).data('maxdate'));
}
$(this).on('change',function(){
parseInputDate(this);
// now, set date relations :)
if (typeof $(this).data('nextelem') != 'undefined') {
$($(this).data('nextelem')).datepicker( "option", "minDate", getDate( this ) );
}
if (typeof $(this).data('prevelem') != 'undefined') {
$($(this).data('prevelem')).datepicker( "option", "maxDate", getDate( this ) );
}
});
});
}
// get date function taken from : http://jqueryui.com/datepicker/#date-range
function getDate( element ) {
var date;
try {
date = $.datepicker.parseDate( $(element).datepicker('option','dateFormat'), element.value );
} catch( error ) {
date = null;
}
return date;
}
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]
format = $(elm).datepicker("option", "dateFormat"); // get current element's datepicker format
// check if it's already a valid entry, then do nothing
if ($(elm).val() == $.datepicker.formatDate(format,$(elm).datepicker('getDate'))) return;
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;
}
var getDateString = function(yyyy,mm,dd) {
var dt = new Date(yyyy,parseInt(mm,10)-1,dd);
// get datepicker format & get date string using datepicker's formatDate function
return $.datepicker.formatDate($(elm).datepicker("option", "dateFormat"),dt);
}
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, & generate date string according to datepicker format
var result = (inputVal.length==2 && isValidDate(year,inputVal[1],inputVal[0]) && getDateString(year,inputVal[1],inputVal[0])) ||
(inputVal.length==3 && isValidDate('20'+inputVal[2],inputVal[1],inputVal[0]) && getDateString('20'+inputVal[2],inputVal[1],inputVal[0])) ||
(inputVal.length==4 && isValidDate(inputVal[2]+inputVal[3],inputVal[1],inputVal[0]) && getDateString(inputVal[2]+inputVal[3],inputVal[1],inputVal[0])) ||
''; // set empty on invalid dates
$(elm).val(result);
} else $(elm).val('');
// add validation to invalidate out-of-range value
// get selected/entered date
var cdate = $(elm).datepicker('getDate');
// get range
var minDateAttr = $(elm).datepicker("option", "minDate");
var maxDateAttr = $(elm).datepicker("option", "maxDate");
// get datepicker instance
var inst = $('#myDate').data("datepicker");
var isValid = false;
if (minDateAttr!=null) {
// get range as date object
var minDateObj = $.datepicker._determineDate(inst, minDateAttr, new Date());
if (minDateObj<=cdate) isValid = true
}
if (isValid && maxDateAttr!=null) {
// get range as date object
var maxDateObj = $.datepicker._determineDate(inst, maxDateAttr, new Date());
if (maxDateObj>=cdate) isValid = true
}
if (!isValid) $(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 rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
Dates :
<input type="text" id="myDate" class="datepicker" data-nextelem="#myDate2" data-mindate="-20" maxlength="10" style="width:80px" /> -
<input type="text" id="myDate2" class="datepicker" data-prevelem="#myDate" data-nextelem="#myDate3" maxlength="10" style="width:80px"/> -
<input type="text" id="myDate3" class="datepicker" data-prevelem="#myDate2" data-maxdate="+2y" maxlength="10" style="width:80px"/>