Вход Регистрация
Файл: Just Wallet 2.0.4/assets/themes/sci/js/datepicker.js
Строк: 1937
<?php
;(function (window, $, undefined) { ;(function () {
    var 
VERSION '2.2.3',
        
pluginName 'datepicker',
        
autoInitSelector '.datepicker-here',
        
$body$datepickersContainer,
        
containerBuilt false,
        
baseTemplate '' +
            
'<div class="datepicker">' +
            
'<i class="datepicker--pointer"></i>' +
            
'<nav class="datepicker--nav"></nav>' +
            
'<div class="datepicker--content"></div>' +
            
'</div>',
        
defaults = {
            
classes'',
            
inlinefalse,
            
language'ru',
            
startDate: new Date(),
            
firstDay'',
            
weekends: [60],
            
dateFormat'',
            
altField'',
            
altFieldDateFormat'@',
            
toggleSelectedtrue,
            
keyboardNavtrue,

            
position'bottom left',
            
offset12,

            
view'days',
            
minView'days',

            
showOtherMonthstrue,
            
selectOtherMonthstrue,
            
moveToOtherMonthsOnSelecttrue,

            
showOtherYearstrue,
            
selectOtherYearstrue,
            
moveToOtherYearsOnSelecttrue,

            
minDate'',
            
maxDate'',
            
disableNavWhenOutOfRangetrue,

            
multipleDatesfalse// Boolean or Number
            
multipleDatesSeparator',',
            
rangefalse,

            
todayButtonfalse,
            
clearButtonfalse,

            
showEvent'focus',
            
autoClosefalse,

            
// navigation
            
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
            
timepickerfalse,
            
onlyTimepickerfalse,
            
dateTimeSeparator' ',
            
timeFormat'',
            
minHours0,
            
maxHours24,
            
minMinutes0,
            
maxMinutes59,
            
hoursStep1,
            
minutesStep1,

            
// events
            
onSelect'',
            
onShow'',
            
onHide'',
            
onChangeMonth'',
            
onChangeYear'',
            
onChangeDecade'',
            
onChangeView'',
            
onRenderCell''
        
},
        
hotKeys = {
            
'ctrlRight': [1739],
            
'ctrlUp': [1738],
            
'ctrlLeft': [1737],
            
'ctrlDown': [1740],
            
'shiftRight': [1639],
            
'shiftUp': [1638],
            
'shiftLeft': [1637],
            
'shiftDown': [1640],
            
'altUp': [1838],
            
'altRight': [1839],
            
'altLeft': [1837],
            
'altDown': [1840],
            
'ctrlShiftUp': [161738]
        },
        
datepicker;

    var 
Datepicker  = function (eloptions) {
        
this.el el;
        
this.$el = $(el);

        
this.opts = $.extend(true, {}, defaultsoptionsthis.$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// Need to prevent unnecessary rendering

        
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()
    };

    
datepicker Datepicker;

    
datepicker.prototype = {
        
VERSIONVERSION,
        
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) {
                    
// Set extra classes for proper transitions
                    
this._setPositionClasses(this.opts.position);
                    
this._bindEvents()
                }
                if (
this.opts.keyboardNav && !this.opts.onlyTimepicker) {
                    
this._bindKeyboardEvents();
                }
                
this.$datepicker.on('mousedown'this._onMouseDownDatepicker.bind(this));
                
this.$datepicker.on('mouseup'this._onMouseUpDatepicker.bind(this));
            }

            if (
this.opts.classes) {
                
this.$datepicker.addClass(this.opts.classes)
            }

            if (
this.opts.timepicker) {
                
this.timepicker = new $.fn.datepicker.Timepicker(thisthis.opts);
                
this._bindTimepickerEvents();
            }

            if (
this.opts.onlyTimepicker) {
                
this.$datepicker.addClass('-only-timepicker-');
            }

            
this.views[this.currentView] = new $.fn.datepicker.Body(thisthis.currentViewthis.opts);
            
this.views[this.currentView].show();
            
this.nav = new $.fn.datepicker.Navigation(thisthis.opts);
            
this.view this.currentView;

            
this.$el.on('clickCell.adp'this._onClickCell.bind(this));
            
this.$datepicker.on('mouseenter''.datepicker--cell'this._onMouseEnterCell.bind(this));
            
this.$datepicker.on('mouseleave''.datepicker--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.datepicker.language[lang];
                if (!
this.loc) {
                    
console.warn('Can't find language "' + lang + '" in Datepicker.languagewill use "ru" instead');
                    this.loc = $.extend(true, {}, $.fn.datepicker.language.ru)
                }

                this.loc = $.extend(true, {}, $.fn.datepicker.language.ru, $.fn.datepicker.language[lang])
            } else {
                this.loc = $.extend(true, {}, $.fn.datepicker.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="datepickers-container" id="datepickers-container"></div>');
            $datepickersContainer = $('
#datepickers-container');
        
},

        
_buildBaseHtml: function () {
            var 
$appendTarget,
                
$inline = $('<div class="datepicker-inline">');

            if(
this.el.nodeName == 'INPUT') {
                if (!
this.opts.inline) {
                    
$appendTarget $datepickersContainer;
                } else {
                    
$appendTarget $inline.insertAfter(this.$el)
                }
            } else {
                
$appendTarget $inline.appendTo(this.$el)
            }

            
this.$datepicker = $(baseTemplate).appendTo($appendTarget);
            
this.$content = $('.datepicker--content'this.$datepicker);
            
this.$nav = $('.datepicker--nav'this.$datepicker);
        },

        
_triggerOnChange: function () {
            if (!
this.selectedDates.length) {
                
// Prevent from triggering multiple onSelect callback with same argument (empty string) in IE10-11
                
if (this._prevOnSelectValue === '') return;
                
this._prevOnSelectValue '';
                return 
this.opts.onSelect(''''this);
            }

            var 
selectedDates this.selectedDates,
                
parsedSelected datepicker.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.dateFormatdate)
                }).
join(this.opts.multipleDatesSeparator);

            
// Create new dates array, to separate it from original selectedDates
            
if (this.opts.multipleDates || this.opts.range) {
                
dates selectedDates.map(function(date) {
                    var 
parsedDate datepicker.getParsedDate(date);
                    return new 
Date(
                        
parsedDate.year,
                        
parsedDate.month,
                        
parsedDate.date,
                        
parsedDate.hours,
                        
parsedDate.minutes
                    
);
                })
            }

            
this._prevOnSelectValue formattedDates;
            
this.opts.onSelect(formattedDatesdatesthis);
        },

        
next: function () {
            var 
this.parsedDate,
                
this.opts;
            switch (
this.view) {
                case 
'days':
                    
this.date = new Date(d.yeard.month 11);
                    if (
o.onChangeMontho.onChangeMonth(this.parsedDate.monththis.parsedDate.year);
                    break;
                case 
'months':
                    
this.date = new Date(d.year 1d.month1);
                    if (
o.onChangeYearo.onChangeYear(this.parsedDate.year);
                    break;
                case 
'years':
                    
this.date = new Date(d.year 1001);
                    if (
o.onChangeDecadeo.onChangeDecade(this.curDecade);
                    break;
            }
        },

        
prev: function () {
            var 
this.parsedDate,
                
this.opts;
            switch (
this.view) {
                case 
'days':
                    
this.date = new Date(d.yeard.month 11);
                    if (
o.onChangeMontho.onChangeMonth(this.parsedDate.monththis.parsedDate.year);
                    break;
                case 
'months':
                    
this.date = new Date(d.year 1d.month1);
                    if (
o.onChangeYearo.onChangeYear(this.parsedDate.year);
                    break;
                case 
'years':
                    
this.date = new Date(d.year 1001);
                    if (
o.onChangeDecadeo.onChangeDecade(this.curDecade);
                    break;
            }
        },

        
formatDate: function (stringdate) {
            
date date || this.date;
            var 
result string,
                
boundary this._getWordBoundaryRegExp,
                
locale this.loc,
                
leadingZero datepicker.getLeadingZeroNum,
                
decade datepicker.getDecade(date),
                
datepicker.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(dateampm);
                
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(resultboundary('aa'), dayPeriod);
                case /
AA/.test(result):
                    
result replacer(resultboundary('AA'), dayPeriod.toUpperCase());
                case /
dd/.test(result):
                    
result replacer(resultboundary('dd'), d.fullDate);
                case /
d/.test(result):
                    
result replacer(resultboundary('d'), d.date);
                case /
DD/.test(result):
                    
result replacer(resultboundary('DD'), locale.days[d.day]);
                case /
D/.test(result):
                    
result replacer(resultboundary('D'), locale.daysShort[d.day]);
                case /
mm/.test(result):
                    
result replacer(resultboundary('mm'), d.fullMonth);
                case /
m/.test(result):
                    
result replacer(resultboundary('m'), d.month 1);
                case /
MM/.test(result):
                    
result replacer(resultboundary('MM'), this.loc.months[d.month]);
                case /
M/.test(result):
                    
result replacer(resultboundary('M'), locale.monthsShort[d.month]);
                case /
ii/.test(result):
                    
result replacer(resultboundary('ii'), d.fullMinutes);
                case /
i/.test(result):
                    
result replacer(resultboundary('i'), d.minutes);
                case /
hh/.test(result):
                    
result replacer(resultboundary('hh'), fullHours);
                case /
h/.test(result):
                    
result replacer(resultboundary('h'), hours);
                case /
yyyy/.test(result):
                    
result replacer(resultboundary('yyyy'), d.year);
                case /
yyyy1/.test(result):
                    
result replacer(resultboundary('yyyy1'), decade[0]);
                case /
yyyy2/.test(result):
                    
result replacer(resultboundary('yyyy2'), decade[1]);
                case /
yy/.test(result):
                    
result replacer(resultboundary('yy'), d.year.toString().slice(-2));
            }

            return 
result;
        },

        
_replacer: function (strregdata) {
            return 
str.replace(reg, function (matchp1,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,
                
_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;

            
// Set new time values from Date
            
if (this.timepicker) {
                
this.timepicker._setTime(date);
            }

            
// On this step timepicker will set valid values in it's instance
            
_this._trigger('selectDate'date);

            
// Set correct time values after timepicker's validation
            // Prevent from setting hours or minutes which values are lesser then `min` value or
            // greater then `max` value
            
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(), 01);
                }
            }

            if (
newDate) {
                
_this.silent true;
                
_this.date newDate;
                
_this.silent false;
                
_this.nav._render()
            }

            if (
opts.multipleDates && !opts.range) { // Set priority to range functionality
                
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;
                    }
                    
// Swap dates if they were selected via dp.selectDate() and second date was smaller then first
                    
if (datepicker.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 (curDatei) {
                if (
datepicker.isSame(curDatedate)) {
                    
selected.splice(i1);

                    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()
            }
        },

        
/**
         * Updates datepicker options
         * @param {String|Object} param - parameter's name to update. If object then it will extend current options
         * @param {String|Number|Object} [value] - new param value
         */
        
update: function (paramvalue) {
            var 
len arguments.length,
                
lastSelectedDate this.lastSelectedDate;

            if (
len == 2) {
                
this.opts[param] = value;
            } else if (
len == && typeof param == 'object') {
                
this.opts = $.extend(truethis.optsparam)
            }

            
this._createShortCuts();
            
this._syncWithMinMaxDates();
            
this._defineLocale(this.opts.language);
            
this.nav._addButtonsIfNeed();
            if (!
this.opts.onlyTimepickerthis.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.$datepicker.addClass(this.opts.classes)
            }

            if (
this.opts.onlyTimepicker) {
                
this.$datepicker.addClass('-only-timepicker-');
            }

            if (
this.opts.timepicker) {
                if (
lastSelectedDatethis.timepicker._handleDate(lastSelectedDate);
                
this.timepicker._updateRanges();
                
this.timepicker._updateCurrentTime();
                
// Change hours and minutes if it's values have been changed through min/max hours/minutes
                
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 (checkDatecellType) {
            var 
res false;
            
this.selectedDates.some(function (date) {
                if (
datepicker.isSame(datecheckDatecellType)) {
                    
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(formatdate)
                }),
                
altValues;

            if (
opts.altField && _this.$altField.length) {
                
altValues this.selectedDates.map(function (date) {
                    return 
_this.formatDate(altFormatdate)
                });
                
altValues altValues.join(this.opts.multipleDatesSeparator);
                
this.$altField.val(altValues);
            }

            
value value.join(this.opts.multipleDatesSeparator);

            
this.$el.val(value)
        },

        
/**
         * Check if date is between minDate and maxDate
         * @param date {object} - date object
         * @param type {string} - cell type
         * @returns {boolean}
         * @private
         */
        
_isInRange: function (datetype) {
            var 
time date.getTime(),
                
datepicker.getParsedDate(date),
                
min datepicker.getParsedDate(this.minDate),
                
max datepicker.getParsedDate(this.maxDate),
                
dMinTime = new Date(d.yeard.monthmin.date).getTime(),
                
dMaxTime = new Date(d.yeard.monthmax.date).getTime(),
                
types = {
                    
daytime >= this.minTime && time <= this.maxTime,
                    
monthdMinTime >= this.minTime && dMaxTime <= this.maxTime,
                    
yeard.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(),
                
leftoffset.left,
                
topoffset.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(yearmonthdate);
        },

        
_setPositionClasses: function (pos) {
            
pos pos.split(' ');
            var 
main pos[0],
                
sec pos[1],
                
classes 'datepicker -' main '-' sec '- -from-' main '-';

            if (
this.visibleclasses += ' active';

            
this.$datepicker
                
.removeAttr('class')
                .
addClass(classes);
        },

        
setPosition: function (position) {
            
position position || this.opts.position;

            var 
dims this._getDimensions(this.$el),
                
selfDims this._getDimensions(this.$datepicker),
                
pos position.split(' '),
                
topleft,
                
offset this.opts.offset,
                
main pos[0],
                
secondary pos[1];

            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/selfDims.height/2;
                    } else {
                        
left dims.left dims.width/selfDims.width/2;
                    }
            }

            
this.$datepicker
                
.css({
                    
leftleft,
                    
toptop
                
})
        },

        
show: function () {
            var 
onShow this.opts.onShow;

            
this.setPosition(this.opts.position);
            
this.$datepicker.addClass('active');
            
this.visible true;

            if (
onShow) {
                
this._bindVisionEvents(onShow)
            }
        },

        
hide: function () {
            var 
onHide this.opts.onHide;

            
this.$datepicker
                
.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.$datepicker.off('transitionend.dp');
            
event(thisfalse);
            
this.$datepicker.one('transitionend.dp'event.bind(thisthistrue))
        },

        
_changeView: function (datedir) {
            
date date || this.focused || this.date;

            var 
nextView dir == 'up' this.viewIndex this.viewIndex 1;
            if (
nextView 2nextView 2;
            if (
nextView 0nextView 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 datepicker.getParsedDate(this._getFocusedDate()),
                
focusedParsed,
                
this.opts,
                
newDate,
                
totalDaysInNextMonth,
                
monthChanged false,
                
yearChanged false,
                
decadeChanged false,
                
date.year,
                
date.month,
                
date.date;

            switch (
key) {
                case 
'ctrlRight':
                case 
'ctrlUp':
                    
+= 1;
                    
monthChanged true;
                    break;
                case 
'ctrlLeft':
                case 
'ctrlDown':
                    
-= 1;
                    
monthChanged true;
                    break;
                case 
'shiftRight':
                case 
'shiftUp':
                    
yearChanged true;
                    
+= 1;
                    break;
                case 
'shiftLeft':
                case 
'shiftDown':
                    
yearChanged true;
                    
-= 1;
                    break;
                case 
'altRight':
                case 
'altUp':
                    
decadeChanged true;
                    
+= 10;
                    break;
                case 
'altLeft':
                case 
'altDown':
                    
decadeChanged true;
                    
-= 10;
                    break;
                case 
'ctrlShiftUp':
                    
this.up();
                    break;
            }

            
totalDaysInNextMonth datepicker.getDaysCount(new Date(y,m));
            
newDate = new Date(y,m,d);

            
// If next month has less days than current, set date to total days in that month
            
if (totalDaysInNextMonth dtotalDaysInNextMonth;

            
// Check if newDate is in valid range
            
if (newDate.getTime() < this.minTime) {
                
newDate this.minDate;
            } else if (
newDate.getTime() > this.maxTime) {
                
newDate this.maxDate;
            }

            
this.focused newDate;

            
focusedParsed datepicker.getParsedDate(newDate);
            if (
monthChanged && o.onChangeMonth) {
                
o.onChangeMonth(focusedParsed.monthfocusedParsed.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(index1);
        },

        
_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 (keyi) { return key == pressedKeys[i]})) {
                    
_this._trigger('hotKey'hotKey);
                    
found true;
                }
            }

            return 
found;
        },

        
_trigger: function (eventargs) {
            
this.$el.trigger(eventargs)
        },

        
_focusNextCell: function (keyCodetype) {
            
type type || this.cellType;

            var 
date datepicker.getParsedDate(this._getFocusedDate()),
                
date.year,
                
date.month,
                
date.date;

            if (
this._isHotKeyPressed()){
                return;
            }

            switch(
keyCode) {
                case 
37// left
                    
type == 'day' ? (-= 1) : '';
                    
type == 'month' ? (-= 1) : '';
                    
type == 'year' ? (-= 1) : '';
                    break;
                case 
38// up
                    
type == 'day' ? (-= 7) : '';
                    
type == 'month' ? (-= 3) : '';
                    
type == 'year' ? (-= 4) : '';
                    break;
                case 
39// right
                    
type == 'day' ? (+= 1) : '';
                    
type == 'month' ? (+= 1) : '';
                    
type == 'year' ? (+= 1) : '';
                    break;
                case 
40// down
                    
type == 'day' ? (+= 7) : '';
                    
type == 'month' ? (+= 3) : '';
                    
type == 'year' ? (+= 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],
                
this.parsedDate;

            if (!
focused) {
                switch (
this.view) {
                    case 
'days':
                        
focused = new Date(d.yeard.month, new Date().getDate());
                        break;
                    case 
'months':
                        
focused = new Date(d.yeard.month1);
                        break;
                    case 
'years':
                        
focused = new Date(d.year01);
                        break;
                }
            }

            return 
focused;
        },

        
_getCell: function (datetype) {
            
type type || this.cellType;

            var 
datepicker.getParsedDate(date),
                
selector '.datepicker--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('datepicker''');

            
_this.selectedDates = [];
            
_this.focused '';
            
_this.views = {};
            
_this.keys = [];
            
_this.minRange '';
            
_this.maxRange '';

            if (
_this.opts.inline || !_this.elIsInput) {
                
_this.$datepicker.closest('.datepicker-inline').remove();
            } else {
                
_this.$datepicker.remove();
            }
        },

        
_handleAlreadySelectedDates: function (alreadySelectedselectedDate) {
            if (
this.opts.range) {
                if (!
this.opts.toggleSelected) {
                    
// Add possibility to select same date when range is true
                    
if (this.selectedDates.length != 2) {
                        
this._trigger('clickCell'selectedDate);
                    }
                } else {
                    
this.removeDate(selectedDate);
                }
            } else if (
this.opts.toggleSelected){
                
this.removeDate(selectedDate);
            }

            
// Change last selected date to be able to change time when clicking on this cell
            
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.timepickerFocusthis.$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);

            
// Arrows
            
if (code >= 37 && code <= 40) {
                
e.preventDefault();
                
this._focusNextCell(code);
            }

            
// Enter
            
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.focusedthis.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(alreadySelectedthis.focused)
                    }
                }
            }

            
// Esc
            
if (code == 27) {
                
this.hide();
            }
        },

        
_onKeyUp: function (e) {
            var 
code e.which;
            
this._unRegisterKey(code);
        },

        
_onHotKey: function (ehotKey) {
            
this._handleHotKey(hotKey);
        },

        
_onMouseEnterCell: function (e) {
            var 
$cell = $(e.target).closest('.datepicker--cell'),
                
date this._getDateFromCell($cell);

            
// Prevent from unnecessary rendering and setting new currentDate
            
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 (
datepicker.less(this.minRangethis.focused)) {
                    
this.maxRange this.minRange;
                    
this.minRange '';
                }
                
this.views[this.currentView]._update();
            }
        },

        
_onMouseLeaveCell: function (e) {
            var 
$cell = $(e.target).closest('.datepicker--cell');

            
$cell.removeClass('-focus-');

            
this.silent true;
            
this.focused '';
            
this.silent false;
        },

        
_onTimeChange: function (ehm) {
            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 (edate) {
            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 (
datepicker.less(this.minRangethis._focused)) {
                    
this.maxRange this.minRange;
                    
this.minRange '';
                }
            }
            if (
this.silent) return;
            
this.date val;
        },

        
get focused() {
            return 
this._focused;
        },

        
get parsedDate() {
            return 
datepicker.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.datepicker.Body(thisvalthis.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.visiblethis.setPosition();
            }

            return 
val
        
},

        
get view() {
            return 
this.currentView;
        },

        
get cellType() {
            return 
this.view.substring(0this.view.length 1)
        },

        
get minTime() {
            var 
min datepicker.getParsedDate(this.minDate);
            return new 
Date(min.yearmin.monthmin.date).getTime()
        },

        
get maxTime() {
            var 
max datepicker.getParsedDate(this.maxDate);
            return new 
Date(max.yearmax.monthmax.date).getTime()
        },

        
get curDecade() {
            return 
datepicker.getDecade(this.date)
        }
    };

    
//  Utils
    // -------------------------------------------------

    
datepicker.getDaysCount = function (date) {
        return new 
Date(date.getFullYear(), date.getMonth() + 10).getDate();
    };

    
datepicker.getParsedDate = function (date) {
        return {
            
yeardate.getFullYear(),
            
monthdate.getMonth(),
            
fullMonth: (date.getMonth() + 1) < 10 '0' + (date.getMonth() + 1) : date.getMonth() + 1// One based
            
datedate.getDate(),
            
fullDatedate.getDate() < 10 '0' date.getDate() : date.getDate(),
            
daydate.getDay(),
            
hoursdate.getHours(),
            
fullHours:  date.getHours() < 10 '0' date.getHours() :  date.getHours() ,
            
minutesdate.getMinutes(),
            
fullMinutes:  date.getMinutes() < 10 '0' date.getMinutes() :  date.getMinutes()
        }
    };

    
datepicker.getDecade = function (date) {
        var 
firstYear Math.floor(date.getFullYear() / 10) * 10;

        return [
firstYearfirstYear 9];
    };

    
datepicker.template = function (strdata) {
        return 
str.replace(/#{([w]+)}/g, function (source, match) {
            
if (data[match] || data[match] === 0) {
                return 
data[match]
            }
        });
    };

    
datepicker.isSame = function (date1date2type) {
        if (!
date1 || !date2) return false;
        var 
d1 datepicker.getParsedDate(date1),
            
d2 datepicker.getParsedDate(date2),
            
_type type type 'day',

            
conditions = {
                
dayd1.date == d2.date && d1.month == d2.month && d1.year == d2.year,
                
monthd1.month == d2.month && d1.year == d2.year,
                
yeard1.year == d2.year
            
};

        return 
conditions[_type];
    };

    
datepicker.less = function (dateCompareTodatetype) {
        if (!
dateCompareTo || !date) return false;
        return 
date.getTime() < dateCompareTo.getTime();
    };

    
datepicker.bigger = function (dateCompareTodatetype) {
        if (!
dateCompareTo || !date) return false;
        return 
date.getTime() > dateCompareTo.getTime();
    };

    
datepicker.getLeadingZeroNum = function (num) {
        return 
parseInt(num) < 10 '0' num num;
    };

    
/**
     * Returns copy of date with hours and minutes equals to 0
     * @param date {Date}
     */
    
datepicker.resetTime = function (date) {
        if (
typeof date != 'object') return;
        
date datepicker.getParsedDate(date);
        return new 
Date(date.yeardate.monthdate.date)
    };

    $.
fn.datepicker = function ( options ) {
        return 
this.each(function () {
            if (!$.
data(thispluginName)) {
                $.
data(this,  pluginName,
                    new 
Datepickerthisoptions ));
            } else {
                var 
_this = $.data(thispluginName);

                
_this.opts = $.extend(true_this.optsoptions);
                
_this.update();
            }
        });
    };

    $.
