;(function (window, $, undefined){ ;(function (){
"use strict";
var VERSION='2.2.3',
pluginName='airdatepicker',
autoInitSelector='.airdatepicker-here',
$body, $airdatepickersContainer,
containerBuilt=false,
baseTemplate='' +
'<div class="airdatepicker">' +
'<i class="airdatepicker--pointer"></i>' +
'<nav class="airdatepicker--nav"></nav>' +
'<div class="airdatepicker--content"></div>' +
'</div>',
defaults={
classes: '',
inline: false,
inline_popup: false,
language: 'en',
startDate: new Date(),
firstDay: '',
weekends: [6, 0],
dateFormat: '',
altField: '',
altFieldDateFormat: '@',
toggleSelected: true,
keyboardNav: true,
position: 'bottom left',
offset: 12,
view: 'days',
minView: 'days',
showOtherMonths: true,
selectOtherMonths: true,
moveToOtherMonthsOnSelect: true,
showOtherYears: true,
selectOtherYears: true,
moveToOtherYearsOnSelect: true,
minDate: '',
maxDate: '',
disableNavWhenOutOfRange: true,
multipleDates: false,
multipleDatesSeparator: ',',
range: false,
todayButton: false,
clearButton: false,
showEvent: 'focus',
autoClose: false,
monthsField: 'monthsShort',
prevHtml: '<svg><path d="M 17,12 l -5,5 l 5,5"></path></svg>',
nextHtml: '<svg><path d="M 14,12 l 5,5 l -5,5"></path></svg>',
navTitles: {
days: 'MM, <i>yyyy</i>',
months: 'yyyy',
years: 'yyyy1 - yyyy2'
},
timepicker: false,
onlyTimepicker: false,
dateTimeSeparator: ' ',
timeFormat: '',
minHours: 0,
maxHours: 24,
minMinutes: 0,
maxMinutes: 59,
hoursStep: 1,
minutesStep: 1,
onSelect: '',
onShow: '',
onHide: '',
onChangeMonth: '',
onChangeYear: '',
onChangeDecade: '',
onChangeView: '',
onRenderCell: ''
},
hotKeys={
'ctrlRight': [17, 39],
'ctrlUp': [17, 38],
'ctrlLeft': [17, 37],
'ctrlDown': [17, 40],
'shiftRight': [16, 39],
'shiftUp': [16, 38],
'shiftLeft': [16, 37],
'shiftDown': [16, 40],
'altUp': [18, 38],
'altRight': [18, 39],
'altLeft': [18, 37],
'altDown': [18, 40],
'ctrlShiftUp': [16, 17, 38]
},
airdatepicker;
var Datepicker=function (el, options){
this.el=el;
this.$el=$(el);
this.opts=$.extend(true, {}, defaults, options, this.$el.data());
if($body==undefined){
$body=$('body');
}
if(!this.opts.startDate){
this.opts.startDate=new Date();
}
if(this.el.nodeName=='INPUT'){
this.elIsInput=true;
}
if(this.opts.altField){
this.$altField=typeof this.opts.altField=='string' ? $(this.opts.altField):this.opts.altField;
}
this.inited=false;
this.visible=false;
this.silent=false;
this.currentDate=this.opts.startDate;
this.currentView=this.opts.view;
this._createShortCuts();
this.selectedDates=[];
this.views={};
this.keys=[];
this.minRange='';
this.maxRange='';
this._prevOnSelectValue='';
this.init()
};
airdatepicker=Datepicker;
airdatepicker.prototype={
VERSION: VERSION,
viewIndexes: ['days', 'months', 'years'],
init: function (){
if(!containerBuilt&&!this.opts.inline&&this.elIsInput){
this._buildDatepickersContainer();
}
this._buildBaseHtml();
this._defineLocale(this.opts.language);
this._syncWithMinMaxDates();
if(this.elIsInput){
if(!this.opts.inline){
this._setPositionClasses(this.opts.position);
this._bindEvents()
}
if(this.opts.keyboardNav&&!this.opts.onlyTimepicker){
this._bindKeyboardEvents();
}
this.$airdatepicker.on('mousedown', this._onMouseDownDatepicker.bind(this));
this.$airdatepicker.on('mouseup', this._onMouseUpDatepicker.bind(this));
}
if(this.opts.classes){
this.$airdatepicker.addClass(this.opts.classes)
}
if(this.opts.timepicker){
this.timepicker=new $.fn.airdatepicker.Timepicker(this, this.opts);
this._bindTimepickerEvents();
}
if(this.opts.onlyTimepicker){
this.$airdatepicker.addClass('-only-timepicker-');
}
this.views[this.currentView]=new $.fn.airdatepicker.Body(this, this.currentView, this.opts);
this.views[this.currentView].show();
this.nav=new $.fn.airdatepicker.Navigation(this, this.opts);
this.view=this.currentView;
this.$el.on('clickCell.adp', this._onClickCell.bind(this));
this.$airdatepicker.on('mouseenter', '.airdatepicker--cell', this._onMouseEnterCell.bind(this));
this.$airdatepicker.on('mouseleave', '.airdatepicker--cell', this._onMouseLeaveCell.bind(this));
this.inited=true;
},
_createShortCuts: function (){
this.minDate=this.opts.minDate ? this.opts.minDate:new Date(-8639999913600000);
this.maxDate=this.opts.maxDate ? this.opts.maxDate:new Date(8639999913600000);
},
_bindEvents:function (){
this.$el.on(this.opts.showEvent + '.adp', this._onShowEvent.bind(this));
this.$el.on('mouseup.adp', this._onMouseUpEl.bind(this));
this.$el.on('blur.adp', this._onBlur.bind(this));
this.$el.on('keyup.adp', this._onKeyUpGeneral.bind(this));
$(window).on('resize.adp', this._onResize.bind(this));
$('body').on('mouseup.adp', this._onMouseUpBody.bind(this));
},
_bindKeyboardEvents: function (){
this.$el.on('keydown.adp', this._onKeyDown.bind(this));
this.$el.on('keyup.adp', this._onKeyUp.bind(this));
this.$el.on('hotKey.adp', this._onHotKey.bind(this));
},
_bindTimepickerEvents: function (){
this.$el.on('timeChange.adp', this._onTimeChange.bind(this));
},
isWeekend: function (day){
return this.opts.weekends.indexOf(day)!==-1;
},
_defineLocale: function (lang){
if(typeof lang=='string'){
this.loc=$.fn.airdatepicker.language[lang];
if(!this.loc){
console.warn('Can\'t find language "' + lang + '" in Datepicker.language, will use "en" instead');
this.loc=$.extend(true, {}, $.fn.airdatepicker.language.ru)
}
this.loc=$.extend(true, {}, $.fn.airdatepicker.language.ru, $.fn.airdatepicker.language[lang])
}else{
this.loc=$.extend(true, {}, $.fn.airdatepicker.language.ru, lang)
}
if(this.opts.dateFormat){
this.loc.dateFormat=this.opts.dateFormat
}
if(this.opts.timeFormat){
this.loc.timeFormat=this.opts.timeFormat
}
if(this.opts.firstDay!==''){
this.loc.firstDay=this.opts.firstDay
}
if(this.opts.timepicker){
this.loc.dateFormat=[this.loc.dateFormat, this.loc.timeFormat].join(this.opts.dateTimeSeparator);
}
if(this.opts.onlyTimepicker){
this.loc.dateFormat=this.loc.timeFormat;
}
var boundary=this._getWordBoundaryRegExp;
if(this.loc.timeFormat.match(boundary('aa')) ||
this.loc.timeFormat.match(boundary('AA'))
){
this.ampm=true;
}},
_buildDatepickersContainer: function (){
containerBuilt=true;
$body.append('<div class="airdatepickers-container" id="airdatepickers-container"></div>');
$airdatepickersContainer=$('#airdatepickers-container');
},
_buildBaseHtml: function (){
var $appendTarget,
$inline=$('<div class="airdatepicker-inline">');
if(this.el.nodeName=='INPUT'){
if(!this.opts.inline){
if(!this.opts.inline_popup) $appendTarget=$airdatepickersContainer;
else $appendTarget=jQuery(this.$el).parent();
}else{
$appendTarget=$inline.insertAfter(this.$el)
}}else{
$appendTarget=$inline.appendTo(this.$el)
}
this.$airdatepicker=$(baseTemplate).appendTo($appendTarget);
this.$content=$('.airdatepicker--content', this.$airdatepicker);
this.$nav=$('.airdatepicker--nav', this.$airdatepicker);
},
_triggerOnChange: function (){
if(!this.selectedDates.length){
if(this._prevOnSelectValue==='') return;
this._prevOnSelectValue='';
return this.opts.onSelect('', '', this);
}
var selectedDates=this.selectedDates,
parsedSelected=airdatepicker.getParsedDate(selectedDates[0]),
formattedDates,
_this=this,
dates=new Date(
parsedSelected.year,
parsedSelected.month,
parsedSelected.date,
parsedSelected.hours,
parsedSelected.minutes
);
formattedDates=selectedDates.map(function (date){
return _this.formatDate(_this.loc.dateFormat, date)
}).join(this.opts.multipleDatesSeparator);
if(this.opts.multipleDates||this.opts.range){
dates=selectedDates.map(function(date){
var parsedDate=airdatepicker.getParsedDate(date);
return new Date(
parsedDate.year,
parsedDate.month,
parsedDate.date,
parsedDate.hours,
parsedDate.minutes
);
})
}
this._prevOnSelectValue=formattedDates;
this.opts.onSelect(formattedDates, dates, this);
},
next: function (){
var d=this.parsedDate,
o=this.opts;
switch (this.view){
case 'days':
this.date=new Date(d.year, d.month + 1, 1);
if(o.onChangeMonth) o.onChangeMonth(this.parsedDate.month, this.parsedDate.year);
break;
case 'months':
this.date=new Date(d.year + 1, d.month, 1);
if(o.onChangeYear) o.onChangeYear(this.parsedDate.year);
break;
case 'years':
this.date=new Date(d.year + 10, 0, 1);
if(o.onChangeDecade) o.onChangeDecade(this.curDecade);
break;
}},
prev: function (){
var d=this.parsedDate,
o=this.opts;
switch (this.view){
case 'days':
this.date=new Date(d.year, d.month - 1, 1);
if(o.onChangeMonth) o.onChangeMonth(this.parsedDate.month, this.parsedDate.year);
break;
case 'months':
this.date=new Date(d.year - 1, d.month, 1);
if(o.onChangeYear) o.onChangeYear(this.parsedDate.year);
break;
case 'years':
this.date=new Date(d.year - 10, 0, 1);
if(o.onChangeDecade) o.onChangeDecade(this.curDecade);
break;
}},
formatDate: function (string, date){
date=date||this.date;
var result=string,
boundary=this._getWordBoundaryRegExp,
locale=this.loc,
leadingZero=airdatepicker.getLeadingZeroNum,
decade=airdatepicker.getDecade(date),
d=airdatepicker.getParsedDate(date),
fullHours=d.fullHours,
hours=d.hours,
ampm=string.match(boundary('aa'))||string.match(boundary('AA')),
dayPeriod='am',
replacer=this._replacer,
validHours;
if(this.opts.timepicker&&this.timepicker&&ampm){
validHours=this.timepicker._getValidHoursFromDate(date, ampm);
fullHours=leadingZero(validHours.hours);
hours=validHours.hours;
dayPeriod=validHours.dayPeriod;
}
switch (true){
case /@/.test(result):
result=result.replace(/@/, date.getTime());
case /aa/.test(result):
result=replacer(result, boundary('aa'), dayPeriod);
case /AA/.test(result):
result=replacer(result, boundary('AA'), dayPeriod.toUpperCase());
case /dd/.test(result):
result=replacer(result, boundary('dd'), d.fullDate);
case /d/.test(result):
result=replacer(result, boundary('d'), d.date);
case /DD/.test(result):
result=replacer(result, boundary('DD'), locale.days[d.day]);
case /D/.test(result):
result=replacer(result, boundary('D'), locale.daysShort[d.day]);
case /mm/.test(result):
result=replacer(result, boundary('mm'), d.fullMonth);
case /m/.test(result):
result=replacer(result, boundary('m'), d.month + 1);
case /MM/.test(result):
result=replacer(result, boundary('MM'), this.loc.months[d.month]);
case /M/.test(result):
result=replacer(result, boundary('M'), locale.monthsShort[d.month]);
case /ii/.test(result):
result=replacer(result, boundary('ii'), d.fullMinutes);
case /i/.test(result):
result=replacer(result, boundary('i'), d.minutes);
case /hh/.test(result):
result=replacer(result, boundary('hh'), fullHours);
case /h/.test(result):
result=replacer(result, boundary('h'), hours);
case /yyyy/.test(result):
result=replacer(result, boundary('yyyy'), d.year);
case /yyyy1/.test(result):
result=replacer(result, boundary('yyyy1'), decade[0]);
case /yyyy2/.test(result):
result=replacer(result, boundary('yyyy2'), decade[1]);
case /yy/.test(result):
result=replacer(result, boundary('yy'), d.year.toString().slice(-2));
}
return result;
},
_replacer: function (str, reg, data){
return str.replace(reg, function (match, p1,p2,p3){
return p1 + data + p3;
})
},
_getWordBoundaryRegExp: function (sign){
var symbols='\\s|\\.|-|/|\\\\|,|\\$|\\!|\\?|:|;';
return new RegExp('(^|>|' + symbols + ')(' + sign + ')($|<|' + symbols + ')', 'g');
},
selectDate: function (date){
var _this=this,
opts=_this.opts,
d=_this.parsedDate,
selectedDates=_this.selectedDates,
len=selectedDates.length,
newDate='';
if(Array.isArray(date)){
date.forEach(function (d){
_this.selectDate(d)
});
return;
}
if(!(date instanceof Date)) return;
this.lastSelectedDate=date;
if(this.timepicker){
this.timepicker._setTime(date);
}
_this._trigger('selectDate', date);
if(this.timepicker){
date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes)
}
if(_this.view=='days'){
if(date.getMonth()!=d.month&&opts.moveToOtherMonthsOnSelect){
newDate=new Date(date.getFullYear(), date.getMonth(), 1);
}}
if(_this.view=='years'){
if(date.getFullYear()!=d.year&&opts.moveToOtherYearsOnSelect){
newDate=new Date(date.getFullYear(), 0, 1);
}}
if(newDate){
_this.silent=true;
_this.date=newDate;
_this.silent=false;
_this.nav._render()
}
if(opts.multipleDates&&!opts.range){
if(len===opts.multipleDates) return;
if(!_this._isSelected(date)){
_this.selectedDates.push(date);
}}else if(opts.range){
if(len==2){
_this.selectedDates=[date];
_this.minRange=date;
_this.maxRange='';
}else if(len==1){
_this.selectedDates.push(date);
if(!_this.maxRange){
_this.maxRange=date;
}else{
_this.minRange=date;
}
if(airdatepicker.bigger(_this.maxRange, _this.minRange)){
_this.maxRange=_this.minRange;
_this.minRange=date;
}
_this.selectedDates=[_this.minRange, _this.maxRange]
}else{
_this.selectedDates=[date];
_this.minRange=date;
}}else{
_this.selectedDates=[date];
}
_this._setInputValue();
if(opts.onSelect){
_this._triggerOnChange();
}
if(opts.autoClose&&!this.timepickerIsActive){
if(!opts.multipleDates&&!opts.range){
_this.hide();
}else if(opts.range&&_this.selectedDates.length==2){
_this.hide();
}}
_this.views[this.currentView]._render()
},
removeDate: function (date){
var selected=this.selectedDates,
_this=this;
if(!(date instanceof Date)) return;
return selected.some(function (curDate, i){
if(airdatepicker.isSame(curDate, date)){
selected.splice(i, 1);
if(!_this.selectedDates.length){
_this.minRange='';
_this.maxRange='';
_this.lastSelectedDate='';
}else{
_this.lastSelectedDate=_this.selectedDates[_this.selectedDates.length - 1];
}
_this.views[_this.currentView]._render();
_this._setInputValue();
if(_this.opts.onSelect){
_this._triggerOnChange();
}
return true
}})
},
today: function (){
this.silent=true;
this.view=this.opts.minView;
this.silent=false;
this.date=new Date();
if(this.opts.todayButton instanceof Date){
this.selectDate(this.opts.todayButton)
}},
clear: function (){
this.selectedDates=[];
this.minRange='';
this.maxRange='';
this.views[this.currentView]._render();
this._setInputValue();
if(this.opts.onSelect){
this._triggerOnChange()
}},
update: function (param, value){
var len=arguments.length,
lastSelectedDate=this.lastSelectedDate;
if(len==2){
this.opts[param]=value;
}else if(len==1&&typeof param=='object'){
this.opts=$.extend(true, this.opts, param)
}
this._createShortCuts();
this._syncWithMinMaxDates();
this._defineLocale(this.opts.language);
this.nav._addButtonsIfNeed();
if(!this.opts.onlyTimepicker) this.nav._render();
this.views[this.currentView]._render();
if(this.elIsInput&&!this.opts.inline){
this._setPositionClasses(this.opts.position);
if(this.visible){
this.setPosition(this.opts.position)
}}
if(this.opts.classes){
this.$airdatepicker.addClass(this.opts.classes)
}
if(this.opts.onlyTimepicker){
this.$airdatepicker.addClass('-only-timepicker-');
}
if(this.opts.timepicker){
if(lastSelectedDate) this.timepicker._handleDate(lastSelectedDate);
this.timepicker._updateRanges();
this.timepicker._updateCurrentTime();
if(lastSelectedDate){
lastSelectedDate.setHours(this.timepicker.hours);
lastSelectedDate.setMinutes(this.timepicker.minutes);
}}
this._setInputValue();
return this;
},
_syncWithMinMaxDates: function (){
var curTime=this.date.getTime();
this.silent=true;
if(this.minTime > curTime){
this.date=this.minDate;
}
if(this.maxTime < curTime){
this.date=this.maxDate;
}
this.silent=false;
},
_isSelected: function (checkDate, cellType){
var res=false;
this.selectedDates.some(function (date){
if(airdatepicker.isSame(date, checkDate, cellType)){
res=date;
return true;
}});
return res;
},
_setInputValue: function (){
var _this=this,
opts=_this.opts,
format=_this.loc.dateFormat,
altFormat=opts.altFieldDateFormat,
value=_this.selectedDates.map(function (date){
return _this.formatDate(format, date)
}),
altValues;
if(opts.altField&&_this.$altField.length){
altValues=this.selectedDates.map(function (date){
return _this.formatDate(altFormat, date)
});
altValues=altValues.join(this.opts.multipleDatesSeparator);
this.$altField.val(altValues);
}
value=value.join(this.opts.multipleDatesSeparator);
this.$el.val(value)
},
_isInRange: function (date, type){
var time=date.getTime(),
d=airdatepicker.getParsedDate(date),
min=airdatepicker.getParsedDate(this.minDate),
max=airdatepicker.getParsedDate(this.maxDate),
dMinTime=new Date(d.year, d.month, min.date).getTime(),
dMaxTime=new Date(d.year, d.month, max.date).getTime(),
types={
day: time >=this.minTime&&time <=this.maxTime,
month: dMinTime >=this.minTime&&dMaxTime <=this.maxTime,
year: d.year >=min.year&&d.year <=max.year
};
return type ? types[type]:types.day
},
_getDimensions: function ($el){
var offset=$el.offset();
return {
width: $el.outerWidth(),
height: $el.outerHeight(),
left: offset.left,
top: offset.top
}},
_getDateFromCell: function (cell){
var curDate=this.parsedDate,
year=cell.data('year')||curDate.year,
month=cell.data('month')==undefined ? curDate.month:cell.data('month'),
date=cell.data('date')||1;
return new Date(year, month, date);
},
_setPositionClasses: function (pos){
pos=pos.split(' ');
var main=pos[0],
sec=pos[1],
classes='airdatepicker -' + main + '-' + sec + '- -from-' + main + '-';
if(this.visible) classes +=' active';
this.$airdatepicker
.removeAttr('class')
.addClass(classes);
},
setPosition: function (position){
position=position||this.opts.position;
var dims=this._getDimensions(this.$el),
selfDims=this._getDimensions(this.$airdatepicker),
pos=position.split(' '),
top, left,
offset=this.opts.offset,
main=pos[0],
secondary=pos[1];
if(this.opts.inline_popup){
dims.left=0;
dims.top=0;
}
switch (main){
case 'top':
top=dims.top - selfDims.height - offset;
break;
case 'right':
left=dims.left + dims.width + offset;
break;
case 'bottom':
top=dims.top + dims.height + offset;
break;
case 'left':
left=dims.left - selfDims.width - offset;
break;
}
switch(secondary){
case 'top':
top=dims.top;
break;
case 'right':
left=dims.left + dims.width - selfDims.width;
break;
case 'bottom':
top=dims.top + dims.height - selfDims.height;
break;
case 'left':
left=dims.left;
break;
case 'center':
if(/left|right/.test(main)){
top=dims.top + dims.height/2 - selfDims.height/2;
}else{
left=dims.left + dims.width/2 - selfDims.width/2;
}}
this.$airdatepicker
.css({
left: left,
top: top
})
},
show: function (){
var onShow=this.opts.onShow;
this.setPosition(this.opts.position);
this.$airdatepicker.addClass('active');
this.visible=true;
if(onShow){
this._bindVisionEvents(onShow)
}},
hide: function (){
var onHide=this.opts.onHide;
this.$airdatepicker
.removeClass('active')
.css({
left: '-100000px'
});
this.focused='';
this.keys=[];
this.inFocus=false;
this.visible=false;
this.$el.blur();
if(onHide){
this._bindVisionEvents(onHide)
}},
down: function (date){
this._changeView(date, 'down');
},
up: function (date){
this._changeView(date, 'up');
},
_bindVisionEvents: function (event){
this.$airdatepicker.off('transitionend.dp');
event(this, false);
this.$airdatepicker.one('transitionend.dp', event.bind(this, this, true))
},
_changeView: function (date, dir){
date=date||this.focused||this.date;
var nextView=dir=='up' ? this.viewIndex + 1:this.viewIndex - 1;
if(nextView > 2) nextView=2;
if(nextView < 0) nextView=0;
this.silent=true;
this.date=new Date(date.getFullYear(), date.getMonth(), 1);
this.silent=false;
this.view=this.viewIndexes[nextView];
},
_handleHotKey: function (key){
var date=airdatepicker.getParsedDate(this._getFocusedDate()),
focusedParsed,
o=this.opts,
newDate,
totalDaysInNextMonth,
monthChanged=false,
yearChanged=false,
decadeChanged=false,
y=date.year,
m=date.month,
d=date.date;
switch (key){
case 'ctrlRight':
case 'ctrlUp':
m +=1;
monthChanged=true;
break;
case 'ctrlLeft':
case 'ctrlDown':
m -=1;
monthChanged=true;
break;
case 'shiftRight':
case 'shiftUp':
yearChanged=true;
y +=1;
break;
case 'shiftLeft':
case 'shiftDown':
yearChanged=true;
y -=1;
break;
case 'altRight':
case 'altUp':
decadeChanged=true;
y +=10;
break;
case 'altLeft':
case 'altDown':
decadeChanged=true;
y -=10;
break;
case 'ctrlShiftUp':
this.up();
break;
}
totalDaysInNextMonth=airdatepicker.getDaysCount(new Date(y,m));
newDate=new Date(y,m,d);
if(totalDaysInNextMonth < d) d=totalDaysInNextMonth;
if(newDate.getTime() < this.minTime){
newDate=this.minDate;
}else if(newDate.getTime() > this.maxTime){
newDate=this.maxDate;
}
this.focused=newDate;
focusedParsed=airdatepicker.getParsedDate(newDate);
if(monthChanged&&o.onChangeMonth){
o.onChangeMonth(focusedParsed.month, focusedParsed.year)
}
if(yearChanged&&o.onChangeYear){
o.onChangeYear(focusedParsed.year)
}
if(decadeChanged&&o.onChangeDecade){
o.onChangeDecade(this.curDecade)
}},
_registerKey: function (key){
var exists=this.keys.some(function (curKey){
return curKey==key;
});
if(!exists){
this.keys.push(key)
}},
_unRegisterKey: function (key){
var index=this.keys.indexOf(key);
this.keys.splice(index, 1);
},
_isHotKeyPressed: function (){
var currentHotKey,
found=false,
_this=this,
pressedKeys=this.keys.sort();
for (var hotKey in hotKeys){
currentHotKey=hotKeys[hotKey];
if(pressedKeys.length!=currentHotKey.length) continue;
if(currentHotKey.every(function (key, i){ return key==pressedKeys[i]})){
_this._trigger('hotKey', hotKey);
found=true;
}}
return found;
},
_trigger: function (event, args){
this.$el.trigger(event, args)
},
_focusNextCell: function (keyCode, type){
type=type||this.cellType;
var date=airdatepicker.getParsedDate(this._getFocusedDate()),
y=date.year,
m=date.month,
d=date.date;
if(this._isHotKeyPressed()){
return;
}
switch(keyCode){
case 37:
type=='day' ? (d -=1):'';
type=='month' ? (m -=1):'';
type=='year' ? (y -=1):'';
break;
case 38:
type=='day' ? (d -=7):'';
type=='month' ? (m -=3):'';
type=='year' ? (y -=4):'';
break;
case 39:
type=='day' ? (d +=1):'';
type=='month' ? (m +=1):'';
type=='year' ? (y +=1):'';
break;
case 40:
type=='day' ? (d +=7):'';
type=='month' ? (m +=3):'';
type=='year' ? (y +=4):'';
break;
}
var nd=new Date(y,m,d);
if(nd.getTime() < this.minTime){
nd=this.minDate;
}else if(nd.getTime() > this.maxTime){
nd=this.maxDate;
}
this.focused=nd;
},
_getFocusedDate: function (){
var focused=this.focused||this.selectedDates[this.selectedDates.length - 1],
d=this.parsedDate;
if(!focused){
switch (this.view){
case 'days':
focused=new Date(d.year, d.month, new Date().getDate());
break;
case 'months':
focused=new Date(d.year, d.month, 1);
break;
case 'years':
focused=new Date(d.year, 0, 1);
break;
}}
return focused;
},
_getCell: function (date, type){
type=type||this.cellType;
var d=airdatepicker.getParsedDate(date),
selector='.airdatepicker--cell[data-year="' + d.year + '"]',
$cell;
switch (type){
case 'month':
selector='[data-month="' + d.month + '"]';
break;
case 'day':
selector +='[data-month="' + d.month + '"][data-date="' + d.date + '"]';
break;
}
$cell=this.views[this.currentView].$el.find(selector);
return $cell.length ? $cell:$('');
},
destroy: function (){
var _this=this;
_this.$el
.off('.adp')
.data('airdatepicker', '');
_this.selectedDates=[];
_this.focused='';
_this.views={};
_this.keys=[];
_this.minRange='';
_this.maxRange='';
if(_this.opts.inline||!_this.elIsInput){
_this.$airdatepicker.closest('.airdatepicker-inline').remove();
}else{
_this.$airdatepicker.remove();
}},
_handleAlreadySelectedDates: function (alreadySelected, selectedDate){
if(this.opts.range){
if(!this.opts.toggleSelected){
if(this.selectedDates.length!=2){
this._trigger('clickCell', selectedDate);
}}else{
this.removeDate(selectedDate);
}}else if(this.opts.toggleSelected){
this.removeDate(selectedDate);
}
if(!this.opts.toggleSelected){
this.lastSelectedDate=alreadySelected;
if(this.opts.timepicker){
this.timepicker._setTime(alreadySelected);
this.timepicker.update();
}}
},
_onShowEvent: function (e){
if(!this.visible){
this.show();
}},
_onBlur: function (){
if(!this.inFocus&&this.visible){
this.hide();
}},
_onMouseDownDatepicker: function (e){
this.inFocus=true;
},
_onMouseUpDatepicker: function (e){
this.inFocus=false;
e.originalEvent.inFocus=true;
if(!e.originalEvent.timepickerFocus) this.$el.focus();
},
_onKeyUpGeneral: function (e){
var val=this.$el.val();
if(!val){
this.clear();
}},
_onResize: function (){
if(this.visible){
this.setPosition();
}},
_onMouseUpBody: function (e){
if(e.originalEvent.inFocus) return;
if(this.visible&&!this.inFocus){
this.hide();
}},
_onMouseUpEl: function (e){
e.originalEvent.inFocus=true;
setTimeout(this._onKeyUpGeneral.bind(this),4);
},
_onKeyDown: function (e){
var code=e.which;
this._registerKey(code);
if(code >=37&&code <=40){
e.preventDefault();
this._focusNextCell(code);
}
if(code==13){
if(this.focused){
if(this._getCell(this.focused).hasClass('-disabled-')) return;
if(this.view!=this.opts.minView){
this.down()
}else{
var alreadySelected=this._isSelected(this.focused, this.cellType);
if(!alreadySelected){
if(this.timepicker){
this.focused.setHours(this.timepicker.hours);
this.focused.setMinutes(this.timepicker.minutes);
}
this.selectDate(this.focused);
return;
}
this._handleAlreadySelectedDates(alreadySelected, this.focused)
}}
}
if(code==27){
this.hide();
}},
_onKeyUp: function (e){
var code=e.which;
this._unRegisterKey(code);
},
_onHotKey: function (e, hotKey){
this._handleHotKey(hotKey);
},
_onMouseEnterCell: function (e){
var $cell=$(e.target).closest('.airdatepicker--cell'),
date=this._getDateFromCell($cell);
this.silent=true;
if(this.focused){
this.focused=''
}
$cell.addClass('-focus-');
this.focused=date;
this.silent=false;
if(this.opts.range&&this.selectedDates.length==1){
this.minRange=this.selectedDates[0];
this.maxRange='';
if(airdatepicker.less(this.minRange, this.focused)){
this.maxRange=this.minRange;
this.minRange='';
}
this.views[this.currentView]._update();
}},
_onMouseLeaveCell: function (e){
var $cell=$(e.target).closest('.airdatepicker--cell');
$cell.removeClass('-focus-');
this.silent=true;
this.focused='';
this.silent=false;
},
_onTimeChange: function (e, h, m){
var date=new Date(),
selectedDates=this.selectedDates,
selected=false;
if(selectedDates.length){
selected=true;
date=this.lastSelectedDate;
}
date.setHours(h);
date.setMinutes(m);
if(!selected&&!this._getCell(date).hasClass('-disabled-')){
this.selectDate(date);
}else{
this._setInputValue();
if(this.opts.onSelect){
this._triggerOnChange();
}}
},
_onClickCell: function (e, date){
if(this.timepicker){
date.setHours(this.timepicker.hours);
date.setMinutes(this.timepicker.minutes);
}
this.selectDate(date);
},
set focused(val){
if(!val&&this.focused){
var $cell=this._getCell(this.focused);
if($cell.length){
$cell.removeClass('-focus-')
}}
this._focused=val;
if(this.opts.range&&this.selectedDates.length==1){
this.minRange=this.selectedDates[0];
this.maxRange='';
if(airdatepicker.less(this.minRange, this._focused)){
this.maxRange=this.minRange;
this.minRange='';
}}
if(this.silent) return;
this.date=val;
},
get focused(){
return this._focused;
},
get parsedDate(){
return airdatepicker.getParsedDate(this.date);
},
set date (val){
if(!(val instanceof Date)) return;
this.currentDate=val;
if(this.inited&&!this.silent){
this.views[this.view]._render();
this.nav._render();
if(this.visible&&this.elIsInput){
this.setPosition();
}}
return val;
},
get date (){
return this.currentDate
},
set view (val){
this.viewIndex=this.viewIndexes.indexOf(val);
if(this.viewIndex < 0){
return;
}
this.prevView=this.currentView;
this.currentView=val;
if(this.inited){
if(!this.views[val]){
this.views[val]=new  $.fn.airdatepicker.Body(this, val, this.opts)
}else{
this.views[val]._render();
}
this.views[this.prevView].hide();
this.views[val].show();
this.nav._render();
if(this.opts.onChangeView){
this.opts.onChangeView(val)
}
if(this.elIsInput&&this.visible) this.setPosition();
}
return val
},
get view(){
return this.currentView;
},
get cellType(){
return this.view.substring(0, this.view.length - 1)
},
get minTime(){
var min=airdatepicker.getParsedDate(this.minDate);
return new Date(min.year, min.month, min.date).getTime()
},
get maxTime(){
var max=airdatepicker.getParsedDate(this.maxDate);
return new Date(max.year, max.month, max.date).getTime()
},
get curDecade(){
return airdatepicker.getDecade(this.date)
}};
airdatepicker.getDaysCount=function (date){
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
};
airdatepicker.getParsedDate=function (date){
return {
year: date.getFullYear(),
month: date.getMonth(),
fullMonth: (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1):date.getMonth() + 1,
date: date.getDate(),
fullDate: date.getDate() < 10 ? '0' + date.getDate():date.getDate(),
day: date.getDay(),
hours: date.getHours(),
fullHours:  date.getHours() < 10 ? '0' + date.getHours():date.getHours() ,
minutes: date.getMinutes(),
fullMinutes:  date.getMinutes() < 10 ? '0' + date.getMinutes():date.getMinutes()
}};
airdatepicker.getDecade=function (date){
var firstYear=Math.floor(date.getFullYear() / 10) * 10;
return [firstYear, firstYear + 9];
};
airdatepicker.template=function (str, data){
return str.replace(/#\{([\w]+)\}/g, function (source, match){
if(data[match]||data[match]===0){
return data[match]
}});
};
airdatepicker.isSame=function (date1, date2, type){
if(!date1||!date2) return false;
var d1=airdatepicker.getParsedDate(date1),
d2=airdatepicker.getParsedDate(date2),
_type=type ? type:'day',
conditions={
day: d1.date==d2.date&&d1.month==d2.month&&d1.year==d2.year,
month: d1.month==d2.month&&d1.year==d2.year,
year: d1.year==d2.year
};
return conditions[_type];
};
airdatepicker.less=function (dateCompareTo, date, type){
if(!dateCompareTo||!date) return false;
return date.getTime() < dateCompareTo.getTime();
};
airdatepicker.bigger=function (dateCompareTo, date, type){
if(!dateCompareTo||!date) return false;
return date.getTime() > dateCompareTo.getTime();
};
airdatepicker.getLeadingZeroNum=function (num){
return parseInt(num) < 10 ? '0' + num:num;
};
airdatepicker.resetTime=function (date){
if(typeof date!='object') return;
date=airdatepicker.getParsedDate(date);
return new Date(date.year, date.month, date.date)
};
$.fn.airdatepicker=function(options){
return this.each(function (){
if(!$.data(this, pluginName)){
$.data(this,  pluginName,
new Datepicker(this, options));
}else{
var _this=$.data(this, pluginName);
_this.opts=$.extend(true, _this.opts, options);
_this.update();
}});
};
$.fn.airdatepicker.Constructor=Datepicker;
$.fn.airdatepicker.language={
en: {
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
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'],
today: 'Today',
clear: 'Clear',
dateFormat: 'mm/dd/yyyy',
timeFormat: 'hh:ii aa',
firstDay: 0
},
cs: {
days: ['Neděle', 'Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota'],
daysShort: ['Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'],
daysMin: ['Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'],
months: ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'],
monthsShort: ['Led', 'Úno', 'Bře', 'Dub', 'Kvě', 'Čvn', 'Čvc', 'Srp', 'Zář', 'Říj', 'Lis', 'Pro'],
today: 'Dnes',
clear: 'Vymazat',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
da: {
days: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag'],
daysShort: ['Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'],
daysMin: ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø'],
months: ['Januar','Februar','Marts','April','Maj','Juni', 'Juli','August','September','Oktober','November','December'],
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'],
today: 'I dag',
clear: 'Nulstil',
dateFormat: 'dd/mm/yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
de: {
days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
daysShort: ['Son', 'Mon', 'Die', 'Mit', 'Don', 'Fre', 'Sam'],
daysMin: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
months: ['Januar','Februar','März','April','Mai','Juni', 'Juli','August','September','Oktober','November','Dezember'],
monthsShort: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
today: 'Heute',
clear: 'Aufräumen',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
es: {
days: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
daysShort: ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'],
daysMin: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
months: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', 'Julio','Augosto','Septiembre','Octubre','Noviembre','Diciembre'],
monthsShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
today: 'Hoy',
clear: 'Limpiar',
dateFormat: 'dd/mm/yyyy',
timeFormat: 'hh:ii aa',
firstDay: 1
},
fi: {
days: ['Sunnuntai', 'Maanantai', 'Tiistai', 'Keskiviikko', 'Torstai', 'Perjantai', 'Lauantai'],
daysShort: ['Su', 'Ma', 'Ti', 'Ke', 'To', 'Pe', 'La'],
daysMin: ['Su', 'Ma', 'Ti', 'Ke', 'To', 'Pe', 'La'],
months: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'],
monthsShort: ['Tammi', 'Helmi', 'Maalis', 'Huhti', 'Touko', 'Kesä', 'Heinä', 'Elo', 'Syys', 'Loka', 'Marras', 'Joulu'],
today: 'Tänään',
clear: 'Tyhjennä',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
fr: {
days: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
daysShort: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
daysMin: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],
months: ['Janvier','Février','Mars','Avril','Mai','Juin', 'Juillet','Août','Septembre','Octobre','Novembre','Decembre'],
monthsShort: ['Jan', 'Fév', 'Mars', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Dec'],
today: "Aujourd'hui",
clear: 'Effacer',
dateFormat: 'dd/mm/yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
hu: {
days: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'],
daysShort: ['Va', 'Hé', 'Ke', 'Sze', 'Cs', 'Pé', 'Szo'],
daysMin: ['V', 'H', 'K', 'Sz', 'Cs', 'P', 'Sz'],
months: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'],
monthsShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'],
today: 'Ma',
clear: 'Törlés',
dateFormat: 'yyyy-mm-dd',
timeFormat: 'hh:ii aa',
firstDay: 1
},
it: {
days: ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'],
daysShort: ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'],
daysMin: ['Do', 'Lu', 'Ma', 'Me', 'Gi', 'Ve', 'Sa'],
months: ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
monthsShort: ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'],
today: 'Oggi',
clear: 'Pulisci',
dateFormat: 'dd/mm/yyyy',
timeFormat: 'hh:ii aa',
firstDay: 1
},
nl: {
days: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
daysShort: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
daysMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
months: ['Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December'],
monthsShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'],
today: 'Vandaag',
clear: 'Legen',
dateFormat: 'dd-mm-yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
pl: {
days: ['Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'],
daysShort: ['Nie', 'Pon', 'Wto', 'Śro', 'Czw', 'Pią', 'Sob'],
daysMin: ['Nd', 'Pn', 'Wt', 'Śr', 'Czw', 'Pt', 'So'],
months: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec', 'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'],
monthsShort: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'],
today: 'Dzisiaj',
clear: 'Wyczyść',
dateFormat: 'yyyy-mm-dd',
timeFormat: 'hh:ii aa',
firstDay: 1
},
pt: {
days: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'],
daysShort: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'],
daysMin: ['Do', 'Se', 'Te', 'Qa', 'Qi', 'Sx', 'Sa'],
months: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
monthsShort: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
today: 'Hoje',
clear: 'Limpar',
dateFormat: 'dd/mm/yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
ro: {
days: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'],
daysShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'],
daysMin: ['D', 'L', 'Ma', 'Mi', 'J', 'V', 'S'],
months: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie','Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'],
monthsShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'],
today: 'Azi',
clear: 'Şterge',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
ru: {
days: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],
daysShort: ['Вос','Пон','Вто','Сре','Чет','Пят','Суб'],
daysMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
months: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
monthsShort: ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'],
today: 'Сегодня',
clear: 'Очистить',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
sk: {
days: ['Nedeľa', 'Pondelok', 'Utorok', 'Streda', 'Štvrtok', 'Piatok', 'Sobota'],
daysShort: ['Ned', 'Pon', 'Uto', 'Str', 'Štv', 'Pia', 'Sob'],
daysMin: ['Ne', 'Po', 'Ut', 'St', 'Št', 'Pi', 'So'],
months: ['Január','Február','Marec','Apríl','Máj','Jún', 'Júl','August','September','Október','November','December'],
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'Máj', 'Jún', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'],
today: 'Dnes',
clear: 'Vymazať',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
tr: {
days: ['Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi'],
daysShort: ['Paz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cmt'],
daysMin: ['Pz', 'Pt', 'Sa', 'Ça', 'Pe', 'Cu', 'Ct'],
months: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran', 'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'],
monthsShort: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara'],
today: 'Bugün',
clear: 'Temizle',
dateFormat: 'dd.mm.yyyy',
timeFormat: 'hh:ii',
firstDay: 1
},
zh: {
days: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
daysShort: ['日', '一', '二', '三', '四', '五', '六'],
daysMin: ['日', '一', '二', '三', '四', '五', '六'],
months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
monthsShort: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
today: '今天',
clear: '清除',
dateFormat: 'yyyy-mm-dd',
timeFormat: 'hh:ii',
firstDay: 1
}};
$(function (){
$(autoInitSelector).airdatepicker();
})
})();
;(function (){
var templates={
days:'' +
'<div class="airdatepicker--days airdatepicker--body">' +
'<div class="airdatepicker--days-names"></div>' +
'<div class="airdatepicker--cells airdatepicker--cells-days"></div>' +
'</div>',
months: '' +
'<div class="airdatepicker--months airdatepicker--body">' +
'<div class="airdatepicker--cells airdatepicker--cells-months"></div>' +
'</div>',
years: '' +
'<div class="airdatepicker--years airdatepicker--body">' +
'<div class="airdatepicker--cells airdatepicker--cells-years"></div>' +
'</div>'
},
airdatepicker=$.fn.airdatepicker,
dp=airdatepicker.Constructor;
airdatepicker.Body=function (d, type, opts){
this.d=d;
this.type=type;
this.opts=opts;
this.$el=$('');
if(this.opts.onlyTimepicker) return;
this.init();
};
airdatepicker.Body.prototype={
init: function (){
this._buildBaseHtml();
this._render();
this._bindEvents();
},
_bindEvents: function (){
this.$el.on('click', '.airdatepicker--cell', $.proxy(this._onClickCell, this));
},
_buildBaseHtml: function (){
this.$el=$(templates[this.type]).appendTo(this.d.$content);
this.$names=$('.airdatepicker--days-names', this.$el);
this.$cells=$('.airdatepicker--cells', this.$el);
},
_getDayNamesHtml: function (firstDay, curDay, html, i){
curDay=curDay!=undefined ? curDay:firstDay;
html=html ? html:'';
i=i!=undefined ? i:0;
if(i > 7) return html;
if(curDay==7) return this._getDayNamesHtml(firstDay, 0, html, ++i);
html +='<div class="airdatepicker--day-name' + (this.d.isWeekend(curDay) ? " -weekend-":"") + '">' + this.d.loc.daysMin[curDay] + '</div>';
return this._getDayNamesHtml(firstDay, ++curDay, html, ++i);
},
_getCellContents: function (date, type){
var classes="airdatepicker--cell airdatepicker--cell-" + type,
currentDate=new Date(),
parent=this.d,
minRange=dp.resetTime(parent.minRange),
maxRange=dp.resetTime(parent.maxRange),
opts=parent.opts,
d=dp.getParsedDate(date),
render={},
html=d.date;
switch (type){
case 'day':
if(parent.isWeekend(d.day)) classes +=" -weekend-";
if(d.month!=this.d.parsedDate.month){
classes +=" -other-month-";
if(!opts.selectOtherMonths){
classes +=" -disabled-";
}
if(!opts.showOtherMonths) html='';
}
break;
case 'month':
html=parent.loc[parent.opts.monthsField][d.month];
break;
case 'year':
var decade=parent.curDecade;
html=d.year;
if(d.year < decade[0]||d.year > decade[1]){
classes +=' -other-decade-';
if(!opts.selectOtherYears){
classes +=" -disabled-";
}
if(!opts.showOtherYears) html='';
}
break;
}
if(opts.onRenderCell){
render=opts.onRenderCell(date, type)||{};
html=render.html ? render.html:html;
classes +=render.classes ? ' ' + render.classes:'';
}
if(opts.range){
if(dp.isSame(minRange, date, type)) classes +=' -range-from-';
if(dp.isSame(maxRange, date, type)) classes +=' -range-to-';
if(parent.selectedDates.length==1&&parent.focused){
if((dp.bigger(minRange, date)&&dp.less(parent.focused, date)) ||
(dp.less(maxRange, date)&&dp.bigger(parent.focused, date))){
classes +=' -in-range-'
}
if(dp.less(maxRange, date)&&dp.isSame(parent.focused, date)){
classes +=' -range-from-'
}
if(dp.bigger(minRange, date)&&dp.isSame(parent.focused, date)){
classes +=' -range-to-'
}}else if(parent.selectedDates.length==2){
if(dp.bigger(minRange, date)&&dp.less(maxRange, date)){
classes +=' -in-range-'
}}
}
if(dp.isSame(currentDate, date, type)) classes +=' -current-';
if(parent.focused&&dp.isSame(date, parent.focused, type)) classes +=' -focus-';
if(parent._isSelected(date, type)) classes +=' -selected-';
if(!parent._isInRange(date, type)||render.disabled) classes +=' -disabled-';
return {
html: html,
classes: classes
}},
_getDaysHtml: function (date){
var totalMonthDays=dp.getDaysCount(date),
firstMonthDay=new Date(date.getFullYear(), date.getMonth(), 1).getDay(),
lastMonthDay=new Date(date.getFullYear(), date.getMonth(), totalMonthDays).getDay(),
daysFromPevMonth=firstMonthDay - this.d.loc.firstDay,
daysFromNextMonth=6 - lastMonthDay + this.d.loc.firstDay;
daysFromPevMonth=daysFromPevMonth < 0 ? daysFromPevMonth + 7:daysFromPevMonth;
daysFromNextMonth=daysFromNextMonth > 6 ? daysFromNextMonth - 7:daysFromNextMonth;
var startDayIndex=-daysFromPevMonth + 1,
m, y,
html='';
for (var i=startDayIndex, max=totalMonthDays + daysFromNextMonth; i <=max; i++){
y=date.getFullYear();
m=date.getMonth();
html +=this._getDayHtml(new Date(y, m, i))
}
return html;
},
_getDayHtml: function (date){
var content=this._getCellContents(date, 'day');
return '<div class="' + content.classes + '" ' +
'data-date="' + date.getDate() + '" ' +
'data-month="' + date.getMonth() + '" ' +
'data-year="' + date.getFullYear() + '">' + content.html + '</div>';
},
_getMonthsHtml: function (date){
var html='',
d=dp.getParsedDate(date),
i=0;
while(i < 12){
html +=this._getMonthHtml(new Date(d.year, i));
i++
}
return html;
},
_getMonthHtml: function (date){
var content=this._getCellContents(date, 'month');
return '<div class="' + content.classes + '" data-month="' + date.getMonth() + '">' + content.html + '</div>'
},
_getYearsHtml: function (date){
var d=dp.getParsedDate(date),
decade=dp.getDecade(date),
firstYear=decade[0] - 1,
html='',
i=firstYear;
for (i; i <=decade[1] + 1; i++){
html +=this._getYearHtml(new Date(i , 0));
}
return html;
},
_getYearHtml: function (date){
var content=this._getCellContents(date, 'year');
return '<div class="' + content.classes + '" data-year="' + date.getFullYear() + '">' + content.html + '</div>'
},
_renderTypes: {
days: function (){
var dayNames=this._getDayNamesHtml(this.d.loc.firstDay),
days=this._getDaysHtml(this.d.currentDate);
this.$cells.html(days);
this.$names.html(dayNames)
},
months: function (){
var html=this._getMonthsHtml(this.d.currentDate);
this.$cells.html(html)
},
years: function (){
var html=this._getYearsHtml(this.d.currentDate);
this.$cells.html(html)
}},
_render: function (){
if(this.opts.onlyTimepicker) return;
this._renderTypes[this.type].bind(this)();
},
_update: function (){
var $cells=$('.airdatepicker--cell', this.$cells),
_this=this,
classes,
$cell,
date;
$cells.each(function (cell, i){
$cell=$(this);
date=_this.d._getDateFromCell($(this));
classes=_this._getCellContents(date, _this.d.cellType);
$cell.attr('class',classes.classes)
});
},
show: function (){
if(this.opts.onlyTimepicker) return;
this.$el.addClass('active');
this.acitve=true;
},
hide: function (){
this.$el.removeClass('active');
this.active=false;
},
_handleClick: function (el){
var date=el.data('date')||1,
month=el.data('month')||0,
year=el.data('year')||this.d.parsedDate.year,
dp=this.d;
if(dp.view!=this.opts.minView){
dp.down(new Date(year, month, date));
return;
}
var selectedDate=new Date(year, month, date),
alreadySelected=this.d._isSelected(selectedDate, this.d.cellType);
if(!alreadySelected){
dp._trigger('clickCell', selectedDate);
return;
}
dp._handleAlreadySelectedDates.bind(dp, alreadySelected, selectedDate)();
},
_onClickCell: function (e){
var $el=$(e.target).closest('.airdatepicker--cell');
if($el.hasClass('-disabled-')) return;
this._handleClick.bind(this)($el);
}};})();
;(function (){
var template='' +
'<div class="airdatepicker--nav-action" data-action="prev">#{prevHtml}</div>' +
'<div class="airdatepicker--nav-title">#{title}</div>' +
'<div class="airdatepicker--nav-action" data-action="next">#{nextHtml}</div>',
buttonsContainerTemplate='<div class="airdatepicker--buttons"></div>',
button='<span class="airdatepicker--button" data-action="#{action}">#{label}</span>',
airdatepicker=$.fn.airdatepicker,
dp=airdatepicker.Constructor;
airdatepicker.Navigation=function (d, opts){
this.d=d;
this.opts=opts;
this.$buttonsContainer='';
this.init();
};
airdatepicker.Navigation.prototype={
init: function (){
this._buildBaseHtml();
this._bindEvents();
},
_bindEvents: function (){
this.d.$nav.on('click', '.airdatepicker--nav-action', $.proxy(this._onClickNavButton, this));
this.d.$nav.on('click', '.airdatepicker--nav-title', $.proxy(this._onClickNavTitle, this));
this.d.$airdatepicker.on('click', '.airdatepicker--button', $.proxy(this._onClickNavButton, this));
},
_buildBaseHtml: function (){
if(!this.opts.onlyTimepicker){
this._render();
}
this._addButtonsIfNeed();
},
_addButtonsIfNeed: function (){
if(this.opts.todayButton){
this._addButton('today')
}
if(this.opts.clearButton){
this._addButton('clear')
}},
_render: function (){
var title=this._getTitle(this.d.currentDate),
html=dp.template(template, $.extend({title: title}, this.opts));
this.d.$nav.html(html);
if(this.d.view=='years'){
$('.airdatepicker--nav-title', this.d.$nav).addClass('-disabled-');
}
this.setNavStatus();
},
_getTitle: function (date){
return this.d.formatDate(this.opts.navTitles[this.d.view], date)
},
_addButton: function (type){
if(!this.$buttonsContainer.length){
this._addButtonsContainer();
}
var data={
action: type,
label: this.d.loc[type]
},
html=dp.template(button, data);
if($('[data-action=' + type + ']', this.$buttonsContainer).length) return;
this.$buttonsContainer.append(html);
},
_addButtonsContainer: function (){
this.d.$airdatepicker.append(buttonsContainerTemplate);
this.$buttonsContainer=$('.airdatepicker--buttons', this.d.$airdatepicker);
},
setNavStatus: function (){
if(!(this.opts.minDate||this.opts.maxDate)||!this.opts.disableNavWhenOutOfRange) return;
var date=this.d.parsedDate,
m=date.month,
y=date.year,
d=date.date;
switch (this.d.view){
case 'days':
if(!this.d._isInRange(new Date(y, m-1, 1), 'month')){
this._disableNav('prev')
}
if(!this.d._isInRange(new Date(y, m+1, 1), 'month')){
this._disableNav('next')
}
break;
case 'months':
if(!this.d._isInRange(new Date(y-1, m, d), 'year')){
this._disableNav('prev')
}
if(!this.d._isInRange(new Date(y+1, m, d), 'year')){
this._disableNav('next')
}
break;
case 'years':
var decade=dp.getDecade(this.d.date);
if(!this.d._isInRange(new Date(decade[0] - 1, 0, 1), 'year')){
this._disableNav('prev')
}
if(!this.d._isInRange(new Date(decade[1] + 1, 0, 1), 'year')){
this._disableNav('next')
}
break;
}},
_disableNav: function (nav){
$('[data-action="' + nav + '"]', this.d.$nav).addClass('-disabled-')
},
_activateNav: function (nav){
$('[data-action="' + nav + '"]', this.d.$nav).removeClass('-disabled-')
},
_onClickNavButton: function (e){
var $el=$(e.target).closest('[data-action]'),
action=$el.data('action');
this.d[action]();
},
_onClickNavTitle: function (e){
if($(e.target).hasClass('-disabled-')) return;
if(this.d.view=='days'){
return this.d.view='months'
}
this.d.view='years';
}}
})();
;(function (){
var template='<div class="airdatepicker--time">' +
'<div class="airdatepicker--time-current">' +
'   <span class="airdatepicker--time-current-hours">#{hourVisible}</span>' +
'   <span class="airdatepicker--time-current-colon">:</span>' +
'   <span class="airdatepicker--time-current-minutes">#{minValue}</span>' +
'</div>' +
'<div class="airdatepicker--time-sliders">' +
'   <div class="airdatepicker--time-row">' +
'	  <input type="range" name="hours" value="#{hourValue}" min="#{hourMin}" max="#{hourMax}" step="#{hourStep}"/>' +
'   </div>' +
'   <div class="airdatepicker--time-row">' +
'	  <input type="range" name="minutes" value="#{minValue}" min="#{minMin}" max="#{minMax}" step="#{minStep}"/>' +
'   </div>' +
'</div>' +
'</div>',
airdatepicker=$.fn.airdatepicker,
dp=airdatepicker.Constructor;
airdatepicker.Timepicker=function (inst, opts){
this.d=inst;
this.opts=opts;
this.init();
};
airdatepicker.Timepicker.prototype={
init: function (){
var input='input';
this._setTime(this.d.date);
this._buildHTML();
if(navigator.userAgent.match(/trident/gi)){
input='change';
}
this.d.$el.on('selectDate', this._onSelectDate.bind(this));
this.$ranges.on(input, this._onChangeRange.bind(this));
this.$ranges.on('mouseup', this._onMouseUpRange.bind(this));
this.$ranges.on('mousemove focus ', this._onMouseEnterRange.bind(this));
this.$ranges.on('mouseout blur', this._onMouseOutRange.bind(this));
},
_setTime: function (date){
var _date=dp.getParsedDate(date);
this._handleDate(date);
this.hours=_date.hours < this.minHours ? this.minHours:_date.hours;
this.minutes=_date.minutes < this.minMinutes ? this.minMinutes:_date.minutes;
},
_setMinTimeFromDate: function (date){
this.minHours=date.getHours();
this.minMinutes=date.getMinutes();
if(this.d.lastSelectedDate){
if(this.d.lastSelectedDate.getHours() > date.getHours()){
this.minMinutes=this.opts.minMinutes;
}}
},
_setMaxTimeFromDate: function (date){
this.maxHours=date.getHours();
this.maxMinutes=date.getMinutes();
if(this.d.lastSelectedDate){
if(this.d.lastSelectedDate.getHours() < date.getHours()){
this.maxMinutes=this.opts.maxMinutes;
}}
},
_setDefaultMinMaxTime: function (){
var maxHours=23,
maxMinutes=59,
opts=this.opts;
this.minHours=opts.minHours < 0||opts.minHours > maxHours ? 0:opts.minHours;
this.minMinutes=opts.minMinutes < 0||opts.minMinutes > maxMinutes ? 0:opts.minMinutes;
this.maxHours=opts.maxHours < 0||opts.maxHours > maxHours ? maxHours:opts.maxHours;
this.maxMinutes=opts.maxMinutes < 0||opts.maxMinutes > maxMinutes ? maxMinutes:opts.maxMinutes;
},
_validateHoursMinutes: function (date){
if(this.hours < this.minHours){
this.hours=this.minHours;
}else if(this.hours > this.maxHours){
this.hours=this.maxHours;
}
if(this.minutes < this.minMinutes){
this.minutes=this.minMinutes;
}else if(this.minutes > this.maxMinutes){
this.minutes=this.maxMinutes;
}},
_buildHTML: function (){
var lz=dp.getLeadingZeroNum,
data={
hourMin: this.minHours,
hourMax: lz(this.maxHours),
hourStep: this.opts.hoursStep,
hourValue: this.hours,
hourVisible: lz(this.displayHours),
minMin: this.minMinutes,
minMax: lz(this.maxMinutes),
minStep: this.opts.minutesStep,
minValue: lz(this.minutes)
},
_template=dp.template(template, data);
this.$timepicker=$(_template).appendTo(this.d.$airdatepicker);
this.$ranges=$('[type="range"]', this.$timepicker);
this.$hours=$('[name="hours"]', this.$timepicker);
this.$minutes=$('[name="minutes"]', this.$timepicker);
this.$hoursText=$('.airdatepicker--time-current-hours', this.$timepicker);
this.$minutesText=$('.airdatepicker--time-current-minutes', this.$timepicker);
if(this.d.ampm){
this.$ampm=$('<span class="airdatepicker--time-current-ampm">')
.appendTo($('.airdatepicker--time-current', this.$timepicker))
.html(this.dayPeriod);
this.$timepicker.addClass('-am-pm-');
}},
_updateCurrentTime: function (){
var h=dp.getLeadingZeroNum(this.displayHours),
m=dp.getLeadingZeroNum(this.minutes);
this.$hoursText.html(h);
this.$minutesText.html(m);
if(this.d.ampm){
this.$ampm.html(this.dayPeriod);
}},
_updateRanges: function (){
this.$hours.attr({
min: this.minHours,
max: this.maxHours
}).val(this.hours);
this.$minutes.attr({
min: this.minMinutes,
max: this.maxMinutes
}).val(this.minutes)
},
_handleDate: function (date){
this._setDefaultMinMaxTime();
if(date){
if(dp.isSame(date, this.d.opts.minDate)){
this._setMinTimeFromDate(this.d.opts.minDate);
}else if(dp.isSame(date, this.d.opts.maxDate)){
this._setMaxTimeFromDate(this.d.opts.maxDate);
}}
this._validateHoursMinutes(date);
},
update: function (){
this._updateRanges();
this._updateCurrentTime();
},
_getValidHoursFromDate: function (date, ampm){
var d=date,
hours=date;
if(date instanceof Date){
d=dp.getParsedDate(date);
hours=d.hours;
}
var _ampm=ampm||this.d.ampm,
dayPeriod='am';
if(_ampm){
switch(true){
case hours==0:
hours=12;
break;
case hours==12:
dayPeriod='pm';
break;
case hours > 11:
hours=hours - 12;
dayPeriod='pm';
break;
default:
break;
}}
return {
hours: hours,
dayPeriod: dayPeriod
}},
set hours (val){
this._hours=val;
var displayHours=this._getValidHoursFromDate(val);
this.displayHours=displayHours.hours;
this.dayPeriod=displayHours.dayPeriod;
},
get hours(){
return this._hours;
},
_onChangeRange: function (e){
var $target=$(e.target),
name=$target.attr('name');
this.d.timepickerIsActive=true;
this[name]=$target.val();
this._updateCurrentTime();
this.d._trigger('timeChange', [this.hours, this.minutes]);
this._handleDate(this.d.lastSelectedDate);
this.update()
},
_onSelectDate: function (e, data){
this._handleDate(data);
this.update();
},
_onMouseEnterRange: function (e){
var name=$(e.target).attr('name');
$('.airdatepicker--time-current-' + name, this.$timepicker).addClass('-focus-');
},
_onMouseOutRange: function (e){
var name=$(e.target).attr('name');
if(this.d.inFocus) return;
$('.airdatepicker--time-current-' + name, this.$timepicker).removeClass('-focus-');
},
_onMouseUpRange: function (e){
this.d.timepickerIsActive=false;
}};})();
})(window, jQuery);