New file |
0,0 → 1,853 |
/** |
* |
* Date picker |
* Author: Stefan Petre www.eyecon.ro |
* |
*/ |
(function ($) { |
var DatePicker = function () { |
var ids = {}, |
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', |
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: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], |
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], |
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], |
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], |
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], |
weekMin: 'wk' |
} |
}, |
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||now.getFullYear(), |
m||now.getMonth(), |
d||now.getDate(), |
h||now.getHours(), |
min||now.getMinutes(), |
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) { |
delete options.date[nr]; |
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]; |
} else { |
tmp = [[],[]]; |
$.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); |
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')) { |
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); |
} |
for (var i = 0; i < options.calendars; i++) { |
cnt = options.starts; |
cal.find('tr:first').append( |
i > 0 ? tpl.space: '', |
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 table').addClass('datepickerViewDays'); |
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]; |
} |
} |
}; |
}(); |
$.fn.extend({ |
DatePicker: DatePicker.init, |
DatePickerHide: DatePicker.hide, |
DatePickerShow: DatePicker.show, |
DatePickerSetDate: DatePicker.setDate, |
DatePickerGetDate: DatePicker.getDate |
}); |
})(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; |
}; |
})(); |