我正在尝试编写一个自定义日期选择器,其中月份和年份范围的默认下拉(通过changeMonth
和changeYear
选项启用)将被自定义下拉列表替换。它是这样的:
小提琴:http://jsfiddle.net/gGV3v/
$("#myId").datepicker({
...default settings...
beforeShow: function() {
...here I replace the default dropdowns by custom dropdowns...
...something like...
$(".ui-datepicker-month").replaceWith("#custom-html-block");
$(".ui-datepicker-year").replaceWith("#another-custom-html-block");
}
});
从自定义下拉列表中选择月份或年份时,我想相应地更改视图中的日期。所以我构建了当前月份和年份的日期字符串(新月/年组合的默认日期为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)
});
我希望span
文字 foo 在点击它时以编程方式设置新日期时保持不变。
问题是:它消除了自定义下拉菜单,默认值下降了。我试着做这样的事情:
$("#myId").datepicker($.extend({setDate: newDateString},oldSettings))
但它仍然无效。我如何使这项工作?
答案 0 :(得分:1)
你可以设置函数$.datepicker._generateMonthYearHeader
的值,它是页面中所有日期选择器全局的缺点。
样本如下:
$.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;
}
}
你的小提琴:http://jsfiddle.net/gGV3v/2/
<强>更新强>
没有按钮,并且使用更好的方法,现在您可以控制所有生成的HTML:
var oldGenerateHTML = $.datepicker._generateHTML;
function newGenerateHTML(inst) {
var html = oldGenerateHTML.call(this, inst);
var $html = $(html);
$html.find('[data-handler=prev]').remove();
$html.find('[data-handler=next]').remove();
$html.find('[data-handler=selectMonth]').replaceWith('<span class="dummy">Foo</span>');
return $html;
}
$.datepicker._generateHTML = newGenerateHTML;
小提琴也更新了:http://jsfiddle.net/gGV3v/4/
答案 1 :(得分:1)
一般来说,这就是为什么延伸很糟糕。父(在你的情况下是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。未经测试