Created
March 6, 2014 19:44
-
-
Save JamoCA/9397850 to your computer and use it in GitHub Desktop.
Pikaday jQuery plugin with my modifications to add DateJS integration. (DateJS can parse strings like "next friday".) http://www.datejs.com/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* Pikaday 1.2.0 (Downloaded on 3/6/2014) | |
* | |
* Copyright © 2014 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday | |
* DateJS modifications by James Moberg | 3/6/2014 | http://about.me/jamesmoberg | |
*/ | |
(function (root, factory) | |
{ | |
'use strict'; | |
var moment; | |
if (typeof exports === 'object') { | |
// CommonJS module | |
// Load moment.js as an optional dependency | |
try { moment = require('moment'); } catch (e) {} | |
module.exports = factory(moment); | |
} else if (typeof define === 'function' && define.amd) { | |
// AMD. Register as an anonymous module. | |
define(function (req) | |
{ | |
// Load moment.js as an optional dependency | |
var id = 'moment'; | |
moment = req.defined && req.defined(id) ? req(id) : undefined; | |
return factory(moment); | |
}); | |
} else { | |
root.Pikaday = factory(root.moment); | |
} | |
}(this, function (moment) | |
{ | |
'use strict'; | |
/** | |
* feature detection and helper functions | |
*/ | |
var hasMoment = typeof moment === 'function', | |
hasDateJS = typeof Date.CultureInfo === 'object', | |
hasEventListeners = !!window.addEventListener, | |
document = window.document, | |
sto = window.setTimeout, | |
addEvent = function(el, e, callback, capture) | |
{ | |
if (hasEventListeners) { | |
el.addEventListener(e, callback, !!capture); | |
} else { | |
el.attachEvent('on' + e, callback); | |
} | |
}, | |
removeEvent = function(el, e, callback, capture) | |
{ | |
if (hasEventListeners) { | |
el.removeEventListener(e, callback, !!capture); | |
} else { | |
el.detachEvent('on' + e, callback); | |
} | |
}, | |
fireEvent = function(el, eventName, data) | |
{ | |
var ev; | |
if (document.createEvent) { | |
ev = document.createEvent('HTMLEvents'); | |
ev.initEvent(eventName, true, false); | |
ev = extend(ev, data); | |
el.dispatchEvent(ev); | |
} else if (document.createEventObject) { | |
ev = document.createEventObject(); | |
ev = extend(ev, data); | |
el.fireEvent('on' + eventName, ev); | |
} | |
}, | |
trim = function(str) | |
{ | |
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,''); | |
}, | |
hasClass = function(el, cn) | |
{ | |
return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1; | |
}, | |
addClass = function(el, cn) | |
{ | |
if (!hasClass(el, cn)) { | |
el.className = (el.className === '') ? cn : el.className + ' ' + cn; | |
} | |
}, | |
removeClass = function(el, cn) | |
{ | |
el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' ')); | |
}, | |
isArray = function(obj) | |
{ | |
return (/Array/).test(Object.prototype.toString.call(obj)); | |
}, | |
isDate = function(obj) | |
{ | |
return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime()); | |
}, | |
isLeapYear = function(year) | |
{ | |
// solution by Matti Virkkunen: http://stackoverflow.com/a/4881951 | |
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; | |
}, | |
getDaysInMonth = function(year, month) | |
{ | |
return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; | |
}, | |
setToStartOfDay = function(date) | |
{ | |
if (isDate(date)) date.setHours(0,0,0,0); | |
}, | |
compareDates = function(a,b) | |
{ | |
// weak date comparison (use setToStartOfDay(date) to ensure correct result) | |
return a.getTime() === b.getTime(); | |
}, | |
extend = function(to, from, overwrite) | |
{ | |
var prop, hasProp; | |
for (prop in from) { | |
hasProp = to[prop] !== undefined; | |
if (hasProp && typeof from[prop] === 'object' && from[prop].nodeName === undefined) { | |
if (isDate(from[prop])) { | |
if (overwrite) { | |
to[prop] = new Date(from[prop].getTime()); | |
} | |
} | |
else if (isArray(from[prop])) { | |
if (overwrite) { | |
to[prop] = from[prop].slice(0); | |
} | |
} else { | |
to[prop] = extend({}, from[prop], overwrite); | |
} | |
} else if (overwrite || !hasProp) { | |
to[prop] = from[prop]; | |
} | |
} | |
return to; | |
}, | |
/** | |
* defaults and localisation | |
*/ | |
defaults = { | |
// bind the picker to a form field | |
field: null, | |
// automatically show/hide the picker on `field` focus (default `true` if `field` is set) | |
bound: undefined, | |
// position of the datepicker, relative to the field (default to bottom & left) | |
// ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position) | |
position: 'bottom left', | |
// the default output format for `.toString()` and `field` value | |
format: 'YYYY-MM-DD', | |
// the initial date to view when first opened | |
defaultDate: null, | |
// make the `defaultDate` the initial selected value | |
setDefaultDate: false, | |
// first day of week (0: Sunday, 1: Monday etc) | |
firstDay: 0, | |
// the minimum/earliest date that can be selected | |
minDate: null, | |
// the maximum/latest date that can be selected | |
maxDate: null, | |
// number of years either side, or array of upper/lower range | |
yearRange: 10, | |
// used internally (don't config outside) | |
minYear: 0, | |
maxYear: 9999, | |
minMonth: undefined, | |
maxMonth: undefined, | |
isRTL: false, | |
// Additional text to append to the year in the calendar title | |
yearSuffix: '', | |
// Render the month after year in the calendar title | |
showMonthAfterYear: false, | |
// how many months are visible (not implemented yet) | |
numberOfMonths: 1, | |
// internationalization | |
i18n: { | |
previousMonth : 'Previous Month', | |
nextMonth : 'Next Month', | |
months : ['January','February','March','April','May','June','July','August','September','October','November','December'], | |
weekdays : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'], | |
weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'] | |
}, | |
// callback function | |
onSelect: null, | |
onOpen: null, | |
onClose: null, | |
onDraw: null | |
}, | |
/** | |
* templating functions to abstract HTML rendering | |
*/ | |
renderDayName = function(opts, day, abbr) | |
{ | |
day += opts.firstDay; | |
while (day >= 7) { | |
day -= 7; | |
} | |
return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day]; | |
}, | |
renderDay = function(i, isSelected, isToday, isDisabled, isEmpty) | |
{ | |
if (isEmpty) { | |
return '<td class="is-empty"></td>'; | |
} | |
var arr = []; | |
if (isDisabled) { | |
arr.push('is-disabled'); | |
} | |
if (isToday) { | |
arr.push('is-today'); | |
} | |
if (isSelected) { | |
arr.push('is-selected'); | |
} | |
return '<td data-day="' + i + '" class="' + arr.join(' ') + '"><button class="pika-button" type="button">' + i + '</button>' + '</td>'; | |
}, | |
renderRow = function(days, isRTL) | |
{ | |
return '<tr>' + (isRTL ? days.reverse() : days).join('') + '</tr>'; | |
}, | |
renderBody = function(rows) | |
{ | |
return '<tbody>' + rows.join('') + '</tbody>'; | |
}, | |
renderHead = function(opts) | |
{ | |
var i, arr = []; | |
for (i = 0; i < 7; i++) { | |
arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>'); | |
} | |
return '<thead>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</thead>'; | |
}, | |
renderTitle = function(instance) | |
{ | |
var i, j, arr, | |
opts = instance._o, | |
month = instance._m, | |
year = instance._y, | |
isMinYear = year === opts.minYear, | |
isMaxYear = year === opts.maxYear, | |
html = '<div class="pika-title">', | |
monthHtml, | |
yearHtml, | |
prev = true, | |
next = true; | |
for (arr = [], i = 0; i < 12; i++) { | |
arr.push('<option value="' + i + '"' + | |
(i === month ? ' selected': '') + | |
((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled' : '') + '>' + | |
opts.i18n.months[i] + '</option>'); | |
} | |
monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month">' + arr.join('') + '</select></div>'; | |
if (isArray(opts.yearRange)) { | |
i = opts.yearRange[0]; | |
j = opts.yearRange[1] + 1; | |
} else { | |
i = year - opts.yearRange; | |
j = 1 + year + opts.yearRange; | |
} | |
for (arr = []; i < j && i <= opts.maxYear; i++) { | |
if (i >= opts.minYear) { | |
arr.push('<option value="' + i + '"' + (i === year ? ' selected': '') + '>' + (i) + '</option>'); | |
} | |
} | |
yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year">' + arr.join('') + '</select></div>'; | |
if (opts.showMonthAfterYear) { | |
html += yearHtml + monthHtml; | |
} else { | |
html += monthHtml + yearHtml; | |
} | |
if (isMinYear && (month === 0 || opts.minMonth >= month)) { | |
prev = false; | |
} | |
if (isMaxYear && (month === 11 || opts.maxMonth <= month)) { | |
next = false; | |
} | |
html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>'; | |
html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>'; | |
return html += '</div>'; | |
}, | |
renderTable = function(opts, data) | |
{ | |
return '<table cellpadding="0" cellspacing="0" class="pika-table">' + renderHead(opts) + renderBody(data) + '</table>'; | |
}, | |
/** | |
* Pikaday constructor | |
*/ | |
Pikaday = function(options) | |
{ | |
var self = this, | |
opts = self.config(options); | |
self._onMouseDown = function(e) | |
{ | |
if (!self._v) { | |
return; | |
} | |
e = e || window.event; | |
var target = e.target || e.srcElement; | |
if (!target) { | |
return; | |
} | |
if (!hasClass(target, 'is-disabled')) { | |
if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) { | |
self.setDate(new Date(self._y, self._m, parseInt(target.innerHTML, 10))); | |
if (opts.bound) { | |
sto(function() { | |
self.hide(); | |
}, 100); | |
} | |
return; | |
} | |
else if (hasClass(target, 'pika-prev')) { | |
self.prevMonth(); | |
} | |
else if (hasClass(target, 'pika-next')) { | |
self.nextMonth(); | |
} | |
} | |
if (!hasClass(target, 'pika-select')) { | |
if (e.preventDefault) { | |
e.preventDefault(); | |
} else { | |
e.returnValue = false; | |
return false; | |
} | |
} else { | |
self._c = true; | |
} | |
}; | |
self._onChange = function(e) | |
{ | |
e = e || window.event; | |
var target = e.target || e.srcElement; | |
if (!target) { | |
return; | |
} | |
if (hasClass(target, 'pika-select-month')) { | |
self.gotoMonth(target.value); | |
} | |
else if (hasClass(target, 'pika-select-year')) { | |
self.gotoYear(target.value); | |
} | |
}; | |
self._onInputChange = function(e) | |
{ | |
var date; | |
if (e.firedBy === self) { | |
return; | |
} | |
if (hasMoment) { | |
date = moment(opts.field.value, opts.format); | |
date = (date && date.isValid()) ? date.toDate() : null; | |
} | |
else if (hasDateJS) { | |
if (Date.parse(opts.field.value) !== null) { | |
date = Date.parse(opts.field.value, opts.format); | |
} | |
} | |
else { | |
date = new Date(Date.parse(opts.field.value)); | |
} | |
self.setDate(isDate(date) ? date : null); | |
if (!self._v) { | |
self.show(); | |
} | |
}; | |
self._onInputFocus = function() | |
{ | |
self.show(); | |
}; | |
self._onInputClick = function() | |
{ | |
self.show(); | |
}; | |
self._onInputBlur = function() | |
{ | |
if (!self._c) { | |
self._b = sto(function() { | |
self.hide(); | |
}, 50); | |
} | |
self._c = false; | |
}; | |
self._onClick = function(e) | |
{ | |
e = e || window.event; | |
var target = e.target || e.srcElement, | |
pEl = target; | |
if (!target) { | |
return; | |
} | |
if (!hasEventListeners && hasClass(target, 'pika-select')) { | |
if (!target.onchange) { | |
target.setAttribute('onchange', 'return;'); | |
addEvent(target, 'change', self._onChange); | |
} | |
} | |
do { | |
if (hasClass(pEl, 'pika-single')) { | |
return; | |
} | |
} | |
while ((pEl = pEl.parentNode)); | |
if (self._v && target !== opts.trigger) { | |
self.hide(); | |
} | |
}; | |
self.el = document.createElement('div'); | |
self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : ''); | |
addEvent(self.el, 'mousedown', self._onMouseDown, true); | |
addEvent(self.el, 'change', self._onChange); | |
if (opts.field) { | |
if (opts.bound) { | |
document.body.appendChild(self.el); | |
} else { | |
opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling); | |
} | |
addEvent(opts.field, 'change', self._onInputChange); | |
if (!opts.defaultDate) { | |
if (hasMoment && opts.field.value) { | |
opts.defaultDate = moment(opts.field.value, opts.format).toDate(); | |
} else if (hasDateJS) { | |
opts.defaultDate = Date.parse(opts.field.value); | |
} else { | |
opts.defaultDate = new Date(Date.parse(opts.field.value)); | |
} | |
opts.setDefaultDate = true; | |
} | |
} | |
var defDate = opts.defaultDate; | |
if (isDate(defDate)) { | |
if (opts.setDefaultDate) { | |
self.setDate(defDate, true); | |
} else { | |
self.gotoDate(defDate); | |
} | |
} else { | |
self.gotoDate(new Date()); | |
} | |
if (opts.bound) { | |
this.hide(); | |
self.el.className += ' is-bound'; | |
addEvent(opts.trigger, 'click', self._onInputClick); | |
addEvent(opts.trigger, 'focus', self._onInputFocus); | |
addEvent(opts.trigger, 'blur', self._onInputBlur); | |
} else { | |
this.show(); | |
} | |
}; | |
/** | |
* public Pikaday API | |
*/ | |
Pikaday.prototype = { | |
/** | |
* configure functionality | |
*/ | |
config: function(options) | |
{ | |
if (!this._o) { | |
this._o = extend({}, defaults, true); | |
} | |
var opts = extend(this._o, options, true); | |
opts.isRTL = !!opts.isRTL; | |
opts.field = (opts.field && opts.field.nodeName) ? opts.field : null; | |
opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field); | |
opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field; | |
var nom = parseInt(opts.numberOfMonths, 10) || 1; | |
opts.numberOfMonths = nom > 4 ? 4 : nom; | |
if (!isDate(opts.minDate)) { | |
opts.minDate = false; | |
} | |
if (!isDate(opts.maxDate)) { | |
opts.maxDate = false; | |
} | |
if ((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate) { | |
opts.maxDate = opts.minDate = false; | |
} | |
if (opts.minDate) { | |
setToStartOfDay(opts.minDate); | |
opts.minYear = opts.minDate.getFullYear(); | |
opts.minMonth = opts.minDate.getMonth(); | |
} | |
if (opts.maxDate) { | |
setToStartOfDay(opts.maxDate); | |
opts.maxYear = opts.maxDate.getFullYear(); | |
opts.maxMonth = opts.maxDate.getMonth(); | |
} | |
if (isArray(opts.yearRange)) { | |
var fallback = new Date().getFullYear() - 10; | |
opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback; | |
opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback; | |
} else { | |
opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange; | |
if (opts.yearRange > 100) { | |
opts.yearRange = 100; | |
} | |
} | |
return opts; | |
}, | |
/** | |
* return a formatted string of the current selection (using Moment.js if available) | |
*/ | |
toString: function(format) | |
{ | |
if (hasDateJS){ | |
if (Date.parse(this._d) !== null){ | |
return Date.parse(this._d).toString(format || this._o.format); | |
} else { | |
return ''; | |
} | |
} else if (!isDate(this._d)){ | |
return ''; | |
} else if (hasMoment){ | |
return moment(this._d).format(format || this._o.format); | |
} else { | |
this._d.toDateString(); | |
} | |
}, | |
/** | |
* return a Moment.js object of the current selection (if available) | |
*/ | |
getMoment: function() | |
{ | |
return hasMoment ? moment(this._d) : null; | |
}, | |
/** | |
* set the current selection from a Moment.js object (if available) | |
*/ | |
setMoment: function(date, preventOnSelect) | |
{ | |
if (hasMoment && moment.isMoment(date)) { | |
this.setDate(date.toDate(), preventOnSelect); | |
} | |
}, | |
/** | |
* return a Date object of the current selection | |
*/ | |
getDate: function() | |
{ | |
return isDate(this._d) ? new Date(this._d.getTime()) : null; | |
}, | |
/** | |
* set the current selection | |
*/ | |
setDate: function(date, preventOnSelect) | |
{ | |
if (!date) { | |
this._d = null; | |
return this.draw(); | |
} | |
if (typeof date === 'string') { | |
if (hasDateJS){ | |
date = Date.parse(date); | |
} else { | |
date = new Date(Date.parse(date)); | |
} | |
} | |
if (!isDate(date)) { | |
return; | |
} | |
var min = this._o.minDate, | |
max = this._o.maxDate; | |
if (isDate(min) && date < min) { | |
date = min; | |
} else if (isDate(max) && date > max) { | |
date = max; | |
} | |
this._d = new Date(date.getTime()); | |
setToStartOfDay(this._d); | |
this.gotoDate(this._d); | |
if (this._o.field) { | |
this._o.field.value = this.toString(); | |
fireEvent(this._o.field, 'change', { firedBy: this }); | |
} | |
if (!preventOnSelect && typeof this._o.onSelect === 'function') { | |
this._o.onSelect.call(this, this.getDate()); | |
} | |
}, | |
/** | |
* change view to a specific date | |
*/ | |
gotoDate: function(date) | |
{ | |
if (!isDate(date)) { | |
return; | |
} | |
this._y = date.getFullYear(); | |
this._m = date.getMonth(); | |
this.draw(); | |
}, | |
gotoToday: function() | |
{ | |
this.gotoDate(new Date()); | |
}, | |
/** | |
* change view to a specific month (zero-index, e.g. 0: January) | |
*/ | |
gotoMonth: function(month) | |
{ | |
if (!isNaN( (month = parseInt(month, 10)) )) { | |
this._m = month < 0 ? 0 : month > 11 ? 11 : month; | |
this.draw(); | |
} | |
}, | |
nextMonth: function() | |
{ | |
if (++this._m > 11) { | |
this._m = 0; | |
this._y++; | |
} | |
this.draw(); | |
}, | |
prevMonth: function() | |
{ | |
if (--this._m < 0) { | |
this._m = 11; | |
this._y--; | |
} | |
this.draw(); | |
}, | |
/** | |
* change view to a specific full year (e.g. "2012") | |
*/ | |
gotoYear: function(year) | |
{ | |
if (!isNaN(year)) { | |
this._y = parseInt(year, 10); | |
this.draw(); | |
} | |
}, | |
/** | |
* change the minDate | |
*/ | |
setMinDate: function(value) | |
{ | |
this._o.minDate = value; | |
}, | |
/** | |
* change the maxDate | |
*/ | |
setMaxDate: function(value) | |
{ | |
this._o.maxDate = value; | |
}, | |
/** | |
* refresh the HTML | |
*/ | |
draw: function(force) | |
{ | |
if (!this._v && !force) { | |
return; | |
} | |
var opts = this._o, | |
minYear = opts.minYear, | |
maxYear = opts.maxYear, | |
minMonth = opts.minMonth, | |
maxMonth = opts.maxMonth; | |
if (this._y <= minYear) { | |
this._y = minYear; | |
if (!isNaN(minMonth) && this._m < minMonth) { | |
this._m = minMonth; | |
} | |
} | |
if (this._y >= maxYear) { | |
this._y = maxYear; | |
if (!isNaN(maxMonth) && this._m > maxMonth) { | |
this._m = maxMonth; | |
} | |
} | |
this.el.innerHTML = renderTitle(this) + this.render(this._y, this._m); | |
if (opts.bound) { | |
this.adjustPosition(); | |
if(opts.field.type !== 'hidden') { | |
sto(function() { | |
opts.trigger.focus(); | |
}, 1); | |
} | |
} | |
if (typeof this._o.onDraw === 'function') { | |
var self = this; | |
sto(function() { | |
self._o.onDraw.call(self); | |
}, 0); | |
} | |
}, | |
adjustPosition: function() | |
{ | |
var field = this._o.trigger, pEl = field, | |
width = this.el.offsetWidth, height = this.el.offsetHeight, | |
viewportWidth = window.innerWidth || document.documentElement.clientWidth, | |
viewportHeight = window.innerHeight || document.documentElement.clientHeight, | |
scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop, | |
left, top, clientRect; | |
if (typeof field.getBoundingClientRect === 'function') { | |
clientRect = field.getBoundingClientRect(); | |
left = clientRect.left + window.pageXOffset; | |
top = clientRect.bottom + window.pageYOffset; | |
} else { | |
left = pEl.offsetLeft; | |
top = pEl.offsetTop + pEl.offsetHeight; | |
while((pEl = pEl.offsetParent)) { | |
left += pEl.offsetLeft; | |
top += pEl.offsetTop; | |
} | |
} | |
// default position is bottom & left | |
if (left + width > viewportWidth || | |
( | |
this._o.position.indexOf('right') > -1 && | |
left - width + field.offsetWidth > 0 | |
) | |
) { | |
left = left - width + field.offsetWidth; | |
} | |
if (top + height > viewportHeight + scrollTop || | |
( | |
this._o.position.indexOf('top') > -1 && | |
top - height - field.offsetHeight > 0 | |
) | |
) { | |
top = top - height - field.offsetHeight; | |
} | |
this.el.style.cssText = [ | |
'position: absolute', | |
'left: ' + left + 'px', | |
'top: ' + top + 'px' | |
].join(';'); | |
}, | |
/** | |
* render HTML for a particular month | |
*/ | |
render: function(year, month) | |
{ | |
var opts = this._o, | |
now = new Date(), | |
days = getDaysInMonth(year, month), | |
before = new Date(year, month, 1).getDay(), | |
data = [], | |
row = []; | |
setToStartOfDay(now); | |
if (opts.firstDay > 0) { | |
before -= opts.firstDay; | |
if (before < 0) { | |
before += 7; | |
} | |
} | |
var cells = days + before, | |
after = cells; | |
while(after > 7) { | |
after -= 7; | |
} | |
cells += 7 - after; | |
for (var i = 0, r = 0; i < cells; i++) | |
{ | |
var day = new Date(year, month, 1 + (i - before)), | |
isDisabled = (opts.minDate && day < opts.minDate) || (opts.maxDate && day > opts.maxDate), | |
isSelected = isDate(this._d) ? compareDates(day, this._d) : false, | |
isToday = compareDates(day, now), | |
isEmpty = i < before || i >= (days + before); | |
row.push(renderDay(1 + (i - before), isSelected, isToday, isDisabled, isEmpty)); | |
if (++r === 7) { | |
data.push(renderRow(row, opts.isRTL)); | |
row = []; | |
r = 0; | |
} | |
} | |
return renderTable(opts, data); | |
}, | |
isVisible: function() | |
{ | |
return this._v; | |
}, | |
show: function() | |
{ | |
if (!this._v) { | |
if (this._o.bound) { | |
addEvent(document, 'click', this._onClick); | |
} | |
removeClass(this.el, 'is-hidden'); | |
this._v = true; | |
this.draw(); | |
if (typeof this._o.onOpen === 'function') { | |
this._o.onOpen.call(this); | |
} | |
} | |
}, | |
hide: function() | |
{ | |
var v = this._v; | |
if (v !== false) { | |
if (this._o.bound) { | |
removeEvent(document, 'click', this._onClick); | |
} | |
this.el.style.cssText = ''; | |
addClass(this.el, 'is-hidden'); | |
this._v = false; | |
if (v !== undefined && typeof this._o.onClose === 'function') { | |
this._o.onClose.call(this); | |
} | |
} | |
}, | |
/** | |
* GAME OVER | |
*/ | |
destroy: function() | |
{ | |
this.hide(); | |
removeEvent(this.el, 'mousedown', this._onMouseDown, true); | |
removeEvent(this.el, 'change', this._onChange); | |
if (this._o.field) { | |
removeEvent(this._o.field, 'change', this._onInputChange); | |
if (this._o.bound) { | |
removeEvent(this._o.trigger, 'click', this._onInputClick); | |
removeEvent(this._o.trigger, 'focus', this._onInputFocus); | |
removeEvent(this._o.trigger, 'blur', this._onInputBlur); | |
} | |
} | |
if (this.el.parentNode) { | |
this.el.parentNode.removeChild(this.el); | |
} | |
} | |
}; | |
return Pikaday; | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment