Javascript 更新后在jQueryUI.datepicker中重新绘制自定义列
我试图定制jQueryUI的datepicker,为我的客户做一些很酷的事情,但我被卡住了。我在日历中添加了一个自定义列,以显示每周的租金。不幸的是,jQueryUI的日历在每次点击时都会重新绘制,所以我的自定义列会被删除,显然,如果他们更改月份,这种情况也会发生 我正在寻找最佳实践来检测我的专栏是否消失并重新绘制。我希望jQueryUI.datepicker在完成绘制时触发某种“完成”事件,但这不会发生。所有的钩子都在画日历之前。感谢您的帮助 代码Javascript 更新后在jQueryUI.datepicker中重新绘制自定义列,javascript,jquery,jquery-ui,datepicker,calendar,Javascript,Jquery,Jquery Ui,Datepicker,Calendar,我试图定制jQueryUI的datepicker,为我的客户做一些很酷的事情,但我被卡住了。我在日历中添加了一个自定义列,以显示每周的租金。不幸的是,jQueryUI的日历在每次点击时都会重新绘制,所以我的自定义列会被删除,显然,如果他们更改月份,这种情况也会发生 我正在寻找最佳实践来检测我的专栏是否消失并重新绘制。我希望jQueryUI.datepicker在完成绘制时触发某种“完成”事件,但这不会发生。所有的钩子都在画日历之前。感谢您的帮助 代码 /** * A Wrapper for j
/**
* A Wrapper for jQueryUI.datepicker.
*/
(function( factory ){
factory( jQuery );
}( function( $ ){
function MpCalendar(options) {
options = options || {}
this._curInst = null;
this._defaults = {
highlightDateCSS: "mpcalendar-highlight",
weeklyRateCSS: "mpcalendar-weekly-rate",
weeklyRateHeading: "Rate"
};
this.settings = $.extend({}, this._defaults, options);
};
$.extend(MpCalendar.prototype , {
/* Create a new instance of the object. */
_newInst: function(target) {
return {
element: target,
blockDates: {},
weeklyRates: [],
input1: [],
input2: []
};
},
/* Retrieve a previous instance of the object. */
_getInst: function(target) {
try {
return $.data(target, "mpcalendar");
} catch(e) {
throw "Missing instance for this MpCalendar.";
}
},
/* Attach the calendar to the target element */
_attachMpCalendar: function(target, settings) {
//Check that we were given a div or span. We're only making inline calendars.
var nodeName = target.nodeName.toLowerCase();
if(nodeName !== ("div" || "span"))
throw new Error('Target must be a div or span got "'+nodeName+'" instead.');
var self = this;
var inst = this._newInst($(target));
inst.settings = $.extend({}, settings || {}, {
beforeShowDay: function(date) {
return self._beforeShowDay(inst, date);
},
onSelect: function(date, datepicker) {
return self._onSelect(inst, date, datepicker);
}
});
//Make sure showWeek is true.
inst.settings.showWeek = true;
//Make sure we have inputs to use.
inst.input1 = $(inst.element.data('mpinput1'));
if(!inst.input1.length)
throw new Error('Could not find mpinput1.');
inst.input2 = $(inst.element.data('mpinput2'));
if(!inst.input2.length)
throw new Error('Could not find mpinput2.');
//Initiate block dates found in the settings.
if(typeof inst.settings.blockDates === "object")
this._setBlockDates(inst, inst.settings.blockDates);
//Initiat weekly rates found in the settings.
if(typeof inst.settings.weeklyRates === "object")
this._setWeeklyRates(inst, inst.settings.weeklyRates);
//Initiate datepicker.
inst.element.datepicker(inst.settings);
//Draw extra rates column.
this._attachRates(inst);
//Store our instance.
$.data(target, "mpcalendar", inst);
},
/* Set block dates with the given list of dates */
_setBlockDatesMpCalendar: function(target, dates) {
if(typeof dates !== "object")
throw new Error('Expected dates to be an "object" got "' + typeof dates + '" instead.');
var inst = this._getInst(target);
this._setBlockDates(inst, dates);
},
/* Add a given date to the block list */
_addBlockDateMpCalendar: function(target, date, status) {
var inst = this._getInst(target);
this._addBlockDate(inst, date, status);
},
/* Remove a given date from the block list */
_removeBlockDateMpCalendar: function(target, date) {
var inst = this._getInst(target);
this._removeBlockDate(inst, date);
},
/* Set Weekly Rates with the given list of rates */
_setWeeklyRatesMpCalendar: function(target, rates) {
if(!(Array.isArray(rates)))
throw new Error('Expected rates to be an "array" got "' + typeof rates + '" instead.');
var inst = this._getInst(target);
this._setWeeklyRates(inst, rates);
},
/* Set the Rate for a single Week */
_setWeeklyRateMpCalendar: function(target, week, rate) {
if(typeof week !== "number")
week = parseInt(week);
if(typeof rate !== "number")
rate = parseFloat(rate);
var inst = this._getInst(target);
this._setWeeklyRate(inst, week, rate);
},
/**
* Return an array of Date objects contianing the dates selected on the calendar.
*
* @param {object} target
* @returns {Array}
*/
_getSelectedDatesMpCalendar: function(target) {
var inst = this._getInst(target);
return this._getSelectedDates(inst);
},
/**
* Return the CSS Class used for the specified date or false if the date is not blocked.
*
* @param {object} target
* @param {Date} date
* @returns {string}
*/
_isBlockedDateMpCalendar: function(target, date) {
var inst = this._getInst(target);
return this._isBlockedDate(inst, date);
},
/* Attach our custom weekly rates column */
_attachRates: function(inst) {
var self = this;
//Attach header and empty rates.
var heading = $('<th>'+ this.settings.weeklyRateHeading +'</th>');
var tdata = $('<td class="'+this.settings.weeklyRateCSS+'"></td>');
inst.element.find('.ui-datepicker-calendar thead tr').append(heading);
inst.element.find('.ui-datepicker-calendar tbody tr').append(tdata);
inst.element.find('td.ui-datepicker-week-col').each(function(){
var week = parseInt($(this).text());
var rate = inst.weeklyRates[week] || "Test";
$(this).closest('tr').find('.'+ self.settings.weeklyRateCSS).html(rate);
});
},
_isBlockedDate: function(inst, date) {
if(!(date instanceof Date))
throw new Error('Expected date to be instance of Date.');
try {
var vacancyStatus = inst.blockDates[date.getFullYear()][date.getMonth()][date.getDate()] || false;
return vacancyStatus;
} catch(e) {
}
return false;
},
_getSelectedDates: function(inst) {
var dates = [];
try {
var date1 = $.datepicker.parseDate($.datepicker._defaults.dateFormat, inst.input1.val());
var date2 = $.datepicker.parseDate($.datepicker._defaults.dateFormat, inst.input2.val());
if((date1 || date2) === null)
return dates;
while(date1 <= date2) {
dates.push(new Date(date1));
date1.setDate(date1.getDate() + 1);
}
} catch(e) {
//Guess we don't have any dates.
}
return dates;
},
_setBlockDates: function(inst, dates) {
inst.blockDates = {};
for(var date in dates) {
if(typeof dates[date] !== 'string')
continue;
this._addBlockDate(inst, date, dates[date]);
}
},
_setWeeklyRates: function(inst, rates) {
inst.weeklyRates = [];
for(var week in rates) {
var rate = rates[week];
if(typeof week !== 'number')
week = parseInt(week);
if(typeof rate !== 'number')
rate = parseFloat(rate);
this._setWeeklyRate(inst, week, rate);
}
},
_removeBlockDate: function(inst, date) {
try {
var datetime = new Date(date);
var day = datetime.getDate();
var month = datetime.getMonth();
var year = datetime.getFullYear();
delete inst.blockDates[year][month][day];
} catch(e) {
//The date probably never existed any way.
}
},
_addBlockDate: function(inst, date, status) {
if(typeof status !== "string")
throw new Error('Expected class name to be typeof "string" got "' + typeof status + '".');
try {
var datetime = new Date(date);
var day = datetime.getDate();
var month = datetime.getMonth();
var year = datetime.getFullYear();
if(typeof inst.blockDates[year] !== "object")
inst.blockDates[year] = {};
if(typeof inst.blockDates[year][month] !== "object")
inst.blockDates[year][month] = {};
inst.blockDates[year][month][day] = status;
} catch(e) {
throw new Error('Error adding block date: "' + e.message + '".');
}
},
_setWeeklyRate: function(inst, week, rate) {
inst.weeklyRates[week] = rate;
},
/* Function attached to datepicker's beforeShowDay, handles showing blocked dates and range selection */
_beforeShowDay: function(inst, date) {
var cssClasses = [];
try {
var vacancyStatus = inst.blockDates[date.getFullYear()][date.getMonth()][date.getDate()];
if(vacancyStatus !== undefined)
cssClasses.push(vacancyStatus);
} catch(e) {
//There is no blockDate set.
}
try {
var date1 = $.datepicker.parseDate($.datepicker._defaults.dateFormat, inst.input1.val());
var date2 = $.datepicker.parseDate($.datepicker._defaults.dateFormat, inst.input2.val());
var highlight = ((date.getTime() === date1.getTime()) || (date2 && date >= date1 && date <= date2)) ? this.settings.highlightDateCSS : '';
cssClasses.push(highlight);
} catch(e) {
//Oh well.
}
if(cssClasses.length > 0)
return [true, cssClasses.join(' '), null];
return [true, '', null];
},
/* Function attached to datepicker's onSelect, allows for rangeselection */
_onSelect: function(inst, dateText, datepicker) {
var date1 = $.datepicker.parseDate($.datepicker._defaults.dateFormat, inst.input1.val());
var date2 = $.datepicker.parseDate($.datepicker._defaults.dateFormat, inst.input2.val());
var selectedDate = $.datepicker.parseDate($.datepicker._defaults.dateFormat, dateText);
if (!date1 || date2) {
inst.input1.val(dateText);
inst.input2.val("");
inst.element.datepicker('refresh');
} else if( selectedDate < date1 ) {
inst.input2.val( inst.input1.val() );
inst.input1.val( dateText );
inst.element.datepicker('refresh');
} else {
inst.input2.val(dateText);
inst.element.datepicker('refresh');
}
},
/* Because we are wrapping datepicker, this handles jQuery calls to internal functions for both MpCalendar and datepicker */
_callFunction: function(target, option) {
var otherArgs = Array.prototype.slice.call(arguments, 2);
if(typeof this["_"+option+"MpCalendar"] === "function")
return this["_"+option+"MpCalendar"].apply(this, [target].concat(otherArgs));
var inst = this._getInst(target);
inst.element.datepicker.apply(inst.element.datepicker(), [option].concat(otherArgs));
}
});
//jQuery extension for using MpCalendar.
$.fn.mpcalendar = function(options) {
var otherArgs = Array.prototype.slice.call(arguments, 1);
//If they are calling for one of our static methods, pass the call to MpCalendar and return the value.
if(typeof options === "string" && (options === "isBlockedDate" || options === "getSelectedDates"))
return $.mpcalendar["_"+options+"MpCalendar"].apply($.mpcalendar, [ this[0] ].concat(otherArgs));
//Else, call the appropriate function and return.
return this.each( function() {
typeof options === "string" ?
$.mpcalendar._callFunction.apply($.mpcalendar, [ this, options ].concat(otherArgs)) :
$.mpcalendar._attachMpCalendar(this, options);
});
};
$.mpcalendar = new MpCalendar();
return $.mpcalendar;
}));
/* Attach our custom weekly rates column */
_attachRates: function(inst) {
var self = this;
//Attach header and empty rates.
var heading = $('<th>'+ this.settings.weeklyRateHeading +'</th>');
var tdata = $('<td class="'+this.settings.weeklyRateCSS+'"></td>');
inst.element.find('.ui-datepicker-calendar thead tr').append(heading);
inst.element.find('.ui-datepicker-calendar tbody tr').append(tdata);
inst.element.find('td.ui-datepicker-week-col').each(function(){
var week = parseInt($(this).text());
var rate = inst.weeklyRates[week] || "Test";
$(this).closest('tr').find('.'+ self.settings.weeklyRateCSS).html(rate);
});
inst.element.find('.ui-datepicker-calendar').first().on('remove', function(){
$(this).off("remove");
setTimeout(function(){
self._attachRates(inst);
}, 1);
});
},
/**
*jQueryUI.datepicker的包装器。
*/
(功能(工厂){
工厂(jQuery);
}(函数($){
功能MpCalendar(选项){
选项=选项| |{}
这是。_curInst=null;
这是默认值。_默认值={
highlightDateCSS:“mpcalendar突出显示”,
weeklyRateCSS:“mpcalendar周费率”,
周刊标题:“利率”
};
this.settings=$.extend({},this.\u默认值,选项);
};
$.extend(MpCalendar.prototype{
/*创建对象的新实例*/
_newInst:功能(目标){
返回{
要素:目标,
块日期:{},
周报日期:【】,
输入1:[],
输入2:[]
};
},
/*检索对象的上一个实例*/
_getInst:函数(目标){
试一试{
返回$.data(目标为“mpcalendar”);
}捕获(e){
抛出“此日历缺少实例。”;
}
},
/*将日历附加到目标元素*/
_附件PCalendar:功能(目标、设置){
//检查是否给了我们一个div或span。我们只制作内联日历。
var nodeName=target.nodeName.toLowerCase();
if(nodeName!=(“div”| |“span”))
抛出新错误('Target必须是div或span get“'+nodeName+”);
var self=这个;
var inst=此。_newInst($(目标));
inst.settings=$.extend({},settings{}{
beforeShowDay:功能(日期){
在展示日(仪表、日期)前返回自己;
},
onSelect:函数(日期、日期选择器){
返回自选择(仪表、日期、日期选择器);
}
});
//确保showWeek是真实的。
inst.settings.showWeek=true;
//确保我们有投入使用。
inst.input1=$(inst.element.data('mpinput1');
如果(!inst.input1.length)
抛出新错误('找不到mpinput1');
inst.input2=$(inst.element.data('mpinput2');
如果(!inst.input2.length)
抛出新错误('找不到mpinput2');
//启动在设置中找到的阻止日期。
if(inst.settings.blockDates的类型==“对象”)
此设置锁定日期(inst、inst.settings.blockDates);
//启动设置中的每周费率。
if(inst.settings.weeklyRates的类型==“对象”)
此._setWeeklyRates(inst,inst.settings.weeklyRates);
//启动日期选择器。
inst.element.datepicker(inst.settings);
//绘制额外费率列。
本附件(inst);
//存储我们的实例。
美元。数据(目标,“日历”,inst);
},
/*使用给定的日期列表设置块日期*/
_setBlockDatesMpCalendar:函数(目标、日期){
如果(日期类型!=“对象”)
抛出新错误('预期日期为“对象”改为“+typeof dates+”);
var inst=此。_getInst(目标);
此日期(仪表、日期);
},
/*将给定日期添加到阻止列表中*/
_addBlockDateMpCalendar:函数(目标、日期、状态){
var inst=此。_getInst(目标);
此日期(仪器、日期、状态);
},
/*从阻止列表中删除给定日期*/
_removeBlockDateMpCalendar:函数(目标,日期){
var inst=此。_getInst(目标);
此日期(inst,date);
},
/*使用给定的费率列表设置每周费率*/
_setWeeklyRatesMpCalendar:函数(目标、速率){
if(!(Array.isArray(rates)))
抛出新错误('预期速率为“数组”而不是“+typeof速率+”);
var inst=此。_getInst(目标);
这是一周一次(仪表、费率);
},
/*设定一周的费率*/
_setWeeklyRateMpCalendar:函数(目标、周、速率){
如果(星期类型!=“编号”)
周=parseInt(周);
if(费率类型!=“编号”)
汇率=浮动汇率(汇率);
var inst=此。_getInst(目标);
本周(月、周、费率);
},
/**
*返回包含日历上选定日期的日期对象数组。
*
*@param{object}目标
*@returns{Array}
*/
_getSelectedDatesMpCalendar:函数(目标){
var inst=此。_getInst(目标);
返回此项。\u获取所选日期(inst);
},
/**
*返回用于指定日期的CSS类,如果该日期未被阻止,则返回false。
*
*@param{object}目标
*@param{Date}Date
*@返回{string}
*/
_isBlockedDateMpCalendar:函数(目标、日期){
var inst=此。_getInst(目标);
返回此信息。_isBlockedDate(安装日期);