fn.datepicker.Constructor Datepicker;

    $.
fn.datepicker.language = {
        
ru: {
            
days: ['Воскресенье''Понедельник''Вторник''Среда''Четверг''Пятница''Суббота'],
            
daysShort: ['Вос','Пон','Вто','Сре','Чет','Пят','Суб'],
            
daysMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
            
months: ['Январь''Февраль''Март''Апрель''Май''Июнь''Июль''Август''Сентябрь''Октябрь''Ноябрь''Декабрь'],
            
monthsShort: ['Янв''Фев''Мар''Апр''Май''Июн''Июл''Авг''Сен''Окт''Ноя''Дек'],
            
today'Сегодня',
            
clear'Очистить',
            
dateFormat'dd.mm.yyyy',
            
timeFormat'hh:ii',
            
firstDay1
        
}
    };

    $(function () {
        $(
autoInitSelector).datepicker();
    })

})();

;(function () {
    var 
templates = {
        
days:'' +
        
'<div class="datepicker--days datepicker--body">' +
        
'<div class="datepicker--days-names"></div>' +
        
'<div class="datepicker--cells datepicker--cells-days"></div>' +
        
'</div>',
        
months'' +
        
'<div class="datepicker--months datepicker--body">' +
        
'<div class="datepicker--cells datepicker--cells-months"></div>' +
        
'</div>',
        
years'' +
        
'<div class="datepicker--years datepicker--body">' +
        
'<div class="datepicker--cells datepicker--cells-years"></div>' +
        
'</div>'
        
},
        
datepicker = $.fn.datepicker,
        
dp datepicker.Constructor;

    
datepicker.Body = function (dtypeopts) {
        
this.d;
        
this.type type;
        
this.opts opts;
        
this.$el = $('');

        if (
this.opts.onlyTimepicker) return;
        
this.init();
    };

    
datepicker.Body.prototype = {
        
init: function () {
            
this._buildBaseHtml();
            
this._render();

            
this._bindEvents();
        },

        
_bindEvents: function () {
            
this.$el.on('click''.datepicker--cell', $.proxy(this._onClickCellthis));
        },

        
_buildBaseHtml: function () {
            
this.$el = $(templates[this.type]).appendTo(this.d.$content);
            
this.$names = $('.datepicker--days-names'this.$el);
            
this.$cells = $('.datepicker--cells'this.$el);
        },

        
_getDayNamesHtml: function (firstDaycurDayhtmli) {
            
curDay curDay != undefined curDay firstDay;
            
html html html '';
            
!= undefined 0;

            if (
7) return html;
            if (
curDay == 7) return this._getDayNamesHtml(firstDay0html, ++i);

            
html += '<div class="datepicker--day-name' + (this.d.isWeekend(curDay) ? " -weekend-" "") + '">' this.d.loc.daysMin[curDay] + '</div>';

            return 
this._getDayNamesHtml(firstDay, ++curDayhtml, ++i);
        },

        
_getCellContents: function (datetype) {
            var 
classes "datepicker--cell datepicker--cell-" type,
                
currentDate = new Date(),
                
parent this.d,
                
minRange dp.resetTime(parent.minRange),
                
maxRange dp.resetTime(parent.maxRange),
                
opts parent.opts,
                
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.showOtherMonthshtml '';
                    }
                    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.showOtherYearshtml '';
                    }
                    break;
            }

            if (
opts.onRenderCell) {
                
render opts.onRenderCell(datetype) || {};
                
html render.html render.html html;
                
classes += render.classes ' ' render.classes '';
            }

            if (
opts.range) {
                if (
dp.isSame(minRangedatetype)) classes += ' -range-from-';
                if (
dp.isSame(maxRangedatetype)) classes += ' -range-to-';

                if (
parent.selectedDates.length == && parent.focused) {
                    if (
                        (
dp.bigger(minRangedate) && dp.less(parent.focuseddate)) ||
                        (
dp.less(maxRangedate) && dp.bigger(parent.focuseddate)))
                    {
                        
classes += ' -in-range-'
                    
}

                    if (
dp.less(maxRangedate) && dp.isSame(parent.focuseddate)) {
                        
classes += ' -range-from-'
                    
}
                    if (
dp.bigger(minRangedate) && dp.isSame(parent.focuseddate)) {
                        
classes += ' -range-to-'
                    
}

                } else if (
parent.selectedDates.length == 2) {
                    if (
dp.bigger(minRangedate) && dp.less(maxRangedate)) {
                        
classes += ' -in-range-'
                    
}
                }
            }


            if (
dp.isSame(currentDatedatetype)) classes += ' -current-';
            if (
parent.focused && dp.isSame(dateparent.focusedtype)) classes += ' -focus-';
            if (
parent._isSelected(datetype)) classes += ' -selected-';
            if (!
parent._isInRange(datetype) || render.disabledclasses += ' -disabled-';

            return {
                
htmlhtml,
                
classesclasses
            
}
        },

        
/**
         * Calculates days number to render. Generates days html and returns it.
         * @param {object} date - Date object
         * @returns {string}
         * @private
         */
        
_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 lastMonthDay this.d.loc.firstDay;

            
daysFromPevMonth daysFromPevMonth daysFromPevMonth daysFromPevMonth;
            
daysFromNextMonth daysFromNextMonth daysFromNextMonth daysFromNextMonth;

            var 
startDayIndex = -daysFromPevMonth 1,
                
my,
                
html '';

            for (var 
startDayIndexmax totalMonthDays daysFromNextMonth<= maxi++) {
                
date.getFullYear();
                
date.getMonth();

                
html += this._getDayHtml(new Date(ymi))
            }

            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>';
        },

        
