日付ピッカーとしてjquery.datePicker-2.1.2を使用しています。問題は、過去の日を選択する必要があることですが、カレンダーでは許可されていません。誰もがそこで何を変えるべきか知っていますか?
CSSファイルの関数を削除しようとしましたdisabled
が、過去の日付が利用可能になりましたが、選択できませんでした。
(function($){
$.fn.extend({
renderCalendar : function(s)
{
var dc = function(a)
{
return document.createElement(a);
};
s = $.extend({}, $.fn.datePicker.defaults, s);
if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) {
var headRow = $(dc('tr'));
for (var i=Date.firstDayOfWeek; i<Date.firstDayOfWeek+7; i++) {
var weekday = i%7;
var day = Date.dayNames[weekday];
headRow.append(
jQuery(dc('th')).attr({'scope':'col', 'abbr':day, 'title':day, 'class':(weekday == 0 || weekday == 6 ? 'weekend' : 'weekday')}).html(s.showHeader == $.dpConst.SHOW_HEADER_SHORT ? day.substr(0, 1) : day)
);
}
};
var calendarTable = $(dc('table'))
.attr(
{
'cellspacing':2,
'className':'jCalendar'
}
)
.append(
(s.showHeader != $.dpConst.SHOW_HEADER_NONE ?
$(dc('thead'))
.append(headRow)
:
dc('thead')
)
);
var tbody = $(dc('tbody'));
var today = (new Date()).zeroTime();
var month = s.month == undefined ? today.getMonth() : s.month;
var year = s.year || today.getFullYear();
var currentDate = new Date(year, month, 1);
var firstDayOffset = Date.firstDayOfWeek - currentDate.getDay() + 1;
if (firstDayOffset > 1) firstDayOffset -= 7;
var weeksToDraw = Math.ceil(( (-1*firstDayOffset+1) + currentDate.getDaysInMonth() ) /7);
currentDate.addDays(firstDayOffset-1);
var doHover = function()
{
if (s.hoverClass) {
$(this).addClass(s.hoverClass);
}
};
var unHover = function()
{
if (s.hoverClass) {
$(this).removeClass(s.hoverClass);
}
};
var w = 0;
while (w++<weeksToDraw) {
var r = jQuery(dc('tr'));
for (var i=0; i<7; i++) {
var thisMonth = currentDate.getMonth() == month;
var d = $(dc('td'))
.text(currentDate.getDate() + '')
.attr('className', (thisMonth ? 'current-month ' : 'other-month ') +
(currentDate.isWeekend() ? 'weekend ' : 'weekday ') +
(thisMonth && currentDate.getTime() == today.getTime() ? 'today ' : '')
)
.hover(doHover, unHover)
;
if (s.renderCallback) {
s.renderCallback(d, currentDate, month, year);
}
r.append(d);
currentDate.addDays(1);
}
tbody.append(r);
}
calendarTable.append(tbody);
return this.each(
function()
{
$(this).empty().append(calendarTable);
}
);
},
datePicker : function(s)
{
if (!$.event._dpCache) $.event._dpCache = [];
// initialise the date picker controller with the relevant settings...
s = $.extend({}, $.fn.datePicker.defaults, s);
return this.each(
function()
{
var $this = $(this);
var alreadyExists = true;
if (!this._dpId) {
this._dpId = $.event.guid++;
$.event._dpCache[this._dpId] = new DatePicker(this);
alreadyExists = false;
}
if (s.inline) {
s.createButton = false;
s.displayClose = false;
s.closeOnSelect = false;
$this.empty();
}
var controller = $.event._dpCache[this._dpId];
controller.init(s);
if (!alreadyExists && s.createButton) {
// create it!
controller.button = $($.dpText.TEXT_CHOOSE_DATE)
.bind(
'click',
function()
{
$this.dpDisplay(this);
this.blur();
return false;
}
);
$this.after(controller.button);
}
if (!alreadyExists && $this.is(':text')) {
$this
.bind(
'dateSelected',
function(e, selectedDate, $td)
{
this.value = selectedDate.asString();
}
).bind(
'change',
function()
{
if (this.value != '') {
var d = Date.fromString(this.value);
if (d) {
controller.setSelected(d, true, true);
}
}
}
);
if (s.clickInput) {
$this.bind(
'click',
function()
{
$this.dpDisplay();
}
);
}
var d = Date.fromString(this.value);
if (this.value != '' && d) {
controller.setSelected(d, true, true);
}
}
$this.addClass('dp-applied');
}
)
},
dpSetDisabled : function(s)
{
return _w.call(this, 'setDisabled', s);
},
dpSetStartDate : function(d)
{
return _w.call(this, 'setStartDate', d);
},
dpSetEndDate : function(d)
{
return _w.call(this, 'setEndDate', d);
},
dpGetSelected : function()
{
var c = _getController(this[0]);
if (c) {
return c.getSelected();
}
return null;
},
dpSetSelected : function(d, v, m)
{
if (v == undefined) v=true;
if (m == undefined) m=true;
return _w.call(this, 'setSelected', Date.fromString(d), v, m, true);
},
dpSetDisplayedMonth : function(m, y)
{
return _w.call(this, 'setDisplayedMonth', Number(m), Number(y), true);
},
dpDisplay : function(e)
{
return _w.call(this, 'display', e);
},
dpSetRenderCallback : function(a)
{
return _w.call(this, 'setRenderCallback', a);
},
dpSetPosition : function(v, h)
{
return _w.call(this, 'setPosition', v, h);
},
dpSetOffset : function(v, h)
{
return _w.call(this, 'setOffset', v, h);
},
dpClose : function()
{
return _w.call(this, '_closeCalendar', false, this[0]);
},
// private function called on unload to clean up any expandos etc and prevent memory links...
_dpDestroy : function()
{
// TODO - implement this?
}
});
var _w = function(f, a1, a2, a3, a4)
{
return this.each(
function()
{
var c = _getController(this);
if (c) {
c[f](a1, a2, a3, a4);
}
}
);
};
function DatePicker(ele)
{
this.ele = ele;
// initial values...
this.displayedMonth = null;
this.displayedYear = null;
this.startDate = null;
this.endDate = null;
this.showYearNavigation = null;
this.closeOnSelect = null;
this.displayClose = null;
this.selectMultiple = null;
this.verticalPosition = null;
this.horizontalPosition = null;
this.verticalOffset = null;
this.horizontalOffset = null;
this.button = null;
this.renderCallback = [];
this.selectedDates = {};
this.inline = null;
this.context = '#dp-popup';
};
$.extend(
DatePicker.prototype,
{
init : function(s)
{
this.setStartDate(s.startDate);
this.setEndDate(s.endDate);
this.setDisplayedMonth(Number(s.month), Number(s.year));
this.setRenderCallback(s.renderCallback);
this.showYearNavigation = s.showYearNavigation;
this.closeOnSelect = s.closeOnSelect;
this.displayClose = s.displayClose;
this.selectMultiple = s.selectMultiple;
this.verticalPosition = s.verticalPosition;
this.horizontalPosition = s.horizontalPosition;
this.hoverClass = s.hoverClass;
this.setOffset(s.verticalOffset, s.horizontalOffset);
this.inline = s.inline;
if (this.inline) {
this.context = this.ele;
this.display();
}
},
setStartDate : function(d)
{
if (d) {
this.startDate = Date.fromString(d);
}
if (!this.startDate) {
this.startDate = (new Date()).zeroTime();
}
this.setDisplayedMonth(this.displayedMonth, this.displayedYear);
},
setEndDate : function(d)
{
if (d) {
this.endDate = Date.fromString(d);
}
if (!this.endDate) {
this.endDate = (new Date('12/31/2999')); // using the JS Date.parse function which expects mm/dd/yyyy
}
if (this.endDate.getTime() < this.startDate.getTime()) {
this.endDate = this.startDate;
}
this.setDisplayedMonth(this.displayedMonth, this.displayedYear);
},
setPosition : function(v, h)
{
this.verticalPosition = v;
this.horizontalPosition = h;
},
setOffset : function(v, h)
{
this.verticalOffset = parseInt(v) || 0;
this.horizontalOffset = parseInt(h) || 0;
},
setDisabled : function(s)
{
$e = $(this.ele);
$e[s ? 'addClass' : 'removeClass']('dp-disabled');
if (this.button) {
$but = $(this.button);
$but[s ? 'addClass' : 'removeClass']('dp-disabled');
$but.attr('title', s ? '' : $.dpText.TEXT_CHOOSE_DATE);
}
if ($e.is(':text')) {
$e.attr('disabled', s ? 'disabled' : '');
}
},
setDisplayedMonth : function(m, y, rerender)
{
if (this.startDate == undefined || this.endDate == undefined) {
return;
}
var s = new Date(this.startDate.getTime());
s.setDate(1);
var e = new Date(this.endDate.getTime());
e.setDate(1);
var t;
if ((!m && !y) || (isNaN(m) && isNaN(y))) {
// no month or year passed - default to current month
t = new Date().zeroTime();
t.setDate(1);
} else if (isNaN(m)) {
// just year passed in - presume we want the displayedMonth
t = new Date(y, this.displayedMonth, 1);
} else if (isNaN(y)) {
// just month passed in - presume we want the displayedYear
t = new Date(this.displayedYear, m, 1);
} else {
// year and month passed in - that's the date we want!
t = new Date(y, m, 1)
}
// check if the desired date is within the range of our defined startDate and endDate
if (t.getTime() < s.getTime()) {
t = s;
} else if (t.getTime() > e.getTime()) {
t = e;
}
var oldMonth = this.displayedMonth;
var oldYear = this.displayedYear;
this.displayedMonth = t.getMonth();
this.displayedYear = t.getFullYear();
if (rerender && (this.displayedMonth != oldMonth || this.displayedYear != oldYear))
{
this._rerenderCalendar();
$(this.ele).trigger('dpMonthChanged', [this.displayedMonth, this.displayedYear]);
}
},
setSelected : function(d, v, moveToMonth, dispatchEvents)
{
if (v == this.isSelected(d)) // this date is already un/selected
{
return;
}
if (this.selectMultiple == false) {
this.selectedDates = {};
$('td.selected', this.context).removeClass('selected');
}
if (moveToMonth && this.displayedMonth != d.getMonth()) {
this.setDisplayedMonth(d.getMonth(), d.getFullYear(), true);
}
this.selectedDates[d.toString()] = v;
var selectorString = 'td.';
selectorString += d.getMonth() == this.displayedMonth ? 'current-month' : 'other-month';
selectorString += ':contains("' + d.getDate() + '")';
var $td;
$(selectorString, this.ele).each(
function()
{
if ($(this).text() == d.getDate())
{
$td = $(this);
$td[v ? 'addClass' : 'removeClass']('selected');
}
}
);
if (dispatchEvents)
{
var s = this.isSelected(d);
$e = $(this.ele);
$e.trigger('dateSelected', [d, $td, s]);
$e.trigger('change');
}
},
isSelected : function(d)
{
return this.selectedDates[d.toString()];
},
getSelected : function()
{
var r = [];
for(s in this.selectedDates) {
if (this.selectedDates[s] == true) {
r.push(Date.parse(s));
}
}
return r;
},
display : function(eleAlignTo)
{
if ($(this.ele).is('.dp-disabled')) return;
eleAlignTo = eleAlignTo || this.ele;
var c = this;
var $ele = $(eleAlignTo);
var eleOffset = $ele.offset();
var $createIn;
var attrs;
var attrsCalendarHolder;
var cssRules;
if (c.inline) {
$createIn = $(this.ele);
attrs = {
'id' : 'calendar-' + this.ele._dpId,
'className' : 'dp-popup dp-popup-inline'
};
cssRules = {
};
} else {
$createIn = $('body');
attrs = {
'id' : 'dp-popup',
'className' : 'dp-popup'
};
cssRules = {
'top' : eleOffset.top + c.verticalOffset,
'left' : eleOffset.left + c.horizontalOffset
};
var _checkMouse = function(e)
{
var el = e.target;
var cal = $('#dp-popup')[0];
while (true){
if (el == cal) {
return true;
} else if (el == document) {
c._closeCalendar();
return false;
} else {
el = $(el).parent()[0];
}
}
};
this._checkMouse = _checkMouse;
this._closeCalendar(true);
}
$createIn
.append(
$('<div></div>')
.attr(attrs)
.css(cssRules)
.append(
$('<h2></h2>'),
$('<div class="dp-nav-prev"></div>')
.append(
$('<a class="dp-nav-prev-year" href="#" title="' + $.dpText.TEXT_PREV_YEAR + '"><<</a>')
.bind(
'click',
function()
{
return c._displayNewMonth.call(c, this, 0, -1);
}
),
$('<a class="dp-nav-prev-month" href="#" title="' + $.dpText.TEXT_PREV_MONTH + '"><</a>')
.bind(
'click',
function()
{
return c._displayNewMonth.call(c, this, -1, 0);
}
)
),
$('<div class="dp-nav-next"></div>')
.append(
$('<a class="dp-nav-next-year" href="#" title="' + $.dpText.TEXT_NEXT_YEAR + '">>></a>')
.bind(
'click',
function()
{
return c._displayNewMonth.call(c, this, 0, 1);
}
),
$('<a class="dp-nav-next-month" href="#" title="' + $.dpText.TEXT_NEXT_MONTH + '">></a>')
.bind(
'click',
function()
{
return c._displayNewMonth.call(c, this, 1, 0);
}
)
),
$('<div></div>')
.attr('className', 'dp-calendar')
)
.bgIframe()
);
var $pop = this.inline ? $('.dp-popup', this.context) : $('#dp-popup');
if (this.showYearNavigation == false) {
$('.dp-nav-prev-year, .dp-nav-next-year', c.context).css('display', 'none');
}
if (this.displayClose) {
$pop.append(
$('<a href="#" id="dp-close">' + $.dpText.TEXT_CLOSE + '</a>')
.bind(
'click',
function()
{
c._closeCalendar();
return false;
}
)
);
}
c._renderCalendar();
$(this.ele).trigger('dpDisplayed', $pop);
if (!c.inline) {
if (this.verticalPosition == $.dpConst.POS_BOTTOM) {
$pop.css('top', eleOffset.top + $ele.height() - $pop.height() + c.verticalOffset);
}
if (this.horizontalPosition == $.dpConst.POS_RIGHT) {
$pop.css('left', eleOffset.left + $ele.width() - $pop.width() + c.horizontalOffset);
}
$(document).bind('mousedown', this._checkMouse);
}
},
setRenderCallback : function(a)
{
if (a == null) return;
if (a && typeof(a) == 'function') {
a = [a];
}
this.renderCallback = this.renderCallback.concat(a);
},
cellRender : function ($td, thisDate, month, year) {
var c = this.dpController;
var d = new Date(thisDate.getTime());
// add our click handlers to deal with it when the days are clicked...
$td.bind(
'click',
function()
{
var $this = $(this);
if (!$this.is('.disabled')) {
c.setSelected(d, !$this.is('.selected') || !c.selectMultiple, false, true);
if (c.closeOnSelect) {
c._closeCalendar();
}
}
}
);
if (c.isSelected(d)) {
$td.addClass('selected');
}
// call any extra renderCallbacks that were passed in
for (var i=0; i<c.renderCallback.length; i++) {
c.renderCallback[i].apply(this, arguments);
}
},
// ele is the clicked button - only proceed if it doesn't have the class disabled...
// m and y are -1, 0 or 1 depending which direction we want to go in...
_displayNewMonth : function(ele, m, y)
{
if (!$(ele).is('.disabled')) {
this.setDisplayedMonth(this.displayedMonth + m, this.displayedYear + y, true);
}
ele.blur();
return false;
},
_rerenderCalendar : function()
{
this._clearCalendar();
this._renderCalendar();
},
_renderCalendar : function()
{
// set the title...
$('h2', this.context).html(Date.monthNames[this.displayedMonth] + ' ' + this.displayedYear);
// render the calendar...
$('.dp-calendar', this.context).renderCalendar(
{
month : this.displayedMonth,
year : this.displayedYear,
renderCallback : this.cellRender,
dpController : this,
hoverClass : this.hoverClass
}
);
// update the status of the control buttons and disable dates before startDate or after endDate...
// TODO: When should the year buttons be disabled? When you can't go forward a whole year from where you are or is that annoying?
if (this.displayedYear == this.startDate.getFullYear() && this.displayedMonth == this.startDate.getMonth()) {
$('.dp-nav-prev-year', this.context).addClass('disabled');
$('.dp-nav-prev-month', this.context).addClass('disabled');
$('.dp-calendar td.other-month', this.context).each(
function()
{
var $this = $(this);
if (Number($this.text()) > 20) {
$this.addClass('disabled');
}
}
);
var d = this.startDate.getDate();
$('.dp-calendar td.current-month', this.context).each(
function()
{
var $this = $(this);
if (Number($this.text()) < d) {
$this.addClass('disabled');
}
}
);
} else {
$('.dp-nav-prev-year', this.context).removeClass('disabled');
$('.dp-nav-prev-month', this.context).removeClass('disabled');
var d = this.startDate.getDate();
if (d > 20) {
// check if the startDate is last month as we might need to add some disabled classes...
var sd = new Date(this.startDate.getTime());
sd.addMonths(1);
if (this.displayedYear == sd.getFullYear() && this.displayedMonth == sd.getMonth()) {
$('dp-calendar td.other-month', this.context).each(
function()
{
var $this = $(this);
if (Number($this.text()) < d) {
$this.addClass('disabled');
}
}
);
}
}
}
if (this.displayedYear == this.endDate.getFullYear() && this.displayedMonth == this.endDate.getMonth()) {
$('.dp-nav-next-year', this.context).addClass('disabled');
$('.dp-nav-next-month', this.context).addClass('disabled');
$('.dp-calendar td.other-month', this.context).each(
function()
{
var $this = $(this);
if (Number($this.text()) < 14) {
$this.addClass('disabled');
}
}
);
var d = this.endDate.getDate();
$('.dp-calendar td.current-month', this.context).each(
function()
{
var $this = $(this);
if (Number($this.text()) > d) {
$this.addClass('disabled');
}
}
);
} else {
$('.dp-nav-next-year', this.context).removeClass('disabled');
$('.dp-nav-next-month', this.context).removeClass('disabled');
var d = this.endDate.getDate();
if (d < 13) {
// check if the endDate is next month as we might need to add some disabled classes...
var ed = new Date(this.endDate.getTime());
ed.addMonths(-1);
if (this.displayedYear == ed.getFullYear() && this.displayedMonth == ed.getMonth()) {
$('.dp-calendar td.other-month', this.context).each(
function()
{
var $this = $(this);
if (Number($this.text()) > d) {
$this.addClass('disabled');
}
}
);
}
}
}
},
_closeCalendar : function(programatic, ele)
{
if (!ele || ele == this.ele)
{
$(document).unbind('mousedown', this._checkMouse);
this._clearCalendar();
$('#dp-popup a').unbind();
$('#dp-popup').empty().remove();
if (!programatic) {
$(this.ele).trigger('dpClosed', [this.getSelected()]);
}
}
},
// empties the current dp-calendar div and makes sure that all events are unbound
// and expandos removed to avoid memory leaks...
_clearCalendar : function()
{
// TODO.
$('.dp-calendar td', this.context).unbind();
$('.dp-calendar', this.context).empty();
}
}
);
// static constants
$.dpConst = {
SHOW_HEADER_NONE : 0,
SHOW_HEADER_SHORT : 1,
SHOW_HEADER_LONG : 2,
POS_TOP : 0,
POS_BOTTOM : 1,
POS_LEFT : 0,
POS_RIGHT : 1
};
// localisable text
$.dpText = {
TEXT_PREV_YEAR : 'Предыдущий год',
TEXT_PREV_MONTH : 'Предыдущий месяц',
TEXT_NEXT_YEAR : 'Следующий год',
TEXT_NEXT_MONTH : 'Следующий месяц',
TEXT_CLOSE : 'Закрыть',
TEXT_CHOOSE_DATE : '<p><u>выбрать дату</u></p>'
};
// version
$.dpVersion = '$Id: jquery.datePicker.js 15 2008-12-17 04:40:18Z kelvin.luck $';
$.fn.datePicker.defaults = {
month : undefined,
year : undefined,
showHeader : $.dpConst.SHOW_HEADER_SHORT,
startDate : undefined,
endDate : undefined,
inline : false,
renderCallback : null,
createButton : true,
showYearNavigation : true,
closeOnSelect : true,
displayClose : false,
selectMultiple : false,
clickInput : false,
verticalPosition : $.dpConst.POS_TOP,
horizontalPosition : $.dpConst.POS_LEFT,
verticalOffset : 0,
horizontalOffset : 0,
hoverClass : 'dp-hover'
};
function _getController(ele)
{
if (ele._dpId) return $.event._dpCache[ele._dpId];
return false;
};
// make it so that no error is thrown if bgIframe plugin isn't included (allows you to use conditional
// comments to only include bgIframe where it is needed in IE without breaking this plugin).
if ($.fn.bgIframe == undefined) {
$.fn.bgIframe = function() {return this; };
};
// clean-up
$(window)
.bind('unload', function() {
var els = $.event._dpCache || [];
for (var i in els) {
$(els[i].ele)._dpDestroy();
}
});
})(jQuery);