/*! asDatepicker - v0.4.1 - 2014-12-24 * https://github.com/amazingSurge/jquery-asDatepicker * Copyright (c) 2014 amazingSurge; Licensed MIT */ (function($, document, window, undefined) { // Optional, but considered best practice by some "use strict"; var pluginName = 'asDatepicker', defaults = { firstDayOfWeek: 0, // 0---6 === sunday---saturday mode: 'single', // single|range|multiple displayMode: 'dropdown', // dropdown|inline calendars: 1, date: 'today', // today|Date (yyyy-mm-dd) keyboard: true, // true | false rangeSeparator: 'to', multipleSeparator: ',', multipleSize: 5, container: 'body', position: 'bottom', // top|right|bottom|left|rightTop|leftTop alwaysShow: false, // true or false onceClick: false, // true or false min: null, // min: '2012-12-1',//null|'today'|days|Date with (yyyy-mm-dd) max: null, // max: '2013-10-1',//null|'today'|days|Date with (yyyy-mm-dd) selectableDate: [], // ['2013-8-1', {from: '2013-8-5', to: '2013-8-10'}, {from: -30, to: 30}]], selectableYear: [], // [{from: 1980, to: 1985}, 1988, {from: 2000, to: 2010}, 2013], selectableMonth: [], // months from 0 - 11 (jan to dec) example: [0, {from: 3, to: 9}, 11], selectableDay: [], // days from 0 - 31, selectableDayOfWeek: [], // days of week 0-6 (su to sa) [0, {from: 2, to: 4}] , [] is default all lang: 'en', //'chinese' views: ['days'], // ['days'], ['days', 'months', 'years'] outputFormat: 'yyyy/mm/dd', mobileMode: false, namespace: 'calendar', tplInputWrapper: function() { return '
'; }, tplWrapper: function() { return '
'; }, tplContent: function() { return '
' + '
' + '
<
' + '
' + '
>
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
'; }, tplTitle: function() { return '
test
'; }, onInit: null, onReady: null, onRender: null, onChange: null, onBeforeShow: null, onShow: null, onBeforeHide: null, onHide: null }; var $doc = $(document); var $win = $(window); var LABEL = {}; var SHOWED = 0; var Plugin = $[pluginName] = function(element, options) { var self = this, data = $(element).data(); this.$el = $(element); this.defaultOptions = $.extend(true, {}, defaults, options, data); this.options = $.extend(true, {}, defaults, options, data); $.each(data, function(option, value) { self.options[option] = self._parseHtmlString(option, value); self.defaultOptions[option] = self._parseHtmlString(option, value); }); this.namespace = this.options.namespace; this.$inputWrap = this.$el.addClass(this.namespace + '-input').wrap(this.options.tplInputWrapper().replace(/namespace/g, this.namespace)).parent(); this.$inputIcon = $(''); this.$inputIcon.appendTo(this.$inputWrap); this.$container = $(this.options.container); this._trigger('init'); this._init(); }; Plugin.LABEL = LABEL; Plugin.localize = function(lang, label) { LABEL[lang] = label; }; Plugin.localize('en', { days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], daysShort: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], buttons: ['Cancel', 'Save'] }); Plugin.prototype = { constructor: Plugin, _init: function() { this.mode = this.options.mode; this.format = this._parseFormat('yyyy-mm-dd'); this.outputFormat = this._parseFormat(this.options.outputFormat || 'yyyy/mm/dd'); this.focused = 0; this.flag = SHOWED++; this.pickerHide = false; this.selected = false; this.showed = false; this.bound = false; this.hasKeyboard = this.options.keyboard; this.map = {}; this.views = []; this.isMobile = this.options.mobileMode; //with other judgements var wrapper = this.options.tplWrapper().replace(/namespace/g, this.namespace), content = this.options.tplContent().replace(/namespace/g, this.namespace), title = this.options.tplTitle().replace(/namespace/g, this.namespace), buttons = LABEL[this.options.lang].buttons; this.$picker = $(wrapper); //set model default property switch (this.mode) { case 'single': this.calendarsNum = 1; break; case 'range': this.calendarsNum = 2; break; case 'multiple': this.calendarsNum = this.isMobile ? 1 : this.options.calendars; this.options.views = ['days']; break; } //set base Views for (var i = 0; i < this.calendarsNum; i++) { this.$picker.append(content); this.views[i] = this.options.views[i] || 'days'; } //check mobileMode if (this.isMobile) { var innerWidth = window.innerWidth; var innerHeight = window.innerHeight; var min = Math.min(innerWidth, innerHeight); this.$el.attr('readonly', 'readonly'); this.$cover = $('
'); this.$picker.append(title) .addClass(this.namespace + '_isMobile'); this.$picker.css({ 'font-size': Math.round(min * 0.04) + 'px' }); } //make $wrapper can be focused this.$picker.attr('tabindex', '0'); //init status in different display mode this._initStatus(this.options.displayMode); //init pointer this._initSections(); //init default Date this._initDate(); for (var j = 0; j < this.calendarsNum; j++) { this._manageViews(j); if (this.isMobile) { this.buttonCancels.eq(j).html(buttons[0]); this.buttonSaves.eq(j).html(buttons[1]); } } //init alwaysShow this._initShowHide(this.options.alwaysShow); this._setValue(); this._trigger('ready'); }, _initStatus: function(displayMode) { if (displayMode === 'inline') { this.options.alwaysShow = true; // this.$el.after(this.$picker).addClass(this.namespace + '_hide'); this.$picker.addClass(this.namespace + '_show'); this.$picker.on({ focus: $.proxy(this._focus, this), blur: $.proxy(this._blur, this) }); } else if (displayMode === 'dropdown') { this.$el.on({ focus: $.proxy(this._focus, this), blur: $.proxy(this._blur, this) }); this.$inputIcon.on('click.inputIcon', $.proxy(this._toggle, this)); this.$picker.appendTo(this.options.container); // this.$picker.addClass(this.namespace + '_absolute'); } }, _initSections: function() { this.calendars = this.$picker.find('.' + this.namespace + '-content'); this.calendarPrevs = this.calendars.find('.' + this.namespace + '-prev'); this.calendarCaptions = this.calendars.find('.' + this.namespace + '-caption'); this.calendarNexts = this.calendars.find('.' + this.namespace + '-next'); this.daypickers = this.calendars.find('.' + this.namespace + '-days'); this.monthpickers = this.calendars.find('.' + this.namespace + '-months'); this.yearpickers = this.calendars.find('.' + this.namespace + '-years'); this.buttonCancels = this.calendars.find('.' + this.namespace + '-button-cancel'); this.buttonSaves = this.calendars.find('.' + this.namespace + '-button-save'); }, _initShowHide: function(alwaysShow) { if (alwaysShow === true) { this.show(); } }, _initDate: function() { var date = this.options.date === 'today' ? new Date() : this._parseDate(this.options.date, this.format); this._date = {}; this._date.currentDate = [new Date(date)]; if (this.mode === 'multiple') { this._date.selectedDate = []; this._date.focusDate = new Date(date); this._date.focusDate.setHours(0, 0, 0, 0); } else { this._date.selectedDate = [new Date(date)]; this._date.focusDate = [new Date(date)]; } this._date.currentDay = []; this._date.currentMonth = []; this._date.currentYear = []; this._date.currentMonthDate = []; this._date.currentYearDate = []; this._date.selectedDay = []; this._date.selectedMonth = []; this._date.selectedYear = []; this._date.selectedMonthDate = []; this._date.selectedYearDate = []; this._date.cache = {}; this._date.cache.currentDate = []; this._date.cache.selectedDate = []; for (var i = 0; i < this.calendarsNum; i++) { this._date.currentDate[i] = this._date.currentDate[i] || new Date(date); if (this.mode === 'multiple') { this._setDate(this._date.currentDate[i], 'month', this._date.currentDate[i].getMonth() + i); } else { this._date.selectedDate[i] = this._date.selectedDate[i] || new Date(date); this._date.selectedDate[i].setHours(0, 0, 0, 0); this._date.focusDate[i] = this._date.focusDate[i] || new Date(date); this._date.focusDate[i].setHours(0, 0, 0, 0); } this._updateDate(i); } }, _manageViews: function(index) { switch (this.views[index]) { case 'days': this._generateDaypicker(index); this.calendars.eq(index).addClass(this.namespace + '_days') .removeClass(this.namespace + '_months') .removeClass(this.namespace + '_years'); break; case 'months': this._generateMonthpicker(index); this.calendars.eq(index).removeClass(this.namespace + '_days') .addClass(this.namespace + '_months') .removeClass(this.namespace + '_years'); break; case 'years': this._generateYearpicker(index); this.calendars.eq(index).removeClass(this.namespace + '_days') .removeClass(this.namespace + '_months') .addClass(this.namespace + '_years'); break; } }, _generateDaypicker: function(index) { this._generateHeader(index, LABEL[this.options.lang].months[this._date.currentMonth[index]] + ' ' + this._date.currentYear[index]); this.daypickers.eq(index).html(this._generateDays(index)); }, _generateMonthpicker: function(index) { this._generateHeader(index, this._date.currentYear[index]); this.monthpickers.eq(index).html(this._generateMonths(index)); }, _generateYearpicker: function(index) { this._generateHeader(index, this._date.currentYear[index] - 7 + ' ' + this.options.rangeSeparator + ' ' + (this._date.currentYear[index] + 4)); this.yearpickers.eq(index).html(this._generateYears(index)); }, _generateHeader: function(index, caption) { this.calendarCaptions.eq(index).html(caption); this._judgeLock(index); }, _generateDays: function(index) { var year = this._date.currentYear[index], month = this._date.currentMonth[index], day, daysInMonth = new Date(year, month + 1, 0).getDate(), firstDay = new Date(year, month, 1).getDay(), daysInPrevMonth = new Date(year, month, 0).getDate(), daysFromPrevMonth = firstDay - this.options.firstDayOfWeek, html = '
', isUntouch, isActive, isInRange, rangeUntouch, content, className, status = [], dateArray = []; daysFromPrevMonth = daysFromPrevMonth < 0 ? 7 + daysFromPrevMonth : daysFromPrevMonth; for (var i = 0; i < 7; i++) { var pos = this.options.firstDayOfWeek + i > 6 ? this.options.firstDayOfWeek + i - 7 : this.options.firstDayOfWeek + i; html += '' + LABEL[this.options.lang].daysShort[pos] + ''; } html += '
'; for (var j = 0; j < 42; j++) { day = (j - daysFromPrevMonth + 1); isActive = false; isInRange = false; isUntouch = false; rangeUntouch = false; status = [isUntouch, isActive, isInRange, rangeUntouch]; content = 0; className = ''; if (j > 0 && j % 7 === 0) { html += '
'; } if (j < daysFromPrevMonth) { //prev month days className = this.namespace + '_otherMonth'; content = (daysInPrevMonth - daysFromPrevMonth + j + 1); dateArray[j] = new Date(year, month - 1, content, 0, 0, 0, 0); } else if (j > (daysInMonth + daysFromPrevMonth - 1)) { //next month days className = this.namespace + '_otherMonth'; content = (day - daysInMonth); dateArray[j] = new Date(year, (month + 1), content, 0, 0, 0, 0); } else { //current month days dateArray[j] = new Date(year, month, day, 0, 0, 0, 0); content = day; if (this.hasKeyboard) { if (this.mode === 'multiple') { if (Date.parse(dateArray[j]) === Date.parse(this._date.focusDate)) { className += ' ' + this.namespace + '_focus'; } } else { if (Date.parse(dateArray[j]) === Date.parse(this._date.focusDate[index])) { className += ' ' + this.namespace + '_focus'; } } } } status = this._judgeStatus(index, 'days', this.mode, status, dateArray[j], this._date.selectedDate); className += this._renderStatus(status); html += '' + content + ''; } html += '
'; return html; }, _generateMonths: function(index) { var year = this._date.currentYear[index], html = '', className, content = LABEL[this.options.lang].monthsShort, dateArray = [], focus = this._date.focusDate[index], isActive, isInRange, isUntouch, rangeUntouch, status = []; html += '
'; for (var i = 0; i < 12; i++) { isActive = false; isInRange = false; isUntouch = false; rangeUntouch = false; status = [isUntouch, isActive, isInRange, rangeUntouch]; className = ''; if (i > 0 && i % 3 === 0) { html += '
'; } dateArray[i] = new Date(year, i, 1, 0, 0, 0, 0); if (this.hasKeyboard) { if (Date.parse(dateArray[i]) === Date.parse(new Date(focus.getFullYear(), focus.getMonth(), 1, 0, 0, 0, 0))) { className += ' ' + this.namespace + '_focus'; } } status = this._judgeStatus(index, 'months', this.mode, status, dateArray[i], this._date.selectedMonthDate); className += this._renderStatus(status); html += '' + content[i] + ''; } html += '
'; return html; }, _generateYears: function(index) { var year = this._date.currentYear[index], html = '', className, content = 0, dateArray = [], focus = this._date.focusDate[index], isActive, isInRange, isUntouch, rangeUntouch, status = []; html += '
'; for (var m = 0; m < 12; m++) { isActive = false; isInRange = false; isUntouch = false; rangeUntouch = false; status = [isUntouch, isActive, isInRange, rangeUntouch]; className = ''; content = year - 7 + m; if (m > 0 && m % 3 === 0) { html += '
'; } dateArray[m] = new Date(content, 0, 1, 0, 0, 0, 0); if (this.hasKeyboard) { if (Date.parse(dateArray[m]) === Date.parse(new Date(focus.getFullYear(), 0, 1, 0, 0, 0, 0))) { className += ' ' + this.namespace + '_focus'; } } status = this._judgeStatus(index, 'years', this.mode, status, dateArray[m], this._date.selectedYearDate); className += this._renderStatus(status); html += '' + content + ''; } html += '
'; return html; }, _judgeLock: function(index) { var prevLock = false, nextLock = false, current, selected; switch (this.mode) { case 'range': if (index === 0) { switch (this.views[index]) { case 'days': current = Date.parse(this._date.currentDate[index]); selected = Date.parse(this._date.selectedMonthDate[1]); break; case 'months': current = Date.parse(this._date.currentYearDate[index]); selected = Date.parse(this._date.selectedYearDate[1]); break; case 'years': current = new Date(this._date.currentYearDate[index]).setFullYear(this._date.currentYear[index] + 4); selected = Date.parse(this._date.selectedYearDate[1]); break; } nextLock = !this._setPoint('<', nextLock, current, selected); } else { switch (this.views[index]) { case 'days': current = Date.parse(this._date.currentDate[index]); selected = Date.parse(this._date.selectedMonthDate[0]); break; case 'months': current = Date.parse(this._date.currentYearDate[index]); selected = Date.parse(this._date.selectedYearDate[0]); break; case 'years': current = new Date(this._date.currentYearDate[index]).setFullYear(this._date.currentYear[index] - 7); selected = Date.parse(this._date.selectedYearDate[0]); break; } prevLock = !this._setPoint('>', prevLock, current, selected); } break; case 'multiple': if (this.calendarsNum > 1) { if (index === 0) { nextLock = true; } else if (index === this.calendarsNum - 1) { prevLock = true; } else { prevLock = nextLock = true; } } break; } if (prevLock === true) { this.calendarPrevs.eq(index).addClass(this.namespace + '_blocked'); } else { this.calendarPrevs.eq(index).removeClass(this.namespace + '_blocked'); } if (nextLock === true) { this.calendarNexts.eq(index).addClass(this.namespace + '_blocked'); } else { this.calendarNexts.eq(index).removeClass(this.namespace + '_blocked'); } }, _judgeSection: function(currentDate, startDate, endDate) { var status = true; if (currentDate < startDate || currentDate > endDate) { status = false; } return status; }, _judgeSections: function(type, currentDate, dateArray, isDay) { var self = this, status = false; switch (type) { case 'date': if (isDay) { currentDate = Date.parse(currentDate); $.each(dateArray, function(i, date) { if (!status) { switch (date.length) { case undefined: if (currentDate === Date.parse(date)) { status = true; } break; case 2: status = self._judgeSection(currentDate, Date.parse(date[0]), Date.parse(date[1])); break; } } }); } else { var min = Date.parse(currentDate[0]), max = Date.parse(currentDate[1]); $.each(dateArray, function(i, date) { if (!status) { switch (date.length) { case undefined: if (Date.parse(date) >= min && Date.parse(date) <= max) { status = true; } break; case 2: status = true; if (max < Date.parse(date[0]) || min > Date.parse(date[1])) { status = false; } break; } } }); } break; case 'block': $.each(dateArray, function(i, date) { if (!status) { switch (date.length) { case undefined: if (currentDate === date) { status = true; } break; case 2: status = self._judgeSection(currentDate, date[0], date[1]); break; } } }); break; case 'dayOfWeek': var curr = currentDate.getDay(); $.each(dateArray, function(i, date) { if (!status) { switch (date.length) { case undefined: if (curr === date) { status = true; } break; case 2: status = self._judgeSection(curr, date[0], date[1]); break; } } }); break; } return status; }, _judgeStatus: function(index, view, mode, status, currentDate, selectedDate) { var untouch = status[0], active = status[1], inRange = status[2]; untouch = !this._isSelectable(view, currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()); switch (mode) { case 'single': active = this._setPoint('=', active, Date.parse(currentDate), Date.parse(selectedDate[index])); break; case 'range': active = this._setPoint('=', active, Date.parse(currentDate), Date.parse(selectedDate[index])); inRange = this._setSection(inRange, currentDate, selectedDate[0], selectedDate[1]); if (index === 0) { untouch = this._setPoint('>', untouch, Date.parse(currentDate), Date.parse(selectedDate[1])); } else if (index === 1) { untouch = this._setPoint('<', untouch, Date.parse(currentDate), Date.parse(selectedDate[0])); } break; case 'multiple': for (var i = 0; i < this._date.selectedDate.length; i++) { if (Date.parse(currentDate) === selectedDate[i]) { active = true; } } break; } return status = [untouch, active, inRange]; }, _setPoint: function(type, status, currentDate, selectedDate) { var _status = status; switch (type) { case '=': if (currentDate === selectedDate) { _status = true; } break; case '<': if (currentDate < selectedDate) { _status = true; } break; case '>': if (currentDate > selectedDate) { _status = true; } break; } return _status; }, _setSection: function(status, currentDate, startDate, endDate) { var _status = status, _current = Date.parse(currentDate), _start = Date.parse(startDate), _end = Date.parse(endDate); if (_current >= _start && _current <= _end) { _status = true; } return _status; }, _isSelectable: function(view, y, m, d) { var isSelectable = true, min = this._parseDate(this.options.min, this.format), max = this._parseDate(this.options.max, this.format), selectableDate = this._parseDateArr(this.options.selectableDate, this.format), selectableYear = this._parseDateSection(this.options.selectableYear), selectableMonth = this._parseDateSection(this.options.selectableMonth), selectableDay = this._parseDateSection(this.options.selectableDay), selectableDayOfWeek = this._parseDateSection(this.options.selectableDayOfWeek); var _minDate, _maxDate, _curr, _isDay; switch (view) { case 'years': _minDate = new Date(y, 0, 1); //the first day in year _maxDate = new Date(y + 1, 0, 0); //the last day in year _curr = [_minDate, _maxDate]; _isDay = false; break; case 'months': _minDate = new Date(y, m, 1); //the first day in month _maxDate = new Date(y, m + 1, 0); //the last day in month _curr = [_minDate, _maxDate]; _isDay = false; break; case 'days': _minDate = _maxDate = _curr = new Date(y, m, d); _isDay = true; break; } if (min && min > _maxDate) { isSelectable = false; } if (max && max < _minDate) { isSelectable = false; } if (isSelectable && selectableDate.length > 0) { isSelectable = this._judgeSections('date', _curr, selectableDate, _isDay); } if (isSelectable && selectableYear.length > 0) { isSelectable = this._judgeSections('block', y, selectableYear); } if (view === 'months' || view === 'days') { if (isSelectable && selectableMonth.length > 0) { isSelectable = this._judgeSections('block', m, selectableMonth); } } if (view === 'days') { if (isSelectable && selectableDay.length > 0) { isSelectable = this._judgeSections('block', d, selectableDay); } if (isSelectable && selectableDayOfWeek.length > 0) { isSelectable = this._judgeSections('dayOfWeek', new Date(y, m, d), selectableDayOfWeek); } } return isSelectable; }, _renderStatus: function(status) { var untouch = status[0], active = status[1], inRange = status[2], rangeUntouch = status[3], className = ''; if (rangeUntouch === true) { className = ' ' + this.namespace + '_untouchable'; } else { if (untouch === true) { className = ' ' + this.namespace + '_untouchable'; } if (inRange === true) { className += ' ' + this.namespace + '_inRange'; } } if (active === true) { className += ' ' + this.namespace + '_active'; } return className; }, _changeView: function(type, index) { switch (type) { case 'caption': if (this.options.mode !== 'multiple') { if (this.views[index] === 'days') { this.views[index] = 'months'; } else if (this.views[index] === 'months') { this.views[index] = 'years'; } } break; case 'content': if (this.views[index] === 'years') { this.views[index] = 'months'; } else if (this.views[index] === 'months') { this.views[index] = 'days'; } break; case 'higher': if (this.options.mode !== 'multiple') { if (this.views[index] === 'days') { this.views[index] = 'months'; } else if (this.views[index] === 'months') { this.views[index] = 'years'; } } break; case 'lower': if (this.options.mode !== 'multiple') { if (this.views[index] === 'years') { this.views[index] = 'months'; } else if (this.views[index] === 'months') { this.views[index] = 'days'; } } break; } }, _setDate: function(obj, YTD, date) { if (typeof YTD === 'object') { for (var key in YTD) { switch (key) { case 'day': obj.setDate(YTD[key]); break; case 'month': obj.setMonth(YTD[key]); break; case 'year': obj.setYear(YTD[key]); break; } } } else { switch (YTD) { case 'day': obj.setDate(date); break; case 'month': obj.setMonth(date); break; case 'year': obj.setYear(date); break; } } }, _formatDate: function(date, format) { date = new Date(date); var val = { d: date.getDate(), m: date.getMonth() + 1, yy: date.getFullYear().toString().substring(2), yyyy: date.getFullYear() }; val.dd = (val.d < 10 ? '0' : '') + val.d; val.mm = (val.m < 10 ? '0' : '') + val.m; date = []; for (var i = 0, length = format.parts.length; i < length; i++) { date.push(val[format.parts[i]]); } return date.join(format.separator); }, _stringSeparate: function(str, separator) { var re = new RegExp("[.\\" + separator + "\\s].*?"), _separator = str.match(re), parts = str.split(_separator); return parts; }, _parseHtmlString: function(option, value) { var array = [], options = Plugin.defaults; if (typeof options[option] === 'object') { var parts = this._stringSeparate(value, ','), sub_parts; for (var i = 0; i < parts.length; i++) { sub_parts = this._stringSeparate(parts[i], '>'); if (sub_parts.length > 1) { sub_parts = { 'from': sub_parts[0], 'to': sub_parts[1] }; } else { sub_parts = sub_parts[0]; } array.push(sub_parts); } return array; } else { return value; } }, _parseFormat: function(format) { var separator = format.match(/[.\/\-\s].*?/), parts = format.split(/\W+/) || parts; if (!parts || parts.length === 0) { throw new Error('Invalid date format.'); } return { separator: separator, parts: parts }; }, _parseDate: function(data, format) { if (data !== null) { var date = new Date(), day = date.getDate(); switch (typeof(data)) { case 'string': if (data.length < 5) { date.setHours(0, 0, 0, 0); date.setDate(day + Number(data)); } else { var parts = data.split(format.separator) || parts, val; date.setHours(0, 0, 0, 0); if (parts.length === format.parts.length) { for (var i = 0, length = format.parts.length; i < length; i++) { val = parseInt(parts[i], 10) || 1; if (val === '1') { return; } switch (format.parts[i]) { case 'dd': case 'd': date.setDate(val); break; case 'mm': case 'm': date.setMonth((val - 1), 1); break; case 'yy': date.setFullYear(2000 + val); break; case 'yyyy': date.setFullYear(val); break; } } } } break; case 'number': date.setHours(0, 0, 0, 0); date.setDate(day + data); break; } return date; } else { return null; } }, _parseDateArr: function(arr, format) { var array = [], count = 0; for (var i = 0; i < arr.length; i++) { if (typeof(arr[i]) === 'string') { array[count++] = this._parseDate(arr[i], format); } else if (typeof(arr[i]) === 'object') { var obj = arr[i], from, to; for (var key in obj) { switch (key) { case 'from': from = obj[key]; break; case 'to': to = obj[key]; break; } } array[count++] = [this._parseDate(from, format), this._parseDate(to, format)]; } } return array; }, _parseDateSection: function(arr) { var array = [], count = 0; for (var i = 0; i < arr.length; i++) { if (typeof(arr[i]) === 'number') { array[count++] = arr[i]; } else if (typeof(arr[i]) === 'string') { array[count++] = Number(arr[i]); } else if (typeof(arr[i]) === 'object') { var obj = arr[i], from, to; for (var key in obj) { switch (key) { case 'from': from = Number(obj[key]); break; case 'to': to = Number(obj[key]); break; } } array[count++] = [from, to]; } } return array; }, _updateDate: function(i) { this._date.currentDate[i].setDate(1); this._date.currentDate[i].setHours(0, 0, 0, 0); this._date.currentDay[i] = this._date.currentDate[i].getDate(); this._date.currentMonth[i] = this._date.currentDate[i].getMonth(); this._date.currentYear[i] = this._date.currentDate[i].getFullYear(); this._date.currentMonthDate[i] = new Date(this._date.currentYear[i], this._date.currentMonth[i], 1, 0, 0, 0, 0); this._date.currentYearDate[i] = new Date(this._date.currentYear[i], 0, 1, 0, 0, 0, 0); if (this.mode !== 'multiple') { this._date.selectedDay[i] = this._date.selectedDate[i].getDate(); this._date.selectedMonth[i] = this._date.selectedDate[i].getMonth(); this._date.selectedYear[i] = this._date.selectedDate[i].getFullYear(); this._date.selectedMonthDate[i] = new Date(this._date.selectedYear[i], this._date.selectedMonth[i], 1, 0, 0, 0, 0); this._date.selectedYearDate[i] = new Date(this._date.selectedYear[i], 0, 1, 0, 0, 0, 0); } }, _position: function() { var calendar_height = this.$picker.outerHeight(), calendar_width = this.$picker.outerWidth(), container_height = this.$container.height() || window.innerHeight, input_top = this.$el.offset().top, input_left = this.$el.offset().left, input_height = this.$el.outerHeight(), input_width = this.$el.outerWidth(), winWidth = window.innerWidth, winHeight = window.innerHeight, scroll_left = this.$container.scrollLeft() || 0, left, top, position = this.options.position; if (this.isMobile) { left = (winWidth - calendar_width) / 2; top = (winHeight - calendar_height) / 2; } else { switch (position) { case 'bottom': case 'right': case 'left': if ((input_top + input_height + calendar_height) > (container_height)) { if (position === 'bottom') { position = 'top'; } else if (position = 'left') { position = 'leftTop'; } else if (position = 'right') { position = 'rightTop'; } } break; case 'top': case 'rightTop': case 'leftTop': if (input_top - calendar_height < 0) { if (position === 'top') { position = 'bottom'; } else if (position = 'leftTop') { position = 'left'; } else if (position = 'rightTop') { position = 'right'; } } break; } switch (position) { case 'top': left = input_left + scroll_left; top = input_top - calendar_height; break; case 'right': left = input_left + input_width + scroll_left; top = input_top; break; case 'bottom': left = input_left + scroll_left; top = input_top + input_height; break; case 'left': left = input_left - calendar_width + scroll_left; top = input_top; break; case 'rightTop': left = input_left + input_width + scroll_left; top = input_top - calendar_height + input_height; break; case 'leftTop': left = input_left - calendar_width + scroll_left; top = input_top - calendar_height + input_height; break; } } this.$picker.css({ "left": left, "top": top }); }, _toggle: function() { if (this.showed) { this.pickerHide = true; this._blur(); } else { this._focus(); } }, _focus: function() { if (this.options.displayMode === 'dropdown' && this.showed === false) { this.show(); } if (this.hasKeyboard) { this._keyboard.init(this); } }, _blur: function() { if (this.options.displayMode === 'dropdown') { if (this.pickerHide === true) { this.hide(); this.pickerHide = false; } } if (this.hasKeyboard) { this._keyboard.destroy(this); } }, _trigger: function(eventType) { var data = arguments.length > 1 ? Array.prototype.slice.call(arguments, 1).push(this) : this; // event this.$el.trigger(pluginName + '::' + eventType, data); // callback eventType = eventType.replace(/\b\w+\b/g, function(word) { return word.substring(0, 1).toUpperCase() + word.substring(1); }); var onFunction = 'on' + eventType; var method_arguments = arguments.length > 1 ? Array.prototype.slice.call(arguments, 1) : undefined; if (typeof this.options[onFunction] === 'function') { this.options[onFunction].apply(this, method_arguments); } }, _click: function(e) { var $target = $(e.target); if ($target.closest(this.$inputIcon).length === 0 && $target.closest(this.$picker).length === 0 && $target.closest(this.$el).length === 0 && this.options.alwaysShow === false) { if (this.isMobile) { this.mobileCancel(0); } else { this.hide(); } } else if ($target.closest(this.$el).length !== 1 && $target.closest(this.$picker).length === 1) { var _target = $(e.target).closest('div'); var _targetSpan = $(e.target).closest('span'); if (_target.parent('.' + this.namespace + '-header').length === 1) { var i = _target.parents('.' + this.namespace + '-content').index(); switch (_target[0].className) { case this.namespace + '-caption': this._changeView('caption', i); this._manageViews(i); break; case this.namespace + '-prev': this.prev(i); break; case this.namespace + '-next': this.next(i); break; } } if (_targetSpan.length === 1) { var j = _targetSpan.parents('.' + this.namespace + '-content').index(); if (!_targetSpan.hasClass(this.namespace + '_otherMonth') && !_targetSpan.hasClass(this.namespace + '_untouchable') && _targetSpan.parent('.' + this.namespace + '-head').length !== 1) { this._changeValue(_targetSpan, j); this._changeView('content', j); this._updateDate(j); switch (this.mode) { case 'single': if (this.views[j] === 'days') { this.selected = true; } this._manageViews(j); break; case 'range': this._manageViews(0); this._manageViews(1); break; case 'multiple': this._manageViews(j - 1); this._manageViews(j); this._manageViews(j + 1); break; } if (!this.isMobile) { this._setValue(); } } } if (_target.parent('.' + this.namespace + '-buttons').length === 1) { var k = _target.parents('.' + this.namespace + '-content').index(), flag = _target[0].className === this.namespace + '-button-save' ? true : false; if (flag) { this.mobileEnter(k); } else { this.mobileCancel(k); } } if (!this.isMobile) { if (this.selected === true && this.options.alwaysShow === false && this.options.onceClick === true) { this.hide(); } else { if (this.options.displayMode === 'dropdown') { this.$el.focus(); } } } } e.preventDefault(); }, _changeValue: function(target, i) { var newVal = '', newDate = '', self = this; switch (this.views[i]) { case 'years': newVal = parseInt(target.text(), 10); this._date.currentDate[i].setYear(newVal); break; case 'months': newVal = Number(target.attr('class').match(/month\-([0-9]+)/)[1]); this._date.currentDate[i].setMonth(newVal); break; case 'days': newVal = parseInt(target.text(), 10); newDate = new Date(this._date.currentYear[i], this._date.currentMonth[i], newVal, 0, 0, 0, 0); switch (this.options.mode) { case 'single': case 'range': this._date.selectedDate[i] = newDate; break; case 'multiple': var date = Date.parse(newDate); if ($.inArray(date, this._date.selectedDate) > -1) { $.each(this._date.selectedDate, function(nr, data) { if (data === date) { self._date.selectedDate.splice(nr, 1); } }); } else { if (this._date.selectedDate.length < this.options.multipleSize) { this._date.selectedDate.push(date); } } break; } break; } }, _setValue: function() { switch (this.mode) { case 'single': var formated = this._formatDate(this._date.selectedDate[0], this.outputFormat); this.$el.val(formated); break; case 'range': var formatedStart = this._formatDate(this._date.selectedDate[0], this.outputFormat), formatedEnd = this._formatDate(this._date.selectedDate[1], this.outputFormat); this.$el.val(formatedStart + ' ' + this.options.rangeSeparator + ' ' + formatedEnd); break; case 'multiple': var val = '', _formated; for (var j = 0; j < this._date.selectedDate.length; j++) { _formated = this._formatDate(this._date.selectedDate[j], this.outputFormat); if (val.length === 0) { val += _formated; } else { val += (this.options.multipleSeparator + _formated); } } this.$el.val(val); break; } this._trigger('change', this.getDate('yyyy-mm-dd'), this.options.name, pluginName); this.oldValue = this.$el.val(); }, _prevent: function(e) { if (e.preventDefault) { e.preventDefault(); } else { e.returnvalue = false; } }, _removeEvents: function() { if (this.options.displayMode === 'inline') { this.picker.off('click.picke'); } else { $doc.off('click.' + this.flag); } this.$el.off('focus'); this.$el.off('blur'); }, prev: function(i, isTurning) { this.touchflag = false; var date = this._date.currentDate[i]; switch (this.views[i]) { case 'days': var prevMonthDays; if (this.mode === 'multiple') { if (isTurning) { if (this.focused === 0) { for (var j = 0; j < this.calendarsNum; j++) { this._date.currentDate[j].setMonth(this._date.currentMonth[j] - 1); this._updateDate(j); this._manageViews(j); } } else { --this.focused; this._manageViews(i); this._manageViews(i - 1); } } else { prevMonthDays = new Date(date.getFullYear(), date.getMonth(), 0).getDate(); if (this._date.focusDate.getDate() > prevMonthDays) { this._date.focusDate.setDate(prevMonthDays); } this._date.focusDate.setMonth(this._date.focusDate.getMonth() - 1); for (var k = 0; k < this.calendarsNum; k++) { this._date.currentDate[k].setMonth(this._date.currentMonth[k] - 1); this._updateDate(k); this._manageViews(k); } } } else { date.setMonth(this._date.currentMonth[i] - 1); if (this.hasKeyboard) { prevMonthDays = new Date(date.getFullYear(), date.getMonth(), 0).getDate(); if (this._date.focusDate[i].getDate() > prevMonthDays) { this._date.focusDate[i].setDate(prevMonthDays); } this._date.focusDate[i] = new Date(date.getFullYear(), date.getMonth(), this._date.focusDate[i].getDate(), 0, 0, 0, 0); } } break; case 'months': date.setYear(this._date.currentYear[i] - 1); if (this.hasKeyboard) { this._date.focusDate[i] = new Date(date.getFullYear(), this._date.focusDate[i].getMonth(), this._date.focusDate[i].getDate(), 0, 0, 0, 0); } break; case 'years': date.setYear(this._date.currentYear[i] - 12); if (this.hasKeyboard && isTurning) { this._date.focusDate[i] = new Date(this._date.focusDate[i].getFullYear() - 12, this._date.focusDate[i].getMonth(), this._date.focusDate[i].getDate(), 0, 0, 0, 0); } break; } this._updateDate(i); this._manageViews(i); }, next: function(i, isTurning) { this.touchflag = false; var date = this._date.currentDate[i]; switch (this.views[i]) { case 'days': var nextMonthDays; if (this.mode === 'multiple') { if (isTurning) { if (this.focused === this.calendarsNum - 1) { for (var j = 0; j < this.calendarsNum; j++) { this._date.currentDate[j].setMonth(this._date.currentMonth[j] + 1); this._updateDate(j); this._manageViews(j); } } else { ++this.focused; this._manageViews(i); this._manageViews(i + 1); } } else { nextMonthDays = new Date(date.getFullYear(), date.getMonth() + 2, 0).getDate(); if (this._date.focusDate.getDate() > nextMonthDays) { this._date.focusDate.setDate(nextMonthDays); } this._date.focusDate.setMonth(this._date.focusDate.getMonth() + 1); for (var k = 0; k < this.calendarsNum; k++) { this._date.currentDate[k].setMonth(this._date.currentMonth[k] + 1); this._updateDate(k); this._manageViews(k); } } } else { date.setMonth(this._date.currentMonth[i] + 1); if (this.hasKeyboard) { nextMonthDays = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(); if (this._date.focusDate[i].getDate() > nextMonthDays) { this._date.focusDate[i].setDate(nextMonthDays); } this._date.focusDate[i] = new Date(date.getFullYear(), date.getMonth(), this._date.focusDate[i].getDate(), 0, 0, 0, 0); } } break; case 'months': date.setYear(this._date.currentYear[i] + 1); if (this.hasKeyboard) { this._date.focusDate[i] = new Date(date.getFullYear(), this._date.focusDate[i].getMonth(), this._date.focusDate[i].getDate(), 0, 0, 0, 0); } break; case 'years': date.setYear(this._date.currentYear[i] + 12); if (this.hasKeyboard && isTurning) { this._date.focusDate[i] = new Date(this._date.focusDate[i].getFullYear() + 12, this._date.focusDate[i].getMonth(), this._date.focusDate[i].getDate(), 0, 0, 0, 0); } break; } this._updateDate(i); this._manageViews(i); }, mobilePrev: function(index) { this.calendars.eq(index).removeClass(this.namespace + '_show'); this.calendars.eq(index - 1).addClass(this.namespace + '_show'); }, mobileNext: function(index) { this.calendars.eq(index).removeClass(this.namespace + '_show'); this.calendars.eq(index + 1).addClass(this.namespace + '_show'); }, mobileInteDate: function(index) { var self = this; if (this.mode === 'multiple') { if (this._date.selectedDate.length > 0) { self._date.currentDate[0] = new Date(this._date.selectedDate[0]); } } else { this._date.currentDate[index] = new Date(this._date.selectedDate[index]); } this.views[index] = 'days'; this._updateDate(index); }, mobileEnter: function(index) { if (this.mode === 'range' && index === 0) { this.mobileNext(index); this.views[index] = 'days'; } else { this.mobileInteDate(index); this._setValue(); this.hide(); } this._manageViews(index); }, mobileCancel: function(index) { if (index === 1) { this.mobilePrev(index); this.views[index] = 'days'; } else { this.dateTransform(this._date.cache, this._date); this.mobileInteDate(index); this.hide(); } this._manageViews(index); }, dateTransform: function(fromDate, toDate) { var self = this; toDate.currentDate = []; toDate.selectedDate = []; $.each(fromDate.currentDate, function(n, v) { toDate.currentDate[n] = new Date(v); }); $.each(fromDate.selectedDate, function(n, v) { var date = new Date(v); toDate.selectedDate[n] = self.mode === 'multiple' ? Date.parse(date) : date; }); }, show: function() { var self = this; if (this.isMobile) { this.dateTransform(this._date, this._date.cache); } if (this.options.displayMode === 'inline') { this._trigger('beforeShow'); this.$picker.on('mouseDown.' + this.flag, function(e) { self._prevent(e); }); this.$picker.on('click.' + this.flag, function(e) { self._click.call(self, e); }); } else { if (this.showed === false) { this._trigger('beforeShow'); this.$inputWrap.addClass(this.namespace + '_active'); // this.$picker.removeClass(this.namespace + '_hide'); this.$picker.addClass(this.namespace + '_show'); if (this.isMobile) { this.calendars.eq(0).addClass(this.namespace + '_show'); if (this.mode === 'range') { this.calendars.eq(1).removeClass(this.namespace + '_show'); } $('body').append(this.$cover).css('overflow', 'hidden'); //Prevent horizontal scroll for ios $doc.on('scrollstart.' + this.flag, function(e) { e.preventDefault(); }); $doc.on('tap.' + this.flag, function(e) { self._click.call(self, e); }); var handle = function(e) { var startX = e.swipestart.coords[0], stopX = e.swipestop.coords[0]; if (stopX > startX) { self.prev.call(self, 0); } else if (stopX < startX) { self.next.call(self, 0); } $doc.one('swipe.' + self.flag, handle); }; $doc.one('swipe.' + this.flag, handle); } else { $doc.on('click.' + this.flag, function(e) { self._click.call(self, e); }); } this._position(); this.showed = true; $win.on('resize.' + this.flag, function() { self._position(); }); // this.$el.focus(); this.$picker.on('mousedown.' + this.flag, function(e) { self._prevent(e); }); } } this._trigger('show'); return this; }, hide: function() { if (this.showed === true) { this._trigger('beforeHide'); this.selected = false; this.$inputWrap.removeClass(this.namespace + '_active'); this.$picker.removeClass(this.namespace + '_show'); this.showed = false; this.$picker.off('mousedown.' + this.flag); $doc.off('click.' + this.flag); $win.off('resize.' + this.flag); if (this.isMobile) { $('body').css('overflow', 'auto'); this.$cover.remove(); $doc.off('click.' + this.flag + ' tap.' + this.flag + ' scrollstart.' + this.flag + ' swipe.' + this.flag); } this.$el.blur(); this._trigger('hide'); } return this; }, getWrap: function() { return this.picker; }, getInput: function() { return this.$el; }, getDate: function(format) { if (format === undefined) { return this._date.selectedDate; } else { var _format = this._parseFormat(format), formated = []; for (var i = 0; i < this._date.selectedDate.length; i++) { formated[i] = this._formatDate(this._date.selectedDate[i], _format); } return formated; } }, multipleClear: function() { this._date.selectedDate = []; for (var i = 0; i < this.calendarsNum; i++) { this._manageViews(i); } this._setValue(); }, destroy: function() { this.$el.removeData('asDatepicker'); this._removeEvents(); this.$picker.remove(); }, update: function(_options) { if (typeof _options !== 'undefined') { for (var m in _options) { this.options[m] = _options[m]; } } this._removeEvents(); this.$picker.remove(); this._init(); }, reset: function(_options) { for (var m in this.defaultOptions) { this.options[m] = this.defaultOptions[m]; } if (typeof _options !== 'undefined') { for (var n in _options) { this.options[n] = _options[n]; } } this._removeEvents(); this.$picker.remove(); this._init(); }, _keyboard: { init: function(self) { this.attach(self, this.gather(self)); }, destroy: function(self) { if (self.options.displayMode === 'dropdown') { self.$el.off('keydown.dropdown'); } else { self.$picker.off('keydown.inline'); } self.bound = false; }, keys: function() { return { 'LEFT': 37, 'UP': 38, 'RIGHT': 39, 'DOWN': 40, 'ENTER': 13, 'ESC': 27, 'CTRL': 17, 'ALT': 18 }; }, prevDate: function() { var i = this.focused, date = this.mode === 'multiple' ? this._date.focusDate : this._date.focusDate[i], hasLocked = this.mode === 'multiple' ? false : this.calendarPrevs.eq(this.focused).hasClass(this.namespace + '_blocked'); switch (this.views[i]) { case 'days': if (Date.parse(date) === Date.parse(this._date.currentDate[i])) { if (!hasLocked) { date.setDate(date.getDate() - 1); this.prev(i, true); } } else { date.setDate(date.getDate() - 1); this._manageViews(i); } break; case 'months': if (date.getMonth() === 0) { if (!hasLocked) { date.setMonth(date.getMonth() - 1); this.prev(i); } } else { date.setMonth(date.getMonth() - 1); this._manageViews(i); } break; case 'years': if (date.getFullYear() === this._date.currentYear[i] - 7) { if (!hasLocked) { date.setFullYear(date.getFullYear() - 1); this.prev(i); } } else { date.setFullYear(date.getFullYear() - 1); this._manageViews(i); } break; } }, nextDate: function() { var i = this.focused, date = this.mode === 'multiple' ? this._date.focusDate : this._date.focusDate[i], hasLocked = this.mode === 'multiple' ? false : this.calendarNexts.eq(this.focused).hasClass(this.namespace + '_blocked'); switch (this.views[i]) { case 'days': if (Date.parse(date) === Date.parse(new Date(this._date.currentYear[i], this._date.currentMonth[i] + 1, 0))) { if (!hasLocked) { date.setDate(date.getDate() + 1); this.next(i, true); } } else { date.setDate(date.getDate() + 1); this._manageViews(i); } break; case 'months': if (date.getMonth() === 11) { if (!hasLocked) { date.setMonth(date.getMonth() + 1); this.next(i); } } else { date.setMonth(date.getMonth() + 1); this._manageViews(i); } break; case 'years': if (date.getFullYear() === this._date.currentYear[i] + 4) { if (!hasLocked) { date.setFullYear(date.getFullYear() + 1); this.next(i); } } else { date.setFullYear(date.getFullYear() + 1); this._manageViews(i); } break; } }, upLine: function() { var i = this.focused, date = this.mode === 'multiple' ? this._date.focusDate : this._date.focusDate[i], hasLocked = this.mode === 'multiple' ? false : this.calendarPrevs.eq(this.focused).hasClass(this.namespace + '_blocked'); switch (this.views[i]) { case 'days': if (new Date(date.getFullYear(), date.getMonth(), date.getDate() - 7).setDate(1) === new Date(this._date.currentDate[i]).setMonth(this._date.currentMonth[i] - 1)) { if (!hasLocked) { date.setDate(date.getDate() - 7); this.prev(i, true); } } else { date.setDate(date.getDate() - 7); this._manageViews(i); } break; case 'months': if (date.getMonth() === 0 || date.getMonth() === 1 || date.getMonth() === 2) { if (!hasLocked) { date.setMonth(date.getMonth() - 3); this.prev(i); } } else { date.setMonth(date.getMonth() - 3); this._manageViews(i); } break; case 'years': if (date.getFullYear() < this._date.currentYear[i] - 4) { if (!hasLocked) { date.setFullYear(date.getFullYear() - 3); this.prev(i); } } else { date.setFullYear(date.getFullYear() - 3); this._manageViews(i); } break; } }, downLine: function() { var i = this.focused, date = this.mode === 'multiple' ? this._date.focusDate : this._date.focusDate[i], hasLocked = this.mode === 'multiple' ? false : this.calendarNexts.eq(this.focused).hasClass(this.namespace + '_blocked'); switch (this.views[i]) { case 'days': if (new Date(date.getFullYear(), date.getMonth(), date.getDate() + 7).setDate(1) === new Date(this._date.currentDate[i]).setMonth(this._date.currentMonth[i] + 1)) { if (!hasLocked) { date.setDate(date.getDate() + 7); this.next(i, true); } } else { date.setDate(date.getDate() + 7); this._manageViews(i); } break; case 'months': if (date.getMonth() === 9 || date.getMonth() === 10 || date.getMonth() === 11) { if (!hasLocked) { date.setMonth(date.getMonth() + 3); this.next(i); } } else { date.setMonth(date.getMonth() + 3); this._manageViews(i); } break; case 'years': if (date.getFullYear() > this._date.currentYear[i] + 1) { if (!hasLocked) { date.setFullYear(date.getFullYear() + 3); this.next(i); } } else { date.setFullYear(date.getFullYear() + 3); this._manageViews(i); } break; } }, prevPage: function() { if (this.mode === 'multiple') { this.prev(this.focused); } else { if (!this.calendarPrevs.eq(this.focused).hasClass(this.namespace + '_blocked')) { this.prev(this.focused, true); } } }, nextPage: function() { if (this.mode === 'multiple') { this.next(this.focused); } else { if (!this.calendarNexts.eq(this.focused).hasClass(this.namespace + '_blocked')) { this.next(this.focused, true); } } }, higherView: function() { if (this.mode !== 'multiple') { var i = this.focused; this._changeView('higher', i); this._manageViews(i); } }, prevCalendar: function() { if (this.mode !== 'multiple') { var len = this.calendars.length; if (--this.focused < 0) { this.focused = len; } } }, nextCalendar: function() { if (this.mode !== 'multiple') { var len = this.calendars.length; if (++this.focused >= len) { this.focused = 0; } } }, updateValue: function(self) { var i = self.focused, date = self.mode === 'multiple' ? self._date.focusDate : self._date.focusDate[i]; if (!self.calendars.eq(i).find('.' + self.namespace + '_focus').hasClass(self.namespace + '_untouchable')) { switch (self.views[i]) { case 'days': switch (self.options.mode) { case 'single': case 'range': self._date.selectedDate[i] = new Date(date); break; case 'multiple': var _date = Date.parse(new Date(date)); if ($.inArray(_date, self._date.selectedDate) > -1) { $.each(self._date.selectedDate, function(nr, data) { if (data === _date) { self._date.selectedDate.splice(nr, 1); return false; } }); } else { self._date.selectedDate.push(_date); } break; } break; case 'months': self._date.currentDate[i].setMonth(date.getMonth()); self.views[i] = 'days'; break; case 'years': self._date.currentDate[i].setFullYear(date.getFullYear()); self.views[i] = 'months'; break; } self._updateDate(i); if (self.mode === 'range') { self._manageViews(0); self._manageViews(1); } else if (self.mode === 'multiple') { self._manageViews(i - 1); self._manageViews(i); self._manageViews(i + 1); } else { self._manageViews(i); } self._setValue(); } }, enter: function() { var inputValue = this.$el.val(), self = this, judge; if (inputValue === this.oldValue || this.oldValue === '') { this._keyboard.updateValue(this); } else { var parts; switch (this.mode) { case 'single': var _date = Date.parse(inputValue); if (_date) { this._date.selectedDate[0] = new Date(_date); this._date.currentDate[0] = new Date(this._date.selectedDate[0]); this._updateDate(0); this._manageViews(0); } break; case 'range': parts = this._stringSeparate(inputValue, this.options.rangeSeparator); var from = Date.parse(parts[0]), to = Date.parse(parts[1]); if (parts.length === 2) { judge = true; if (from && to) { if (from > to) { judge = false; } } else { judge = false; } } else { judge = false; } if (judge === true) { this._date.selectedDate[0] = new Date(from); this._date.selectedDate[1] = new Date(to); for (var i = 0; i < 2; i++) { this._date.currentDate[i] = new Date(this._date.selectedDate[i]); this._updateDate(i); this._manageViews(i); } } else { this._keyboard.updateValue(this); } break; case 'multiple': parts = this._stringSeparate(inputValue, this.options.multipleSeparator); var _parts = []; judge = true; for (var j = 0; j < parts.length; j++) { _parts.push(Date.parse(parts[j])); if (!Date.parse(parts[j])) { judge = false; } } if (judge === true) { this._date.selectedDate = []; for (var k = 0; k < _parts.length; k++) { if ($.inArray(_parts[k], this._date.selectedDate) > -1) { $.each(this._date.selectedDate, function(nr, data) { if (data === _parts[k]) { self._date.selectedDate.splice(nr, 1); } }); } else { this._date.selectedDate.push(_parts[k]); } } for (var m = 0; m < this.calendarsNum; m++) { this._updateDate(m); this._manageViews(m); } } else { this._keyboard.updateValue(this); } break; } } this._setValue(); }, esc: function() { this.$el.blur(); this.hide(); }, tab: function() { this.pickerHide = true; }, gather: function(self) { return { left: $.proxy(this.prevDate, self), up: $.proxy(this.upLine, self), right: $.proxy(this.nextDate, self), down: $.proxy(this.downLine, self), ctrl_left: $.proxy(this.prevPage, self), ctrl_up: $.proxy(this.higherView, self), ctrl_right: $.proxy(this.nextPage, self), // ctrl_down: $.proxy(this.lowerView, self), alt_left: $.proxy(this.prevCalendar, self), alt_right: $.proxy(this.nextCalendar, self), enter: $.proxy(this.enter, self), esc: $.proxy(this.esc, self) }; }, press: function(e) { var key = e.keyCode || e.which, map; if (e.ctrlKey) { e.preventDefault(); map = this.map[17]; } else if (e.altKey) { e.preventDefault(); map = this.map[18]; } else { map = this.map; } if (key === 9) { this._keyboard.tab.call(this); } if (key in map && typeof map[key] === 'function') { e.preventDefault(); map[key].call(this); } }, attach: function(self, map) { var key, _self = this; for (key in map) { if (map.hasOwnProperty(key)) { var uppercase = [], parts = self._stringSeparate(key, '_'), len = parts.length; if (len === 1) { uppercase[0] = parts[0].toUpperCase(); self.map[this.keys()[uppercase[0]]] = map[key]; } else { for (var i = 0; i < parts.length; i++) { uppercase[i] = parts[i].toUpperCase(); if (i === 0) { if (self.map[this.keys()[uppercase[0]]] === undefined) { self.map[this.keys()[uppercase[0]]] = {}; } } else { self.map[this.keys()[uppercase[0]]][this.keys()[uppercase[i]]] = map[key]; } } } } } if (!self.bound) { self.bound = true; if (self.options.displayMode === 'dropdown') { self.$el.on('keydown.dropdown', function(e) { _self.press.call(self, e); }); } else { self.$picker.on('keydown.inline', function(e) { _self.press.call(self, e); }); } } } } }; Plugin.defaults = defaults; $.fn[pluginName] = function(options) { if (typeof options === 'string') { var method = options; var method_arguments = Array.prototype.slice.call(arguments, 1); if (/^\_/.test(method)) { return false; } else if (/^(getWrap|getInput|getDate)$/.test(method)) { var api = this.first().data(pluginName); if (api && typeof api[method] === 'function') { return api[method].apply(api, method_arguments); } } else { return this.each(function() { var api = $.data(this, pluginName); if (api && typeof api[method] === 'function') { api[method].apply(api, method_arguments); } }); } } else { return this.each(function() { if (!$.data(this, pluginName)) { $.data(this, pluginName, new Plugin(this, options)); } }); } }; })(jQuery, document, window);