/**
         * Generates months html
         * @param {object} date - date instance
         * @returns {string}
         * @private
         */
        
_getMonthsHtml: function (date) {
            var 
html '',
                
dp.getParsedDate(date),
                
0;

            while(
12) {
                
html += this._getMonthHtml(new Date(d.yeari));
                
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 
dp.getParsedDate(date),
                
decade dp.getDecade(date),
                
firstYear decade[0] - 1,
                
html '',
                
firstYear;

            for (
i<= decade[1] + 1i++) {
                
html += this._getYearHtml(new Date(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 = $('.datepicker--cell'this.$cells),
                
_this this,
                
classes,
                
$cell,
                
date;
            
$cells.each(function (celli) {
                
$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;
        },

        
//  Events
        // -------------------------------------------------

        
_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;
            
// Change view if min view does not reach yet
            
if (dp.view != this.opts.minView) {
                
dp.down(new Date(yearmonthdate));
                return;
            }
            
// Select date if min view is reached
            
var selectedDate = new Date(yearmonthdate),
                
alreadySelected this.d._isSelected(selectedDatethis.d.cellType);

            if (!
alreadySelected) {
                
dp._trigger('clickCell'selectedDate);
                return;
            }

            
dp._handleAlreadySelectedDates.bind(dpalreadySelectedselectedDate)();

        },

        
_onClickCell: function (e) {
            var 
$el = $(e.target).closest('.datepicker--cell');

            if (
$el.hasClass('-disabled-')) return;

            
this._handleClick.bind(this)($el);
        }
    };
})();

;(function () {
    var 
template '' +
        
'<div class="datepicker--nav-action" data-action="prev">#{prevHtml}</div>' +
        
'<div class="datepicker--nav-title">#{title}</div>' +
        
'<div class="datepicker--nav-action" data-action="next">#{nextHtml}</div>',
        
buttonsContainerTemplate '<div class="datepicker--buttons"></div>',
        
button '<span class="datepicker--button" data-action="#{action}">#{label}</span>',
        
datepicker = $.fn.datepicker,
        
dp datepicker.Constructor;

    
datepicker.Navigation = function (dopts) {
        
this.d;
        
this.opts opts;

        
this.$buttonsContainer '';

        
this.init();
    };

    
datepicker.Navigation.prototype = {
        
init: function () {
            
this._buildBaseHtml();
            
this._bindEvents();
        },

        
_bindEvents: function () {
            
this.d.$nav.on('click''.datepicker--nav-action', $.proxy(this._onClickNavButtonthis));
            
this.d.$nav.on('click''.datepicker--nav-title', $.proxy(this._onClickNavTitlethis));
            
this.d.$datepicker.on('click''.datepicker--button', $.proxy(this._onClickNavButtonthis));
        },

        
_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({titletitle}, this.opts));
            
this.d.$nav.html(html);
            if (
this.d.view == 'years') {
                $(
'.datepicker--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 = {
                    
actiontype,
                    
labelthis.d.loc[type]
                },
                
html dp.template(buttondata);

            if ($(
'[data-action=' type ']'this.$buttonsContainer).length) return;
            
this.$buttonsContainer.append(html);
        },

        
_addButtonsContainer: function () {
            
this.d.$datepicker.append(buttonsContainerTemplate);
            
this.$buttonsContainer = $('.datepicker--buttons'this.d.$datepicker);
        },

        
setNavStatus: function () {
            if (!(
this.opts.minDate || this.opts.maxDate) || !this.opts.disableNavWhenOutOfRange) return;

            var 
date this.d.parsedDate,
                
date.month,
                
date.year,
                
date.date;

            switch (
this.d.view) {
                case 
'days':
                    if (!
this.d._isInRange(new Date(ym-11), 'month')) {
                        
this._disableNav('prev')
                    }
                    if (!
this.d._isInRange(new Date(ym+11), 'month')) {
                        
this._disableNav('next')
                    }
                    break;
                case 
'months':
                    if (!
this.d._isInRange(new Date(y-1md), 'year')) {
                        
this._disableNav('prev')
                    }
                    if (!
this.d._isInRange(new Date(y+1md), 'year')) {
                        
this._disableNav('next')
                    }
                    break;
                case 
'years':
                    var 
decade dp.getDecade(this.d.date);
                    if (!
this.d._isInRange(new Date(decade[0] - 101), 'year')) {
                        
this._disableNav('prev')
                    }
                    if (!
this.d._isInRange(new Date(decade[1] + 101), '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="datepicker--time">' +
        
'<div class="datepicker--time-current">' +
        
'   <span class="datepicker--time-current-hours">#{hourVisible}</span>' +
        
'   <span class="datepicker--time-current-colon">:</span>' +
        
'   <span class="datepicker--time-current-minutes">#{minValue}</span>' +
        
'</div>' +
        
'<div class="datepicker--time-sliders">' +
        
'   <div class="datepicker--time-row">' +
        
'      <input type="range" name="hours" value="#{hourValue}" min="#{hourMin}" max="#{hourMax}" step="#{hourStep}"/>' +
        
'   </div>' +
        
'   <div class="datepicker--time-row">' +
        
'      <input type="range" name="minutes" value="#{minValue}" min="#{minMin}" max="#{minMax}" step="#{minStep}"/>' +
        
'   </div>' +
        
'</div>' +
        
'</div>',
        
datepicker = $.fn.datepicker,
        
dp datepicker.Constructor;

    
datepicker.Timepicker = function (instopts) {
        
this.inst;
        
this.opts opts;

        
this.init();
    };

    
datepicker.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(inputthis._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;
        },

        
/**
         * Sets minHours and minMinutes from date (usually it's a minDate)
         * Also changes minMinutes if current hours are bigger then @date hours
         * @param date {Date}
         * @private
         */
        
_setMinTimeFromDate: function (date) {
            
this.minHours date.getHours();
            
this.minMinutes date.getMinutes();

            
// If, for example, min hours are 10, and current hours are 12,
            // update minMinutes to default value, to be able to choose whole range of values
            
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 || opts.minHours maxHours opts.minHours;
            
this.minMinutes opts.minMinutes || opts.minMinutes maxMinutes opts.minMinutes;
            
this.maxHours opts.maxHours || opts.maxHours maxHours maxHours opts.maxHours;
            
this.maxMinutes opts.maxMinutes || opts.maxMinutes maxMinutes maxMinutes opts.maxMinutes;
        },

        
/**
         * Looks for min/max hours/minutes and if current values
         * are out of range sets valid values.
         * @private
         */
        
_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 = {
                    
hourMinthis.minHours,
                    
hourMaxlz(this.maxHours),
                    
hourStepthis.opts.hoursStep,
                    
hourValuethis.hours,
                    
hourVisiblelz(this.displayHours),
                    
minMinthis.minMinutes,
                    
minMaxlz(this.maxMinutes),
                    
minStepthis.opts.minutesStep,
                    
minValuelz(this.minutes)
                },
                
_template dp.template(templatedata);

            
this.$timepicker = $(_template).appendTo(this.d.$datepicker);
            
this.$ranges = $('[type="range"]'this.$timepicker);
            
this.$hours = $('[name="hours"]'this.$timepicker);
            
this.$minutes = $('[name="minutes"]'this.$timepicker);
            
this.$hoursText = $('.datepicker--time-current-hours'this.$timepicker);
            
this.$minutesText = $('.datepicker--time-current-minutes'this.$timepicker);

            if (
this.d.ampm) {
                
this.$ampm = $('<span class="datepicker--time-current-ampm">')
                    .
appendTo($('.datepicker--time-current'this.$timepicker))
                    .
html(this.dayPeriod);

                
this.$timepicker.addClass('-am-pm-');
            }
        },

        
_updateCurrentTime: function () {
            var 
=  dp.getLeadingZeroNum(this.displayHours),
                
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({
                
minthis.minHours,
                
maxthis.maxHours
            
}).val(this.hours);

            
this.$minutes.attr({
                
minthis.minMinutes,
                
maxthis.maxMinutes
            
}).val(this.minutes)
        },

        
/**
         * Sets minHours, minMinutes etc. from date. If date is not passed, than sets
         * values from options
         * @param [date] {object} - Date object, to get values from
         * @private
         */
        
_handleDate: function (date) {
            
this._setDefaultMinMaxTime();
            if (
date) {
                if (
dp.isSame(datethis.d.opts.minDate)) {
                    
this._setMinTimeFromDate(this.d.opts.minDate);
                } else if (
dp.isSame(datethis.d.opts.maxDate)) {
                    
this._setMaxTimeFromDate(this.d.opts.maxDate);
                }
            }

            
this._validateHoursMinutes(date);
        },

        
update: function () {
            
this._updateRanges();
            
this._updateCurrentTime();
        },

        
/**
         * Calculates valid hour value to display in text input and datepicker's body.
         * @param date {Date|Number} - date or hours
         * @param [ampm] {Boolean} - 12 hours mode
         * @returns {{hours: *, dayPeriod: string}}
         * @private
         */
        
_getValidHoursFromDate: function (dateampm) {
            var 
date,
                
hours date;

            if (
date instanceof Date) {
                
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 {
                
hourshours,
                
dayPerioddayPeriod
            
}
        },

        
set hours (val) {
            
this._hours val;

            var 
displayHours this._getValidHoursFromDate(val);

            
this.displayHours displayHours.hours;
            
this.dayPeriod displayHours.dayPeriod;
        },

        
get hours() {
            return 
this._hours;
        },

        
//  Events
        // -------------------------------------------------

        
_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.hoursthis.minutes]);

            
this._handleDate(this.d.lastSelectedDate);
            
this.update()
        },

        
_onSelectDate: function (edata) {
            
this._handleDate(data);
            
this.update();
        },

        
_onMouseEnterRange: function (e) {
            var 
name = $(e.target).attr('name');
            $(
'.datepicker--time-current-' namethis.$timepicker).addClass('-focus-');
        },

        
_onMouseOutRange: function (e) {
            var 
name = $(e.target).attr('name');
            if (
this.d.inFocus) return; // Prevent removing focus when mouse out of range slider
            
$('.datepicker--time-current-' namethis.$timepicker).removeClass('-focus-');
        },

        
_onMouseUpRange: function (e) {
            
this.d.timepickerIsActive false;
        }
    };
})();
 })(
windowjQuery);
?>
Онлайн: 0
Реклама