摘要:JQuery-UI的datepicker擴充
JQuery-UI是非常簡單好用的函式庫,利用這個函式庫可以輕易地完成一些網頁上的操作特效,
對於其中的datepicker控制項,我想要使用民國年的格式來顯示日期,
這一點其本身並不支援,也沒有提供可以設定的方法,因此需要透過變更其原本的行為來達成目的,
而我希望達成的目標是,不去修改其原始碼,藉由一些手段來重新定義其行為,
這一點在Javascript上是可以輕易達成的,
要達成這樣的目的,從datepicker的原始碼中可以知道日期的顯示有三個部分是跟年有關的,
一個是日曆顯示的年的顯示函式_generateMonthYearHeader,
將值讀取並轉成日期的_setDateFromField,以及將日期格式化的_formatDate,
因此只要重新定義這三個函式,就能使datepicker可以使用民國年的格式來顯示日期,
日曆顯示的部分,我保留原本的函式以別的名稱存放,並以自己定義的函式取代,
$.datepicker._phoenixGenerateMonthYearHeader = $.datepicker._generateMonthYearHeader;
$.datepicker._generateMonthYearHeader = function(inst, drawMonth, drawYear, minDate, maxDate,
selectedDate, secondary, monthNames, monthNamesShort)
{
var result = $($.datepicker._phoenixGenerateMonthYearHeader(
inst, drawMonth, drawYear - 1911, minDate, maxDate,
selectedDate, secondary, monthNames, monthNamesShort));
result.children(".ui-datepicker-year").html($._this.html() + "年");
return result.parent().html();
};
另外兩個函式則直接以自己的函式取代,
$.datepicker._setDateFromField = function(inst)
{
var dateFormat = this._get(inst, 'dateFormat');
var dates = inst.input ? inst.input.val() : null;
inst.endDay = inst.endMonth = inst.endYear = null;
var date = defaultDate = this._getDefaultDate(inst);
var settings = this._getFormatConfig(inst);
try
{
var dateArr = dates.split("/");
var year = parseInt(dateArr[0]) + 1911;
var month = parseInt(dateArr[1]);
var day = parseInt(dateArr[2]);
date = this.parseDate(dateFormat, this.formatDate(dateFormat, date, settings), settings) || defaultDate;
} catch (event)
{
this.log(event);
date = defaultDate;
}
inst.selectedDay = date.getDate();
inst.drawMonth = inst.selectedMonth = date.getMonth();
inst.drawYear = inst.selectedYear = date.getFullYear();
inst.currentDay = (dates ? date.getDate() : 0);
inst.currentMonth = (dates ? date.getMonth() : 0);
inst.currentYear = (dates ? date.getFullYear() : 0);
this._adjustInstDate(inst);
};
$.datepicker._formatDate = function(inst, day, month, year)
{
if (!day)
{
inst.currentDay = inst.selectedDay;
inst.currentMonth = inst.selectedMonth;
inst.currentYear = inst.selectedYear;
}
var date = (day ? (typeof day == 'object' ? day :
this._daylightSavingAdjust(new Date(year, month, day))) :
this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
return (date.getFullYear() - 1911) + "/" +
(date.getMonth() < 9 ? "0" + (date.getMonth() + 1) : (date.getMonth() + 1)) + "/" +
(date.getDate() < 9 ? "0" + date.getDate() : date.getDate());
};
這樣就能使datepicker顯示民國年,不過這之中感覺javascript的this並不怎麼好掌握,
有時候某種方法可以,在別的地方,這個方法又不行了,
得找些資料來了解javascript的this是怎麼回事。
完成的程式只要在引入JQuery-UI的datepicker之後引入,就可以改變datepicker的行為,
完整的程式碼:
(function(_jQueryInit)
{
jQuery.fn.init = function(selector, context)
{
return (jQuery._this = new _jQueryInit(selector, context));
};
})(jQuery.fn.init);
(function($)
{
$.datepicker._phoenixGenerateMonthYearHeader = $.datepicker._generateMonthYearHeader;
$.datepicker._generateMonthYearHeader = function(inst, drawMonth, drawYear, minDate, maxDate,
selectedDate, secondary, monthNames, monthNamesShort)
{
var result = $($.datepicker._phoenixGenerateMonthYearHeader(
inst, drawMonth, drawYear - 1911, minDate, maxDate,
selectedDate, secondary, monthNames, monthNamesShort));
result.children(".ui-datepicker-year").html($._this.html() + "年");
return result.parent().html();
};
$.datepicker._setDateFromField = function(inst)
{
var dateFormat = this._get(inst, 'dateFormat');
var dates = inst.input ? inst.input.val() : null;
inst.endDay = inst.endMonth = inst.endYear = null;
var date = defaultDate = this._getDefaultDate(inst);
var settings = this._getFormatConfig(inst);
try
{
var dateArr = dates.split("/");
var year = parseInt(dateArr[0]) + 1911;
var month = parseInt(dateArr[1]);
var day = parseInt(dateArr[2]);
date = this.parseDate(dateFormat, this.formatDate(dateFormat, date, settings), settings) || defaultDate;
} catch (event)
{
this.log(event);
date = defaultDate;
}
inst.selectedDay = date.getDate();
inst.drawMonth = inst.selectedMonth = date.getMonth();
inst.drawYear = inst.selectedYear = date.getFullYear();
inst.currentDay = (dates ? date.getDate() : 0);
inst.currentMonth = (dates ? date.getMonth() : 0);
inst.currentYear = (dates ? date.getFullYear() : 0);
this._adjustInstDate(inst);
};
$.datepicker._formatDate = function(inst, day, month, year)
{
if (!day)
{
inst.currentDay = inst.selectedDay;
inst.currentMonth = inst.selectedMonth;
inst.currentYear = inst.selectedYear;
}
var date = (day ? (typeof day == 'object' ? day :
this._daylightSavingAdjust(new Date(year, month, day))) :
this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
return (date.getFullYear() - 1911) + "/" +
(date.getMonth() < 9 ? "0" + (date.getMonth() + 1) : (date.getMonth() + 1)) + "/" +
(date.getDate() < 9 ? "0" + date.getDate() : date.getDate());
};
})(jQuery);
----------------------------------------------------------------------------------------------------------------------------------------------
謝謝星寂兄的告知,更新的程式碼:
(function(_jQueryInit)
{
jQuery.fn.init = function(selector, context)
{
return (jQuery._this = new _jQueryInit(selector, context));
};
})(jQuery.fn.init);
(function($)
{
$.datepicker._baseGenerateMonthYearHeader = $.datepicker._generateMonthYearHeader;
$.datepicker._generateMonthYearHeader = function(inst, drawMonth, drawYear, minDate, maxDate,
selectedDate, secondary, monthNames, monthNamesShort)
{
var result = $($.datepicker._baseGenerateMonthYearHeader(
inst, drawMonth, drawYear - 1911, minDate, maxDate,
selectedDate, secondary, monthNames, monthNamesShort));
result.children(".ui-datepicker-year").html($._this.html() + "年");
return $("<div/>").append(result).html();
};
$.datepicker._setDateFromField = function(inst)
{
var dateFormat = this._get(inst, 'dateFormat');
var dates = inst.input ? inst.input.val() : null;
inst.endDay = inst.endMonth = inst.endYear = null;
var date = defaultDate = this._getDefaultDate(inst);
var settings = this._getFormatConfig(inst);
try
{
var dateArr = dates.split("/");
var year = parseInt(dateArr[0]) + 1911;
var month = parseInt(dateArr[1]);
var day = parseInt(dateArr[2]);
date = this.parseDate(dateFormat, this.formatDate(dateFormat, date, settings), settings) || defaultDate;
} catch (event)
{
this.log(event);
date = defaultDate;
}
inst.selectedDay = date.getDate();
inst.drawMonth = inst.selectedMonth = date.getMonth();
inst.drawYear = inst.selectedYear = date.getFullYear();
inst.currentDay = (dates ? date.getDate() : 0);
inst.currentMonth = (dates ? date.getMonth() : 0);
inst.currentYear = (dates ? date.getFullYear() : 0);
this._adjustInstDate(inst);
};
$.datepicker._formatDate = function(inst, day, month, year)
{
if (!day)
{
inst.currentDay = inst.selectedDay;
inst.currentMonth = inst.selectedMonth;
inst.currentYear = inst.selectedYear;
}
var date = (day ? (typeof day == 'object' ? day :
this._daylightSavingAdjust(new Date(year, month, day))) :
this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
return (date.getFullYear() - 1911) + "/" +
(date.getMonth() < 9 ? "0" + (date.getMonth() + 1) : (date.getMonth() + 1)) + "/" +
(date.getDate() < 9 ? "0" + date.getDate() : date.getDate());
};
})(jQuery);