Javascript UI日期选择器:选择日期将覆盖现有设置
我正在尝试编写一个自定义日期选择器,其中月份和年份范围的默认下拉列表(通过Javascript UI日期选择器:选择日期将覆盖现有设置,javascript,jquery,jquery-ui-datepicker,Javascript,Jquery,Jquery Ui Datepicker,我正在尝试编写一个自定义日期选择器,其中月份和年份范围的默认下拉列表(通过changemount和changeYear选项启用)被自定义下拉列表替换。是这样的: $("#myId").datepicker($.extend({setDate: newDateString},oldSettings)) 小提琴: 在从自定义下拉列表中选择月份或年份时,我希望相应地更改视图中的日期。因此,我从当前月份和年份构造日期字符串(这里,新月份/年份组合的日期默认为1),然后调用 $("#custom-htm
changemount
和changeYear
选项启用)被自定义下拉列表替换。是这样的:
$("#myId").datepicker($.extend({setDate: newDateString},oldSettings))
小提琴:
在从自定义下拉列表中选择月份或年份时,我希望相应地更改视图中的日期。因此,我从当前月份和年份构造日期字符串(这里,新月份/年份组合的日期默认为1),然后调用
$("#custom-html-block .custom-dropdown-option").on("click",function() {
...construct newDateString...
$("#myId").datepicker("setDate",newDateString)
});
$("#another-custom-html-block .custom-dropdown-option").on("click",function() {
...construct newDateString...
$("#myId").datepicker("setDate",newDateString)
});
我希望带有文本foo的span
在以编程方式单击新日期时保持不变
问题是:它会清除自定义下拉列表,而默认下拉列表会再次出现。我试着这样做:
$("#myId").datepicker($.extend({setDate: newDateString},oldSettings))
但它仍然不起作用。如何实现此功能?您可以设置函数
$.datepicker.\u generateMonthYearHeader
的值,该函数的下半部将是页面中所有datepicker的全局值
样本如下:
$.datepicker._generateMonthYearHeader = function(inst, drawMonth, drawYear, minDate, maxDate,
secondary, monthNames, monthNamesShort) {
var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
changeMonth = this._get(inst, "changeMonth"),
changeYear = this._get(inst, "changeYear"),
showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
html = "<div class='ui-datepicker-title'>",
monthHtml = "";
// year selection
if ( !inst.yearshtml ) {
inst.yearshtml = "";
if (secondary || !changeYear) {
html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
} else {
// determine range of years to display
years = this._get(inst, "yearRange").split(":");
thisYear = new Date().getFullYear();
determineYear = function(value) {
var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
parseInt(value, 10)));
return (isNaN(year) ? thisYear : year);
};
year = determineYear(years[0]);
endYear = Math.max(year, determineYear(years[1] || ""));
year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
inst.yearshtml += "<span class = 'dummy'>Foo</span> <select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"
for (; year <= endYear; year++) {
inst.yearshtml += "<option value='" + year + "'" +
(year === drawYear ? " selected='selected'" : "") +
">" + year + "</option>";
}
inst.yearshtml += "</select>";
html += inst.yearshtml;
inst.yearshtml = null;
}
}
$.datepicker.\u generateMonthYearHeader=函数(inst、drawMonth、drawYear、minDate、maxDate、,
二级,monthNames,Monthnameshort){
年、月、年、今年、确定年、年、年终、,
changeMonth=此项(inst,“changeMonth”),
changeYear=此项(inst,“changeYear”),
showMonthAfterYear=这个。_get(inst,“showMonthAfterYear”),
html=“”,
monthHtml=“”;
//年份选择
如果(!inst.yearshtml){
inst.yearshtml=“”;
如果(二级| |!变更年){
html+=“”+drawYear+“”;
}否则{
//确定要显示的年份范围
年数=此值。_get(inst,“yearRange”).split(“:”);
thisYear=新日期().getFullYear();
DeterminationEAR=函数(值){
var year=(value.match(/c[+\-].*/)?drawYear+parseInt(value.substring(1),10):
(value.match(/[+\-].*/)?今年+parseInt(值,10):
parseInt(值,10));
申报表(isNaN(年度)?本年度:年度);
};
年=确定年(年[0]);
endYear=Math.max(year,determinateyear(years[1]| |“”);
year=(minDate?Math.max(year,minDate.getFullYear()):year);
endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);
inst.yearshtml+=“Foo”
对于(;year一般来说,这就是为什么extend很糟糕。家长(在你的例子中是datepicker)对childs(你的自定义html)一无所知。每次它刷新视图时,你的更改都会丢失。这个问题通常通过组合来解决。目标是创建你自己的小部件(我认为这是jQuery中的术语)将datepicker作为局部变量并控制_generateMonthYearHeader函数调用。理论上很容易说,但在实践中(特别是jQuery)很难实现。更简单的解决方案是代理函数
//preserve _generateHTML because after it finish, html is visible and .ui-datepicker-month and .ui-datepicker-year are in dom tree
fn = $.datepicker._generateHTML; //preserve original function
$.datepicker._generateHTML = function(inst) {
//call original function
fn.call(this, inst);
//do custom changes
//you'll need better selectors in case of multiple datepicker instances
$(".ui-datepicker-month").replaceWith("#custom-html-block");
$(".ui-datepicker-year").replaceWith("#another-custom-html-block");
}
就我个人而言,我不喜欢这种方法(我更喜欢像我说的那样组合),但在你的例子中,它会更容易实现。其原因是generateMonthYearHeader是从许多不同的函数调用的
p.S.未经测试您介意提供一个吗?嗯,这是一个庞大的代码,嵌入了大量css和html。如果我过滤掉它们,它将减少我在这里提供的两个内容:(选择日期是否也会导致下拉列表被重置?不,因为下拉列表是在关注文本输入时弹出的,所以当我单击日期时,它会消失。当我再次关注文本输入时,会弹出一个新实例和自定义下拉列表。因此,不,在选择日期时,直到它消失,我似乎不会替换它们。H不过,如果你试图通过左上角和右上角的按钮导航到上个月或下个月,新的月份就来了,下拉列表将更改为默认值。你为什么要从自定义下拉列表开始?你只是想对下拉列表的外观有更多的控制吗?就我所知,这很有魅力。只是编辑,哟你的代码没有改变日期,因为你忘了在
中包含文本foo。这是更新后的提琴:当然,我错过了那部分。我更新了答案,谢谢。但是我再次浏览了答案,它还照顾到了用户通过左上角和右上角的按钮浏览月份的部分。太棒了另外,你能给if-else
条件添加更多的注释吗?这是从源代码中获取的。我用一个简化版本更新了答案。
//preserve _generateHTML because after it finish, html is visible and .ui-datepicker-month and .ui-datepicker-year are in dom tree
fn = $.datepicker._generateHTML; //preserve original function
$.datepicker._generateHTML = function(inst) {
//call original function
fn.call(this, inst);
//do custom changes
//you'll need better selectors in case of multiple datepicker instances
$(".ui-datepicker-month").replaceWith("#custom-html-block");
$(".ui-datepicker-year").replaceWith("#another-custom-html-block");
}