897 lines
33 KiB
JavaScript
897 lines
33 KiB
JavaScript
/*
|
|
|
|
Jappix - An open social platform
|
|
These are the datepicker JS script
|
|
|
|
-------------------------------------------------
|
|
|
|
Licenses: MIT, GPL, AGPL
|
|
Authors: Stefan Petre, Vanaryon
|
|
Last revision: 19/12/10
|
|
|
|
*/
|
|
|
|
(function ($) {
|
|
var DatePicker = function () {
|
|
var ids = {},
|
|
views = {
|
|
years: 'datepickerViewYears',
|
|
moths: 'datepickerViewMonths',
|
|
days: 'datepickerViewDays'
|
|
},
|
|
tpl = {
|
|
wrapper: '<div class="datepicker"><div class="datepickerBorderT" /><div class="datepickerBorderB" /><div class="datepickerBorderL" /><div class="datepickerBorderR" /><div class="datepickerBorderTL" /><div class="datepickerBorderTR" /><div class="datepickerBorderBL" /><div class="datepickerBorderBR" /><div class="datepickerContainer"><table cellspacing="0" cellpadding="0"><tbody><tr></tr></tbody></table></div></div>',
|
|
head: [
|
|
'<td>',
|
|
'<table cellspacing="0" cellpadding="0">',
|
|
'<thead>',
|
|
'<tr>',
|
|
'<th class="datepickerGoPrev"><a href="#"><span><%=prev%></span></a></th>',
|
|
'<th colspan="6" class="datepickerMonth"><a href="#"><span></span></a></th>',
|
|
'<th class="datepickerGoNext"><a href="#"><span><%=next%></span></a></th>',
|
|
'</tr>',
|
|
'<tr class="datepickerDoW">',
|
|
'<th><span><%=week%></span></th>',
|
|
'<th><span><%=day1%></span></th>',
|
|
'<th><span><%=day2%></span></th>',
|
|
'<th><span><%=day3%></span></th>',
|
|
'<th><span><%=day4%></span></th>',
|
|
'<th><span><%=day5%></span></th>',
|
|
'<th><span><%=day6%></span></th>',
|
|
'<th><span><%=day7%></span></th>',
|
|
'</tr>',
|
|
'</thead>',
|
|
'</table></td>'
|
|
],
|
|
space : '<td class="datepickerSpace"><div></div></td>',
|
|
days: [
|
|
'<tbody class="datepickerDays">',
|
|
'<tr>',
|
|
'<th class="datepickerWeek"><a href="#"><span><%=weeks[0].week%></span></a></th>',
|
|
'<td class="<%=weeks[0].days[0].classname%>"><a href="#"><span><%=weeks[0].days[0].text%></span></a></td>',
|
|
'<td class="<%=weeks[0].days[1].classname%>"><a href="#"><span><%=weeks[0].days[1].text%></span></a></td>',
|
|
'<td class="<%=weeks[0].days[2].classname%>"><a href="#"><span><%=weeks[0].days[2].text%></span></a></td>',
|
|
'<td class="<%=weeks[0].days[3].classname%>"><a href="#"><span><%=weeks[0].days[3].text%></span></a></td>',
|
|
'<td class="<%=weeks[0].days[4].classname%>"><a href="#"><span><%=weeks[0].days[4].text%></span></a></td>',
|
|
'<td class="<%=weeks[0].days[5].classname%>"><a href="#"><span><%=weeks[0].days[5].text%></span></a></td>',
|
|
'<td class="<%=weeks[0].days[6].classname%>"><a href="#"><span><%=weeks[0].days[6].text%></span></a></td>',
|
|
'</tr>',
|
|
'<tr>',
|
|
'<th class="datepickerWeek"><a href="#"><span><%=weeks[1].week%></span></a></th>',
|
|
'<td class="<%=weeks[1].days[0].classname%>"><a href="#"><span><%=weeks[1].days[0].text%></span></a></td>',
|
|
'<td class="<%=weeks[1].days[1].classname%>"><a href="#"><span><%=weeks[1].days[1].text%></span></a></td>',
|
|
'<td class="<%=weeks[1].days[2].classname%>"><a href="#"><span><%=weeks[1].days[2].text%></span></a></td>',
|
|
'<td class="<%=weeks[1].days[3].classname%>"><a href="#"><span><%=weeks[1].days[3].text%></span></a></td>',
|
|
'<td class="<%=weeks[1].days[4].classname%>"><a href="#"><span><%=weeks[1].days[4].text%></span></a></td>',
|
|
'<td class="<%=weeks[1].days[5].classname%>"><a href="#"><span><%=weeks[1].days[5].text%></span></a></td>',
|
|
'<td class="<%=weeks[1].days[6].classname%>"><a href="#"><span><%=weeks[1].days[6].text%></span></a></td>',
|
|
'</tr>',
|
|
'<tr>',
|
|
'<th class="datepickerWeek"><a href="#"><span><%=weeks[2].week%></span></a></th>',
|
|
'<td class="<%=weeks[2].days[0].classname%>"><a href="#"><span><%=weeks[2].days[0].text%></span></a></td>',
|
|
'<td class="<%=weeks[2].days[1].classname%>"><a href="#"><span><%=weeks[2].days[1].text%></span></a></td>',
|
|
'<td class="<%=weeks[2].days[2].classname%>"><a href="#"><span><%=weeks[2].days[2].text%></span></a></td>',
|
|
'<td class="<%=weeks[2].days[3].classname%>"><a href="#"><span><%=weeks[2].days[3].text%></span></a></td>',
|
|
'<td class="<%=weeks[2].days[4].classname%>"><a href="#"><span><%=weeks[2].days[4].text%></span></a></td>',
|
|
'<td class="<%=weeks[2].days[5].classname%>"><a href="#"><span><%=weeks[2].days[5].text%></span></a></td>',
|
|
'<td class="<%=weeks[2].days[6].classname%>"><a href="#"><span><%=weeks[2].days[6].text%></span></a></td>',
|
|
'</tr>',
|
|
'<tr>',
|
|
'<th class="datepickerWeek"><a href="#"><span><%=weeks[3].week%></span></a></th>',
|
|
'<td class="<%=weeks[3].days[0].classname%>"><a href="#"><span><%=weeks[3].days[0].text%></span></a></td>',
|
|
'<td class="<%=weeks[3].days[1].classname%>"><a href="#"><span><%=weeks[3].days[1].text%></span></a></td>',
|
|
'<td class="<%=weeks[3].days[2].classname%>"><a href="#"><span><%=weeks[3].days[2].text%></span></a></td>',
|
|
'<td class="<%=weeks[3].days[3].classname%>"><a href="#"><span><%=weeks[3].days[3].text%></span></a></td>',
|
|
'<td class="<%=weeks[3].days[4].classname%>"><a href="#"><span><%=weeks[3].days[4].text%></span></a></td>',
|
|
'<td class="<%=weeks[3].days[5].classname%>"><a href="#"><span><%=weeks[3].days[5].text%></span></a></td>',
|
|
'<td class="<%=weeks[3].days[6].classname%>"><a href="#"><span><%=weeks[3].days[6].text%></span></a></td>',
|
|
'</tr>',
|
|
'<tr>',
|
|
'<th class="datepickerWeek"><a href="#"><span><%=weeks[4].week%></span></a></th>',
|
|
'<td class="<%=weeks[4].days[0].classname%>"><a href="#"><span><%=weeks[4].days[0].text%></span></a></td>',
|
|
'<td class="<%=weeks[4].days[1].classname%>"><a href="#"><span><%=weeks[4].days[1].text%></span></a></td>',
|
|
'<td class="<%=weeks[4].days[2].classname%>"><a href="#"><span><%=weeks[4].days[2].text%></span></a></td>',
|
|
'<td class="<%=weeks[4].days[3].classname%>"><a href="#"><span><%=weeks[4].days[3].text%></span></a></td>',
|
|
'<td class="<%=weeks[4].days[4].classname%>"><a href="#"><span><%=weeks[4].days[4].text%></span></a></td>',
|
|
'<td class="<%=weeks[4].days[5].classname%>"><a href="#"><span><%=weeks[4].days[5].text%></span></a></td>',
|
|
'<td class="<%=weeks[4].days[6].classname%>"><a href="#"><span><%=weeks[4].days[6].text%></span></a></td>',
|
|
'</tr>',
|
|
'<tr>',
|
|
'<th class="datepickerWeek"><a href="#"><span><%=weeks[5].week%></span></a></th>',
|
|
'<td class="<%=weeks[5].days[0].classname%>"><a href="#"><span><%=weeks[5].days[0].text%></span></a></td>',
|
|
'<td class="<%=weeks[5].days[1].classname%>"><a href="#"><span><%=weeks[5].days[1].text%></span></a></td>',
|
|
'<td class="<%=weeks[5].days[2].classname%>"><a href="#"><span><%=weeks[5].days[2].text%></span></a></td>',
|
|
'<td class="<%=weeks[5].days[3].classname%>"><a href="#"><span><%=weeks[5].days[3].text%></span></a></td>',
|
|
'<td class="<%=weeks[5].days[4].classname%>"><a href="#"><span><%=weeks[5].days[4].text%></span></a></td>',
|
|
'<td class="<%=weeks[5].days[5].classname%>"><a href="#"><span><%=weeks[5].days[5].text%></span></a></td>',
|
|
'<td class="<%=weeks[5].days[6].classname%>"><a href="#"><span><%=weeks[5].days[6].text%></span></a></td>',
|
|
'</tr>',
|
|
'</tbody>'
|
|
],
|
|
months: [
|
|
'<tbody class="<%=className%>">',
|
|
'<tr>',
|
|
'<td colspan="2"><a href="#"><span><%=data[0]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[1]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[2]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[3]%></span></a></td>',
|
|
'</tr>',
|
|
'<tr>',
|
|
'<td colspan="2"><a href="#"><span><%=data[4]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[5]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[6]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[7]%></span></a></td>',
|
|
'</tr>',
|
|
'<tr>',
|
|
'<td colspan="2"><a href="#"><span><%=data[8]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[9]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[10]%></span></a></td>',
|
|
'<td colspan="2"><a href="#"><span><%=data[11]%></span></a></td>',
|
|
'</tr>',
|
|
'</tbody>'
|
|
]
|
|
},
|
|
defaults = {
|
|
flat: false,
|
|
starts: 1,
|
|
prev: '◀',
|
|
next: '▶',
|
|
lastSel: false,
|
|
mode: 'single',
|
|
view: 'days',
|
|
calendars: 1,
|
|
format: 'Y-m-d',
|
|
position: 'bottom',
|
|
eventName: 'click',
|
|
onRender: function(){return {};},
|
|
onChange: function(){return true;},
|
|
onShow: function(){return true;},
|
|
onBeforeShow: function(){return true;},
|
|
onHide: function(){return true;},
|
|
locale: {
|
|
days: [_e("Sunday"), _e("Monday"), _e("Tuesday"), _e("Wednesday"), _e("Thursday"), _e("Friday"), _e("Saturday"), _e("Sunday")],
|
|
daysShort: [cut(_e("Sunday"), 3), cut(_e("Monday"), 3), cut(_e("Tuesday"), 3), cut(_e("Wednesday"), 3), cut(_e("Thursday"), 3), cut(_e("Friday"), 3), cut(_e("Saturday"), 3), cut(_e("Sunday"), 3)],
|
|
daysMin: [cut(_e("Sunday"), 2), cut(_e("Monday"), 2), cut(_e("Tuesday"), 2), cut(_e("Wednesday"), 2), cut(_e("Thursday"), 2), cut(_e("Friday"), 2), cut(_e("Saturday"), 2), cut(_e("Sunday"), 2)],
|
|
months: [_e("January"), _e("February"), _e("March"), _e("April"), _e("May"), _e("June"), _e("July"), _e("August"), _e("September"), _e("October"), _e("November"), _e("December")],
|
|
monthsShort: [cut(_e("January"), 3), cut(_e("February"), 3), cut(_e("March"), 3), cut(_e("April"), 3), cut(_e("May"), 3), cut(_e("June"), 3), cut(_e("July"), 3), cut(_e("August"), 3), cut(_e("September"), 3), cut(_e("October"), 3), cut(_e("November"), 3), cut(_e("December"), 3)],
|
|
weekMin: ''
|
|
}
|
|
},
|
|
fill = function(el) {
|
|
var options = $(el).data('datepicker');
|
|
var cal = $(el);
|
|
var currentCal = Math.floor(options.calendars/2), date, data, dow, month, cnt = 0, week, days, indic, indic2, html, tblCal;
|
|
cal.find('td>table tbody').remove();
|
|
for (var i = 0; i < options.calendars; i++) {
|
|
date = new Date(options.current);
|
|
date.addMonths(-currentCal + i);
|
|
tblCal = cal.find('table').eq(i+1);
|
|
switch (tblCal[0].className) {
|
|
case 'datepickerViewDays':
|
|
dow = formatDate(date, 'B, Y');
|
|
break;
|
|
case 'datepickerViewMonths':
|
|
dow = date.getFullYear();
|
|
break;
|
|
case 'datepickerViewYears':
|
|
dow = (date.getFullYear()-6) + ' - ' + (date.getFullYear()+5);
|
|
break;
|
|
}
|
|
tblCal.find('thead tr:first th:eq(1) span').text(dow);
|
|
dow = date.getFullYear()-6;
|
|
data = {
|
|
data: [],
|
|
className: 'datepickerYears'
|
|
}
|
|
for ( var j = 0; j < 12; j++) {
|
|
data.data.push(dow + j);
|
|
}
|
|
html = tmpl(tpl.months.join(''), data);
|
|
date.setDate(1);
|
|
data = {weeks:[], test: 10};
|
|
month = date.getMonth();
|
|
var dow = (date.getDay() - options.starts) % 7;
|
|
date.addDays(-(dow + (dow < 0 ? 7 : 0)));
|
|
week = -1;
|
|
cnt = 0;
|
|
while (cnt < 42) {
|
|
indic = parseInt(cnt/7,10);
|
|
indic2 = cnt%7;
|
|
if (!data.weeks[indic]) {
|
|
week = date.getWeekNumber();
|
|
data.weeks[indic] = {
|
|
week: week,
|
|
days: []
|
|
};
|
|
}
|
|
data.weeks[indic].days[indic2] = {
|
|
text: date.getDate(),
|
|
classname: []
|
|
};
|
|
if (month != date.getMonth()) {
|
|
data.weeks[indic].days[indic2].classname.push('datepickerNotInMonth');
|
|
}
|
|
if (date.getDay() == 0) {
|
|
data.weeks[indic].days[indic2].classname.push('datepickerSunday');
|
|
}
|
|
if (date.getDay() == 6) {
|
|
data.weeks[indic].days[indic2].classname.push('datepickerSaturday');
|
|
}
|
|
var fromUser = options.onRender(date);
|
|
var val = date.valueOf();
|
|
if (fromUser.selected || options.date == val || $.inArray(val, options.date) > -1 || (options.mode == 'range' && val >= options.date[0] && val <= options.date[1])) {
|
|
data.weeks[indic].days[indic2].classname.push('datepickerSelected');
|
|
}
|
|
if (fromUser.disabled) {
|
|
data.weeks[indic].days[indic2].classname.push('datepickerDisabled');
|
|
}
|
|
if (fromUser.className) {
|
|
data.weeks[indic].days[indic2].classname.push(fromUser.className);
|
|
}
|
|
data.weeks[indic].days[indic2].classname = data.weeks[indic].days[indic2].classname.join(' ');
|
|
cnt++;
|
|
date.addDays(1);
|
|
}
|
|
html = tmpl(tpl.days.join(''), data) + html;
|
|
data = {
|
|
data: options.locale.monthsShort,
|
|
className: 'datepickerMonths'
|
|
};
|
|
html = tmpl(tpl.months.join(''), data) + html;
|
|
tblCal.append(html);
|
|
}
|
|
},
|
|
parseDate = function (date, format) {
|
|
if (date.constructor == Date) {
|
|
return new Date(date);
|
|
}
|
|
var parts = date.split(/\W+/);
|
|
var against = format.split(/\W+/), d, m, y, h, min, now = new Date();
|
|
for (var i = 0; i < parts.length; i++) {
|
|
switch (against[i]) {
|
|
case 'd':
|
|
case 'e':
|
|
d = parseInt(parts[i],10);
|
|
break;
|
|
case 'm':
|
|
m = parseInt(parts[i], 10)-1;
|
|
break;
|
|
case 'Y':
|
|
case 'y':
|
|
y = parseInt(parts[i], 10);
|
|
y += y > 100 ? 0 : (y < 29 ? 2000 : 1900);
|
|
break;
|
|
case 'H':
|
|
case 'I':
|
|
case 'k':
|
|
case 'l':
|
|
h = parseInt(parts[i], 10);
|
|
break;
|
|
case 'P':
|
|
case 'p':
|
|
if (/pm/i.test(parts[i]) && h < 12) {
|
|
h += 12;
|
|
} else if (/am/i.test(parts[i]) && h >= 12) {
|
|
h -= 12;
|
|
}
|
|
break;
|
|
case 'M':
|
|
min = parseInt(parts[i], 10);
|
|
break;
|
|
}
|
|
}
|
|
return new Date(
|
|
y === undefined ? now.getFullYear() : y,
|
|
m === undefined ? now.getMonth() : m,
|
|
d === undefined ? now.getDate() : d,
|
|
h === undefined ? now.getHours() : h,
|
|
min === undefined ? now.getMinutes() : min,
|
|
0
|
|
);
|
|
},
|
|
formatDate = function(date, format) {
|
|
var m = date.getMonth();
|
|
var d = date.getDate();
|
|
var y = date.getFullYear();
|
|
var wn = date.getWeekNumber();
|
|
var w = date.getDay();
|
|
var s = {};
|
|
var hr = date.getHours();
|
|
var pm = (hr >= 12);
|
|
var ir = (pm) ? (hr - 12) : hr;
|
|
var dy = date.getDayOfYear();
|
|
if (ir == 0) {
|
|
ir = 12;
|
|
}
|
|
var min = date.getMinutes();
|
|
var sec = date.getSeconds();
|
|
var parts = format.split(''), part;
|
|
for ( var i = 0; i < parts.length; i++ ) {
|
|
part = parts[i];
|
|
switch (parts[i]) {
|
|
case 'a':
|
|
part = date.getDayName();
|
|
break;
|
|
case 'A':
|
|
part = date.getDayName(true);
|
|
break;
|
|
case 'b':
|
|
part = date.getMonthName();
|
|
break;
|
|
case 'B':
|
|
part = date.getMonthName(true);
|
|
break;
|
|
case 'C':
|
|
part = 1 + Math.floor(y / 100);
|
|
break;
|
|
case 'd':
|
|
part = (d < 10) ? ("0" + d) : d;
|
|
break;
|
|
case 'e':
|
|
part = d;
|
|
break;
|
|
case 'H':
|
|
part = (hr < 10) ? ("0" + hr) : hr;
|
|
break;
|
|
case 'I':
|
|
part = (ir < 10) ? ("0" + ir) : ir;
|
|
break;
|
|
case 'j':
|
|
part = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy;
|
|
break;
|
|
case 'k':
|
|
part = hr;
|
|
break;
|
|
case 'l':
|
|
part = ir;
|
|
break;
|
|
case 'm':
|
|
part = (m < 9) ? ("0" + (1+m)) : (1+m);
|
|
break;
|
|
case 'M':
|
|
part = (min < 10) ? ("0" + min) : min;
|
|
break;
|
|
case 'p':
|
|
case 'P':
|
|
part = pm ? "PM" : "AM";
|
|
break;
|
|
case 's':
|
|
part = Math.floor(date.getTime() / 1000);
|
|
break;
|
|
case 'S':
|
|
part = (sec < 10) ? ("0" + sec) : sec;
|
|
break;
|
|
case 'u':
|
|
part = w + 1;
|
|
break;
|
|
case 'w':
|
|
part = w;
|
|
break;
|
|
case 'y':
|
|
part = ('' + y).substr(2, 2);
|
|
break;
|
|
case 'Y':
|
|
part = y;
|
|
break;
|
|
}
|
|
parts[i] = part;
|
|
}
|
|
return parts.join('');
|
|
},
|
|
extendDate = function(options) {
|
|
if (Date.prototype.tempDate) {
|
|
return;
|
|
}
|
|
Date.prototype.tempDate = null;
|
|
Date.prototype.months = options.months;
|
|
Date.prototype.monthsShort = options.monthsShort;
|
|
Date.prototype.days = options.days;
|
|
Date.prototype.daysShort = options.daysShort;
|
|
Date.prototype.getMonthName = function(fullName) {
|
|
return this[fullName ? 'months' : 'monthsShort'][this.getMonth()];
|
|
};
|
|
Date.prototype.getDayName = function(fullName) {
|
|
return this[fullName ? 'days' : 'daysShort'][this.getDay()];
|
|
};
|
|
Date.prototype.addDays = function (n) {
|
|
this.setDate(this.getDate() + n);
|
|
this.tempDate = this.getDate();
|
|
};
|
|
Date.prototype.addMonths = function (n) {
|
|
if (this.tempDate == null) {
|
|
this.tempDate = this.getDate();
|
|
}
|
|
this.setDate(1);
|
|
this.setMonth(this.getMonth() + n);
|
|
this.setDate(Math.min(this.tempDate, this.getMaxDays()));
|
|
};
|
|
Date.prototype.addYears = function (n) {
|
|
if (this.tempDate == null) {
|
|
this.tempDate = this.getDate();
|
|
}
|
|
this.setDate(1);
|
|
this.setFullYear(this.getFullYear() + n);
|
|
this.setDate(Math.min(this.tempDate, this.getMaxDays()));
|
|
};
|
|
Date.prototype.getMaxDays = function() {
|
|
var tmpDate = new Date(Date.parse(this)),
|
|
d = 28, m;
|
|
m = tmpDate.getMonth();
|
|
d = 28;
|
|
while (tmpDate.getMonth() == m) {
|
|
d ++;
|
|
tmpDate.setDate(d);
|
|
}
|
|
return d - 1;
|
|
};
|
|
Date.prototype.getFirstDay = function() {
|
|
var tmpDate = new Date(Date.parse(this));
|
|
tmpDate.setDate(1);
|
|
return tmpDate.getDay();
|
|
};
|
|
Date.prototype.getWeekNumber = function() {
|
|
var tempDate = new Date(this);
|
|
tempDate.setDate(tempDate.getDate() - (tempDate.getDay() + 6) % 7 + 3);
|
|
var dms = tempDate.valueOf();
|
|
tempDate.setMonth(0);
|
|
tempDate.setDate(4);
|
|
return Math.round((dms - tempDate.valueOf()) / (604800000)) + 1;
|
|
};
|
|
Date.prototype.getDayOfYear = function() {
|
|
var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
|
|
var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
|
|
var time = now - then;
|
|
return Math.floor(time / 24*60*60*1000);
|
|
};
|
|
},
|
|
layout = function (el) {
|
|
var options = $(el).data('datepicker');
|
|
var cal = $('#' + options.id);
|
|
if (!options.extraHeight) {
|
|
var divs = $(el).find('div');
|
|
options.extraHeight = divs.get(0).offsetHeight + divs.get(1).offsetHeight;
|
|
options.extraWidth = divs.get(2).offsetWidth + divs.get(3).offsetWidth;
|
|
}
|
|
var tbl = cal.find('table:first').get(0);
|
|
var width = tbl.offsetWidth;
|
|
var height = tbl.offsetHeight;
|
|
cal.css({
|
|
width: width + options.extraWidth + 'px',
|
|
height: height + options.extraHeight + 'px'
|
|
}).find('div.datepickerContainer').css({
|
|
width: width + 'px',
|
|
height: height + 'px'
|
|
});
|
|
},
|
|
click = function(ev) {
|
|
if ($(ev.target).is('span')) {
|
|
ev.target = ev.target.parentNode;
|
|
}
|
|
var el = $(ev.target);
|
|
if (el.is('a')) {
|
|
ev.target.blur();
|
|
if (el.hasClass('datepickerDisabled')) {
|
|
return false;
|
|
}
|
|
var options = $(this).data('datepicker');
|
|
var parentEl = el.parent();
|
|
var tblEl = parentEl.parent().parent().parent();
|
|
var tblIndex = $('table', this).index(tblEl.get(0)) - 1;
|
|
var tmp = new Date(options.current);
|
|
var changed = false;
|
|
var fillIt = false;
|
|
if (parentEl.is('th')) {
|
|
if (parentEl.hasClass('datepickerWeek') && options.mode == 'range' && !parentEl.next().hasClass('datepickerDisabled')) {
|
|
var val = parseInt(parentEl.next().text(), 10);
|
|
tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
|
|
if (parentEl.next().hasClass('datepickerNotInMonth')) {
|
|
tmp.addMonths(val > 15 ? -1 : 1);
|
|
}
|
|
tmp.setDate(val);
|
|
options.date[0] = (tmp.setHours(0,0,0,0)).valueOf();
|
|
tmp.setHours(23,59,59,0);
|
|
tmp.addDays(6);
|
|
options.date[1] = tmp.valueOf();
|
|
fillIt = true;
|
|
changed = true;
|
|
options.lastSel = false;
|
|
} else if (parentEl.hasClass('datepickerMonth')) {
|
|
tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
|
|
switch (tblEl.get(0).className) {
|
|
case 'datepickerViewDays':
|
|
tblEl.get(0).className = 'datepickerViewMonths';
|
|
el.find('span').text(tmp.getFullYear());
|
|
break;
|
|
case 'datepickerViewMonths':
|
|
tblEl.get(0).className = 'datepickerViewYears';
|
|
el.find('span').text((tmp.getFullYear()-6) + ' - ' + (tmp.getFullYear()+5));
|
|
break;
|
|
case 'datepickerViewYears':
|
|
tblEl.get(0).className = 'datepickerViewDays';
|
|
el.find('span').text(formatDate(tmp, 'B, Y'));
|
|
break;
|
|
}
|
|
} else if (parentEl.parent().parent().is('thead')) {
|
|
switch (tblEl.get(0).className) {
|
|
case 'datepickerViewDays':
|
|
options.current.addMonths(parentEl.hasClass('datepickerGoPrev') ? -1 : 1);
|
|
break;
|
|
case 'datepickerViewMonths':
|
|
options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -1 : 1);
|
|
break;
|
|
case 'datepickerViewYears':
|
|
options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -12 : 12);
|
|
break;
|
|
}
|
|
fillIt = true;
|
|
}
|
|
} else if (parentEl.is('td') && !parentEl.hasClass('datepickerDisabled')) {
|
|
switch (tblEl.get(0).className) {
|
|
case 'datepickerViewMonths':
|
|
options.current.setMonth(tblEl.find('tbody.datepickerMonths td').index(parentEl));
|
|
options.current.setFullYear(parseInt(tblEl.find('thead th.datepickerMonth span').text(), 10));
|
|
options.current.addMonths(Math.floor(options.calendars/2) - tblIndex);
|
|
tblEl.get(0).className = 'datepickerViewDays';
|
|
break;
|
|
case 'datepickerViewYears':
|
|
options.current.setFullYear(parseInt(el.text(), 10));
|
|
tblEl.get(0).className = 'datepickerViewMonths';
|
|
break;
|
|
default:
|
|
var val = parseInt(el.text(), 10);
|
|
tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
|
|
if (parentEl.hasClass('datepickerNotInMonth')) {
|
|
tmp.addMonths(val > 15 ? -1 : 1);
|
|
}
|
|
tmp.setDate(val);
|
|
switch (options.mode) {
|
|
case 'multiple':
|
|
val = (tmp.setHours(0,0,0,0)).valueOf();
|
|
if ($.inArray(val, options.date) > -1) {
|
|
$.each(options.date, function(nr, dat){
|
|
if (dat == val) {
|
|
options.date.splice(nr,1);
|
|
return false;
|
|
}
|
|
});
|
|
} else {
|
|
options.date.push(val);
|
|
}
|
|
break;
|
|
case 'range':
|
|
if (!options.lastSel) {
|
|
options.date[0] = (tmp.setHours(0,0,0,0)).valueOf();
|
|
}
|
|
val = (tmp.setHours(23,59,59,0)).valueOf();
|
|
if (val < options.date[0]) {
|
|
options.date[1] = options.date[0] + 86399000;
|
|
options.date[0] = val - 86399000;
|
|
} else {
|
|
options.date[1] = val;
|
|
}
|
|
options.lastSel = !options.lastSel;
|
|
break;
|
|
default:
|
|
options.date = tmp.valueOf();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
fillIt = true;
|
|
changed = true;
|
|
}
|
|
if (fillIt) {
|
|
fill(this);
|
|
}
|
|
if (changed) {
|
|
options.onChange.apply(this, prepareDate(options));
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
prepareDate = function (options) {
|
|
var tmp;
|
|
if (options.mode == 'single') {
|
|
tmp = new Date(options.date);
|
|
return [formatDate(tmp, options.format), tmp, options.el];
|
|
} else {
|
|
tmp = [[],[], options.el];
|
|
$.each(options.date, function(nr, val){
|
|
var date = new Date(val);
|
|
tmp[0].push(formatDate(date, options.format));
|
|
tmp[1].push(date);
|
|
});
|
|
return tmp;
|
|
}
|
|
},
|
|
getViewport = function () {
|
|
var m = document.compatMode == 'CSS1Compat';
|
|
return {
|
|
l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
|
|
t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),
|
|
w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),
|
|
h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)
|
|
};
|
|
},
|
|
isChildOf = function(parentEl, el, container) {
|
|
if (parentEl == el) {
|
|
return true;
|
|
}
|
|
if (parentEl.contains) {
|
|
return parentEl.contains(el);
|
|
}
|
|
if ( parentEl.compareDocumentPosition ) {
|
|
return !!(parentEl.compareDocumentPosition(el) & 16);
|
|
}
|
|
var prEl = el.parentNode;
|
|
while(prEl && prEl != container) {
|
|
if (prEl == parentEl)
|
|
return true;
|
|
prEl = prEl.parentNode;
|
|
}
|
|
return false;
|
|
},
|
|
show = function (ev) {
|
|
var cal = $('#' + $(this).data('datepickerId'));
|
|
if (!cal.is(':visible')) {
|
|
var calEl = cal.get(0);
|
|
fill(calEl);
|
|
var options = cal.data('datepicker');
|
|
options.onBeforeShow.apply(this, [cal.get(0)]);
|
|
var pos = $(this).offset();
|
|
var viewPort = getViewport();
|
|
var top = pos.top;
|
|
var left = pos.left;
|
|
var oldDisplay = $.curCSS(calEl, 'display');
|
|
cal.css({
|
|
visibility: 'hidden',
|
|
display: 'block'
|
|
});
|
|
layout(calEl);
|
|
switch (options.position){
|
|
case 'top':
|
|
top -= calEl.offsetHeight;
|
|
break;
|
|
case 'left':
|
|
left -= calEl.offsetWidth;
|
|
break;
|
|
case 'right':
|
|
left += this.offsetWidth;
|
|
break;
|
|
case 'bottom':
|
|
top += this.offsetHeight;
|
|
break;
|
|
}
|
|
if (top + calEl.offsetHeight > viewPort.t + viewPort.h) {
|
|
top = pos.top - calEl.offsetHeight;
|
|
}
|
|
if (top < viewPort.t) {
|
|
top = pos.top + this.offsetHeight + calEl.offsetHeight;
|
|
}
|
|
if (left + calEl.offsetWidth > viewPort.l + viewPort.w) {
|
|
left = pos.left - calEl.offsetWidth;
|
|
}
|
|
if (left < viewPort.l) {
|
|
left = pos.left + this.offsetWidth
|
|
}
|
|
cal.css({
|
|
visibility: 'visible',
|
|
display: 'block',
|
|
top: top + 'px',
|
|
left: left + 'px'
|
|
});
|
|
if (options.onShow.apply(this, [cal.get(0)]) != false) {
|
|
cal.show();
|
|
}
|
|
$(document).bind('mousedown', {cal: cal, trigger: this}, hide);
|
|
}
|
|
return false;
|
|
},
|
|
hide = function (ev) {
|
|
if (ev.target != ev.data.trigger && !isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {
|
|
if (ev.data.cal.data('datepicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) {
|
|
ev.data.cal.hide();
|
|
}
|
|
$(document).unbind('mousedown', hide);
|
|
}
|
|
};
|
|
return {
|
|
init: function(options){
|
|
options = $.extend({}, defaults, options||{});
|
|
extendDate(options.locale);
|
|
options.calendars = Math.max(1, parseInt(options.calendars,10)||1);
|
|
options.mode = /single|multiple|range/.test(options.mode) ? options.mode : 'single';
|
|
return this.each(function(){
|
|
if (!$(this).data('datepicker')) {
|
|
options.el = this;
|
|
if (options.date.constructor == String) {
|
|
options.date = parseDate(options.date, options.format);
|
|
options.date.setHours(0,0,0,0);
|
|
}
|
|
if (options.mode != 'single') {
|
|
if (options.date.constructor != Array) {
|
|
options.date = [options.date.valueOf()];
|
|
if (options.mode == 'range') {
|
|
options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf());
|
|
}
|
|
} else {
|
|
for (var i = 0; i < options.date.length; i++) {
|
|
options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf();
|
|
}
|
|
if (options.mode == 'range') {
|
|
options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf();
|
|
}
|
|
}
|
|
} else {
|
|
options.date = options.date.valueOf();
|
|
}
|
|
if (!options.current) {
|
|
options.current = new Date();
|
|
} else {
|
|
options.current = parseDate(options.current, options.format);
|
|
}
|
|
options.current.setDate(1);
|
|
options.current.setHours(0,0,0,0);
|
|
var id = 'datepicker_' + parseInt(Math.random() * 1000), cnt;
|
|
options.id = id;
|
|
$(this).data('datepickerId', options.id);
|
|
var cal = $(tpl.wrapper).attr('id', id).bind('click', click).data('datepicker', options);
|
|
if (options.className) {
|
|
cal.addClass(options.className);
|
|
}
|
|
var html = '';
|
|
for (var i = 0; i < options.calendars; i++) {
|
|
cnt = options.starts;
|
|
if (i > 0) {
|
|
html += tpl.space;
|
|
}
|
|
html += tmpl(tpl.head.join(''), {
|
|
week: options.locale.weekMin,
|
|
prev: options.prev,
|
|
next: options.next,
|
|
day1: options.locale.daysMin[(cnt++)%7],
|
|
day2: options.locale.daysMin[(cnt++)%7],
|
|
day3: options.locale.daysMin[(cnt++)%7],
|
|
day4: options.locale.daysMin[(cnt++)%7],
|
|
day5: options.locale.daysMin[(cnt++)%7],
|
|
day6: options.locale.daysMin[(cnt++)%7],
|
|
day7: options.locale.daysMin[(cnt++)%7]
|
|
});
|
|
}
|
|
cal
|
|
.find('tr:first').append(html)
|
|
.find('table').addClass(views[options.view]);
|
|
fill(cal.get(0));
|
|
if (options.flat) {
|
|
cal.appendTo(this).show().css('position', 'relative');
|
|
layout(cal.get(0));
|
|
} else {
|
|
cal.appendTo(document.body);
|
|
$(this).bind(options.eventName, show);
|
|
}
|
|
}
|
|
});
|
|
},
|
|
showPicker: function() {
|
|
return this.each( function () {
|
|
if ($(this).data('datepickerId')) {
|
|
show.apply(this);
|
|
}
|
|
});
|
|
},
|
|
hidePicker: function() {
|
|
return this.each( function () {
|
|
if ($(this).data('datepickerId')) {
|
|
$('#' + $(this).data('datepickerId')).hide();
|
|
}
|
|
});
|
|
},
|
|
setDate: function(date, shiftTo){
|
|
return this.each(function(){
|
|
if ($(this).data('datepickerId')) {
|
|
var cal = $('#' + $(this).data('datepickerId'));
|
|
var options = cal.data('datepicker');
|
|
options.date = date;
|
|
if (options.date.constructor == String) {
|
|
options.date = parseDate(options.date, options.format);
|
|
options.date.setHours(0,0,0,0);
|
|
}
|
|
if (options.mode != 'single') {
|
|
if (options.date.constructor != Array) {
|
|
options.date = [options.date.valueOf()];
|
|
if (options.mode == 'range') {
|
|
options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf());
|
|
}
|
|
} else {
|
|
for (var i = 0; i < options.date.length; i++) {
|
|
options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf();
|
|
}
|
|
if (options.mode == 'range') {
|
|
options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf();
|
|
}
|
|
}
|
|
} else {
|
|
options.date = options.date.valueOf();
|
|
}
|
|
if (shiftTo) {
|
|
options.current = new Date (options.mode != 'single' ? options.date[0] : options.date);
|
|
}
|
|
fill(cal.get(0));
|
|
}
|
|
});
|
|
},
|
|
getDate: function(formated) {
|
|
if (this.size() > 0) {
|
|
return prepareDate($('#' + $(this).data('datepickerId')).data('datepicker'))[formated ? 0 : 1];
|
|
}
|
|
},
|
|
clear: function(){
|
|
return this.each(function(){
|
|
if ($(this).data('datepickerId')) {
|
|
var cal = $('#' + $(this).data('datepickerId'));
|
|
var options = cal.data('datepicker');
|
|
if (options.mode != 'single') {
|
|
options.date = [];
|
|
fill(cal.get(0));
|
|
}
|
|
}
|
|
});
|
|
},
|
|
fixLayout: function(){
|
|
return this.each(function(){
|
|
if ($(this).data('datepickerId')) {
|
|
var cal = $('#' + $(this).data('datepickerId'));
|
|
var options = cal.data('datepicker');
|
|
if (options.flat) {
|
|
layout(cal.get(0));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}();
|
|
$.fn.extend({
|
|
DatePicker: DatePicker.init,
|
|
DatePickerHide: DatePicker.hidePicker,
|
|
DatePickerShow: DatePicker.showPicker,
|
|
DatePickerSetDate: DatePicker.setDate,
|
|
DatePickerGetDate: DatePicker.getDate,
|
|
DatePickerClear: DatePicker.clear,
|
|
DatePickerLayout: DatePicker.fixLayout
|
|
});
|
|
})(jQuery);
|
|
|
|
(function(){
|
|
var cache = {};
|
|
|
|
this.tmpl = function tmpl(str, data){
|
|
// Figure out if we're getting a template, or if we need to
|
|
// load the template - and be sure to cache the result.
|
|
var fn = !/\W/.test(str) ?
|
|
cache[str] = cache[str] ||
|
|
tmpl(document.getElementById(str).innerHTML) :
|
|
|
|
// Generate a reusable function that will serve as a template
|
|
// generator (and which will be cached).
|
|
new Function("obj",
|
|
"var p=[],print=function(){p.push.apply(p,arguments);};" +
|
|
|
|
// Introduce the data as local variables using with(){}
|
|
"with(obj){p.push('" +
|
|
|
|
// Convert the template into pure JavaScript
|
|
str
|
|
.replace(/[\r\t\n]/g, " ")
|
|
.split("<%").join("\t")
|
|
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
|
|
.replace(/\t=(.*?)%>/g, "',$1,'")
|
|
.split("\t").join("');")
|
|
.split("%>").join("p.push('")
|
|
.split("\r").join("\\'")
|
|
+ "');}return p.join('');");
|
|
|
|
// Provide some basic currying to the user
|
|
return data ? fn( data ) : fn;
|
|
};
|
|
})();
|