From a0d00a6e205098fa576c17905e5ef8e837e37d12 Mon Sep 17 00:00:00 2001 From: t1m0n Date: Fri, 4 Dec 2015 12:11:48 +0300 Subject: [PATCH] complete keyboard nav --- dist/css/datepicker.css | 2 + dist/css/datepicker.min.css | 2 +- dist/js/datepicker.js | 277 +++++++++++++++++++------------ dist/js/datepicker.min.js | 2 +- docs/jade/pages/index-ru.jade | 21 --- src/js/body.js | 35 ++-- src/js/datepicker.js | 242 +++++++++++++++++---------- src/sass/_datepicker-config.scss | 1 + src/sass/cell.scss | 4 + 9 files changed, 345 insertions(+), 241 deletions(-) diff --git a/dist/css/datepicker.css b/dist/css/datepicker.css index 0f9518b..a3801b8 100644 --- a/dist/css/datepicker.css +++ b/dist/css/datepicker.css @@ -60,6 +60,8 @@ .datepicker--cell.-selected-.-current- { color: #fff; background: #5cc4ef; } + .datepicker--cell.-selected-.-focus- { + background: #45bced; } .datepicker--days-names { display: -webkit-flex; diff --git a/dist/css/datepicker.min.css b/dist/css/datepicker.min.css index 1156b2b..39f1898 100644 --- a/dist/css/datepicker.min.css +++ b/dist/css/datepicker.min.css @@ -1 +1 @@ -.datepicker--cells{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.datepicker--cell{border-radius:4px;cursor:pointer;display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;height:32px;z-index:1}.datepicker--cell.-focus-,.datepicker--cell:hover{background:#f0f0f0}.datepicker--cell.-current-{color:#4EB5E6}.datepicker--cell.-current-.-focus-,.datepicker--cell.-current-:hover{color:#4a4a4a}.datepicker--cell.-disabled-{cursor:default;color:#aeaeae;background:0 0}.datepicker--cell.-disabled-.-focus-{color:#aeaeae;background:#f0f0f0}.datepicker--cell.-disabled-.-current-:hover{color:#aeaeae}.datepicker--cell.-selected-,.datepicker--cell.-selected-.-current-{color:#fff;background:#5cc4ef}.datepicker--days-names{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin:8px 0 3px}.datepicker--day-name{color:#FF9A19;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex:1;-ms-flex:1;flex:1;text-align:center;text-transform:uppercase;font-size:.8em}.datepicker--body,.datepicker-inline .datepicker--pointer{display:none}.datepicker--cell-day{width:14.28571%}.datepicker--cells-months{height:170px}.datepicker--cell-month{width:33.33%;height:25%}.datepicker--cells-years,.datepicker--years{height:170px}.datepicker--cell-year{width:25%;height:33.33%}.datepickers-container{position:absolute;left:0;top:0}.datepicker{background:#fff;border:1px solid #dbdbdb;box-shadow:0 4px 12px rgba(0,0,0,.15);border-radius:4px;box-sizing:content-box;font-family:Tahoma,sans-serif;font-size:14px;color:#4a4a4a;width:250px;position:absolute;left:-100000px;opacity:0;transition:opacity .3s ease,left 0s .3s,-webkit-transform .3s ease;transition:opacity .3s ease,transform .3s ease,left 0s .3s;transition:opacity .3s ease,transform .3s ease,left 0s .3s,-webkit-transform .3s ease;z-index:100}.datepicker.-from-top-{-webkit-transform:translateY(-8px);transform:translateY(-8px)}.datepicker.-from-right-{-webkit-transform:translateX(8px);transform:translateX(8px)}.datepicker.-from-bottom-{-webkit-transform:translateY(8px);transform:translateY(8px)}.datepicker.-from-left-{-webkit-transform:translateX(-8px);transform:translateX(-8px)}.datepicker.active{opacity:1;-webkit-transform:translate(0);transform:translate(0);transition:opacity .3s ease,left 0s 0s,-webkit-transform .3s ease;transition:opacity .3s ease,transform .3s ease,left 0s 0s;transition:opacity .3s ease,transform .3s ease,left 0s 0s,-webkit-transform .3s ease}.datepicker-inline .datepicker{border-color:#d7d7d7;box-shadow:none;position:static;left:auto;right:auto;opacity:1;-webkit-transform:none;transform:none}.datepicker--content{box-sizing:content-box;padding:4px}.datepicker--pointer{position:absolute;background:#fff;border-top:1px solid #dbdbdb;border-right:1px solid #dbdbdb;width:10px;height:10px;z-index:-1}.datepicker--nav-action:hover,.datepicker--nav-title:hover{background:#f0f0f0}.-top-center- .datepicker--pointer,.-top-left- .datepicker--pointer,.-top-right- .datepicker--pointer{top:calc(100% - 4px);-webkit-transform:rotate(135deg);transform:rotate(135deg)}.-right-bottom- .datepicker--pointer,.-right-center- .datepicker--pointer,.-right-top- .datepicker--pointer{right:calc(100% - 4px);-webkit-transform:rotate(225deg);transform:rotate(225deg)}.-bottom-center- .datepicker--pointer,.-bottom-left- .datepicker--pointer,.-bottom-right- .datepicker--pointer{bottom:calc(100% - 4px);-webkit-transform:rotate(315deg);transform:rotate(315deg)}.-left-bottom- .datepicker--pointer,.-left-center- .datepicker--pointer,.-left-top- .datepicker--pointer{left:calc(100% - 4px);-webkit-transform:rotate(45deg);transform:rotate(45deg)}.-bottom-left- .datepicker--pointer,.-top-left- .datepicker--pointer{left:10px}.-bottom-right- .datepicker--pointer,.-top-right- .datepicker--pointer{right:10px}.-bottom-center- .datepicker--pointer,.-top-center- .datepicker--pointer{left:calc(50% - 10px / 2)}.-left-top- .datepicker--pointer,.-right-top- .datepicker--pointer{top:10px}.-left-bottom- .datepicker--pointer,.-right-bottom- .datepicker--pointer{bottom:10px}.-left-center- .datepicker--pointer,.-right-center- .datepicker--pointer{top:calc(50% - 10px / 2)}.datepicker--body.active{display:block}.datepicker--nav{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;border-bottom:1px solid #efefef;min-height:32px;padding:4px}.datepicker--nav-action,.datepicker--nav-title{display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.datepicker--nav-action{width:32px;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.datepicker--nav-action.-disabled-{visibility:hidden}.datepicker--nav-action svg{width:32px;height:32px}.datepicker--nav-action path{fill:none;stroke:#9c9c9c;stroke-width:2px}.datepicker--nav-title{border-radius:4px;padding:0 8px}.datepicker--nav-title i{font-style:normal;color:#9c9c9c;margin-left:5px}.datepicker--nav-title.-disabled-{cursor:default;background:0 0}.datepicker--buttons{display:-webkit-flex;display:-ms-flexbox;display:flex;padding:4px;border-top:1px solid #efefef}.datepicker--button{color:#4EB5E6;cursor:pointer;border-radius:4px;-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:32px}.datepicker--button:hover{color:#4a4a4a;background:#f0f0f0}.datepicker--cell-day.-other-month-,.datepicker--cell-year.-other-decade-{color:#dedede}.datepicker--cell-day.-other-month-:hover,.datepicker--cell-year.-other-decade-:hover{color:#c5c5c5}.-disabled-.datepicker--cell-day.-other-month-:hover,.-disabled-.datepicker--cell-year.-other-decade-:hover{color:#dedede}.-selected-.datepicker--cell-day.-other-month-,.-selected-.datepicker--cell-year.-other-decade-{color:#fff;background:#a2ddf6}.datepicker--cell-day.-other-month-:empty,.datepicker--cell-year.-other-decade-:empty{background:0 0;border:none} \ No newline at end of file +.datepicker--cells{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.datepicker--cell{border-radius:4px;cursor:pointer;display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;height:32px;z-index:1}.datepicker--cell.-focus-,.datepicker--cell:hover{background:#f0f0f0}.datepicker--cell.-current-{color:#4EB5E6}.datepicker--cell.-current-.-focus-,.datepicker--cell.-current-:hover{color:#4a4a4a}.datepicker--cell.-disabled-{cursor:default;color:#aeaeae;background:0 0}.datepicker--cell.-disabled-.-focus-{color:#aeaeae;background:#f0f0f0}.datepicker--cell.-disabled-.-current-:hover{color:#aeaeae}.datepicker--cell.-selected-,.datepicker--cell.-selected-.-current-{color:#fff;background:#5cc4ef}.datepicker--cell.-selected-.-focus-{background:#45bced}.datepicker--days-names{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin:8px 0 3px}.datepicker--day-name{color:#FF9A19;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex:1;-ms-flex:1;flex:1;text-align:center;text-transform:uppercase;font-size:.8em}.datepicker--body,.datepicker-inline .datepicker--pointer{display:none}.datepicker--cell-day{width:14.28571%}.datepicker--cells-months{height:170px}.datepicker--cell-month{width:33.33%;height:25%}.datepicker--cells-years,.datepicker--years{height:170px}.datepicker--cell-year{width:25%;height:33.33%}.datepickers-container{position:absolute;left:0;top:0}.datepicker{background:#fff;border:1px solid #dbdbdb;box-shadow:0 4px 12px rgba(0,0,0,.15);border-radius:4px;box-sizing:content-box;font-family:Tahoma,sans-serif;font-size:14px;color:#4a4a4a;width:250px;position:absolute;left:-100000px;opacity:0;transition:opacity .3s ease,left 0s .3s,-webkit-transform .3s ease;transition:opacity .3s ease,transform .3s ease,left 0s .3s;transition:opacity .3s ease,transform .3s ease,left 0s .3s,-webkit-transform .3s ease;z-index:100}.datepicker.-from-top-{-webkit-transform:translateY(-8px);transform:translateY(-8px)}.datepicker.-from-right-{-webkit-transform:translateX(8px);transform:translateX(8px)}.datepicker.-from-bottom-{-webkit-transform:translateY(8px);transform:translateY(8px)}.datepicker.-from-left-{-webkit-transform:translateX(-8px);transform:translateX(-8px)}.datepicker.active{opacity:1;-webkit-transform:translate(0);transform:translate(0);transition:opacity .3s ease,left 0s 0s,-webkit-transform .3s ease;transition:opacity .3s ease,transform .3s ease,left 0s 0s;transition:opacity .3s ease,transform .3s ease,left 0s 0s,-webkit-transform .3s ease}.datepicker-inline .datepicker{border-color:#d7d7d7;box-shadow:none;position:static;left:auto;right:auto;opacity:1;-webkit-transform:none;transform:none}.datepicker--content{box-sizing:content-box;padding:4px}.datepicker--pointer{position:absolute;background:#fff;border-top:1px solid #dbdbdb;border-right:1px solid #dbdbdb;width:10px;height:10px;z-index:-1}.datepicker--nav-action:hover,.datepicker--nav-title:hover{background:#f0f0f0}.-top-center- .datepicker--pointer,.-top-left- .datepicker--pointer,.-top-right- .datepicker--pointer{top:calc(100% - 4px);-webkit-transform:rotate(135deg);transform:rotate(135deg)}.-right-bottom- .datepicker--pointer,.-right-center- .datepicker--pointer,.-right-top- .datepicker--pointer{right:calc(100% - 4px);-webkit-transform:rotate(225deg);transform:rotate(225deg)}.-bottom-center- .datepicker--pointer,.-bottom-left- .datepicker--pointer,.-bottom-right- .datepicker--pointer{bottom:calc(100% - 4px);-webkit-transform:rotate(315deg);transform:rotate(315deg)}.-left-bottom- .datepicker--pointer,.-left-center- .datepicker--pointer,.-left-top- .datepicker--pointer{left:calc(100% - 4px);-webkit-transform:rotate(45deg);transform:rotate(45deg)}.-bottom-left- .datepicker--pointer,.-top-left- .datepicker--pointer{left:10px}.-bottom-right- .datepicker--pointer,.-top-right- .datepicker--pointer{right:10px}.-bottom-center- .datepicker--pointer,.-top-center- .datepicker--pointer{left:calc(50% - 10px / 2)}.-left-top- .datepicker--pointer,.-right-top- .datepicker--pointer{top:10px}.-left-bottom- .datepicker--pointer,.-right-bottom- .datepicker--pointer{bottom:10px}.-left-center- .datepicker--pointer,.-right-center- .datepicker--pointer{top:calc(50% - 10px / 2)}.datepicker--body.active{display:block}.datepicker--nav{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;border-bottom:1px solid #efefef;min-height:32px;padding:4px}.datepicker--nav-action,.datepicker--nav-title{display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.datepicker--nav-action{width:32px;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.datepicker--nav-action.-disabled-{visibility:hidden}.datepicker--nav-action svg{width:32px;height:32px}.datepicker--nav-action path{fill:none;stroke:#9c9c9c;stroke-width:2px}.datepicker--nav-title{border-radius:4px;padding:0 8px}.datepicker--nav-title i{font-style:normal;color:#9c9c9c;margin-left:5px}.datepicker--nav-title.-disabled-{cursor:default;background:0 0}.datepicker--buttons{display:-webkit-flex;display:-ms-flexbox;display:flex;padding:4px;border-top:1px solid #efefef}.datepicker--button{color:#4EB5E6;cursor:pointer;border-radius:4px;-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:32px}.datepicker--button:hover{color:#4a4a4a;background:#f0f0f0}.datepicker--cell-day.-other-month-,.datepicker--cell-year.-other-decade-{color:#dedede}.datepicker--cell-day.-other-month-:hover,.datepicker--cell-year.-other-decade-:hover{color:#c5c5c5}.-disabled-.datepicker--cell-day.-other-month-:hover,.-disabled-.datepicker--cell-year.-other-decade-:hover{color:#dedede}.-selected-.datepicker--cell-day.-other-month-,.-selected-.datepicker--cell-year.-other-decade-{color:#fff;background:#a2ddf6}.datepicker--cell-day.-other-month-:empty,.datepicker--cell-year.-other-decade-:empty{background:0 0;border:none} \ No newline at end of file diff --git a/dist/js/datepicker.js b/dist/js/datepicker.js index b45e2a7..b335e2c 100644 --- a/dist/js/datepicker.js +++ b/dist/js/datepicker.js @@ -57,6 +57,7 @@ var Datepicker; months: 'yyyy', years: 'yyyy1 - yyyy2' }, + keyboardNav: true, // events onSelect: '', @@ -75,6 +76,10 @@ var Datepicker; 'shiftUp': [16, 38], 'shiftLeft': [16, 37], 'shiftDown': [16, 40], + 'altUp': [18, 38], + 'altRight': [18, 39], + 'altLeft': [18, 37], + 'altDown': [18, 40], 'ctrlShiftUp': [16, 17, 38] }; @@ -155,9 +160,11 @@ var Datepicker; this.$datepicker.on('mouseup', this._onMouseUpDatepicker.bind(this)); $(window).on('resize', this._onResize.bind(this)); - this.$el.on('keydown', this._onKeyDown.bind(this)); - this.$el.on('keyup', this._onKeyUp.bind(this)); - this.$el.on('hotKey', this._onHotKey.bind(this)); + if (this.opts.keyboardNav) { + this.$el.on('keydown', this._onKeyDown.bind(this)); + this.$el.on('keyup', this._onKeyUp.bind(this)); + this.$el.on('hotKey', this._onHotKey.bind(this)); + } }, isWeekend: function (day) { @@ -572,109 +579,45 @@ var Datepicker; left: '-100000px' }); + this.focused = ''; + this.keys = []; + this.inFocus = false; this.visible = false; this.$el.blur(); }, down: function (date) { - date = date || this.focused || this.date; - - var nextViewIndex = this.viewIndex - 1; - if (nextViewIndex < 0) nextViewIndex = 0; - this.silent = true; - this.date = new Date(date.getFullYear(), date.getMonth(), 1); - this.silent = false; - this.view = this.viewIndexes[nextViewIndex]; + this._changeView(date, 'down'); }, up: function (date) { + this._changeView(date, 'up'); + }, + + _changeView: function (date, dir) { date = date || this.focused || this.date; - var nextViewIndex = this.viewIndex + 1; - if (nextViewIndex > 2) nextViewIndex = 2; + var nextView = dir == 'up' ? this.viewIndex + 1 : this.viewIndex - 1; + if (nextView > 2) nextView = 2; + if (nextView < 0) nextView = 0; + this.silent = true; this.date = new Date(date.getFullYear(), date.getMonth(), 1); this.silent = false; - this.view = this.viewIndexes[nextViewIndex]; - }, + this.view = this.viewIndexes[nextView]; - _onShowEvent: function () { - 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; - this.$el.focus() - }, - - _onInput: function () { - var val = this.$el.val(); - - if (!val) { - this.clear(); - } - }, - - _onResize: function () { - if (this.visible) { - this.setPosition(); - } - }, -//TODO добавить esc - _onKeyDown: function (e) { - var code = e.which; - - this._registerKey(code); - - if (code >= 37 && code <= 40) { - e.preventDefault(); - this._focusNextCell(code); - } - - if (code == 13) { - if (this.focused) { - if (this._getCell(this.focused).hasClass('-disabled-')) return; - if (this.view != this.opts.minView) { - this.down() - } else { - var alreadySelected = this._isSelected(this.focused, this.cellType); - - if (!alreadySelected) { - this.selectDate(this.focused); - } else if (alreadySelected && this.opts.toggleSelected){ - this.removeDate(this.focused); - } - } - } - } - }, - - _onKeyUp: function (e) { - var code = e.which; - this._unRegisterKey(code); - }, - - _onHotKey: function (e, hotKey) { - this._handleHotKey(hotKey); }, _handleHotKey: function (key) { var date = Datepicker.getParsedDate(this._getFocusedDate()), - nd, + focusedParsed, + o = this.opts, + newDate, totalDaysInNextMonth, + monthChanged = false, + yearChanged = false, + decadeChanged = false, y = date.year, m = date.month, d = date.date; @@ -683,36 +626,63 @@ var Datepicker; case 'ctrlRight': case 'ctrlUp': m += 1; + monthChanged = true; break; case 'ctrlLeft': case 'ctrlDown': m -= 1; + monthChanged = true; break; case 'shiftRight': case 'shiftUp': + yearChanged = true; y += 1; break; case 'shiftLeft': case 'shiftDown': + yearChanged = true; y -= 1; break; + case 'altRight': + case 'altUp': + decadeChanged = true; + y += 10; + break; + case 'altLeft': + case 'altDown': + decadeChanged = true; + y -= 10; + break; case 'ctrlShiftUp': this.up(); break; } totalDaysInNextMonth = Datepicker.getDaysCount(new Date(y,m)); + newDate = new Date(y,m,d); - nd = new Date(y,m,d); + // If next month has less days than current, set date to total days in that month if (totalDaysInNextMonth < d) d = totalDaysInNextMonth; - if (nd.getTime() < this.minTime) { - nd = this.minDate; - } else if (nd.getTime() > this.maxTime) { - nd = this.maxDate; + // 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 = nd; + this.focused = newDate; + + focusedParsed = Datepicker.getParsedDate(newDate); + if (monthChanged && o.onChangeMonth) { + o.onChangeMonth(focusedParsed.month, focusedParsed.year) + } + if (yearChanged && o.onChangeYear) { + o.onChangeYear(focusedParsed.year) + } + if (decadeChanged && o.onChangeDecade) { + o.onChangeDecade(this.curDecade) + } }, _registerKey: function (key) { @@ -841,7 +811,95 @@ var Datepicker; return $cell.length ? $cell : ''; }, + _onShowEvent: function () { + 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; + this.$el.focus() + }, + + _onInput: function () { + var val = this.$el.val(); + + if (!val) { + this.clear(); + } + }, + + _onResize: function () { + if (this.visible) { + this.setPosition(); + } + }, + + _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.focused, this.cellType); + + if (!alreadySelected) { + this.selectDate(this.focused); + } else if (alreadySelected && this.opts.toggleSelected){ + this.removeDate(this.focused); + } + } + } + } + + // Esc + if (code == 27) { + this.hide(); + } + }, + + _onKeyUp: function (e) { + var code = e.which; + this._unRegisterKey(code); + }, + + _onHotKey: function (e, hotKey) { + this._handleHotKey(hotKey); + }, + + + set focused(val) { + if (!val && this.focused) { + var $cell = this._getCell(this.focused); + + if ($cell.length) { + $cell.removeClass('-focus-') + } + } this._focused = val; this.date = val; }, @@ -1025,9 +1083,10 @@ var Datepicker; '
' + '
' + '
' - }; + }, + D = Datepicker; - Datepicker.Body = function (d, type, opts) { + D.Body = function (d, type, opts) { this.d = d; this.type = type; this.opts = opts; @@ -1035,7 +1094,7 @@ var Datepicker; this.init(); }; - Datepicker.Body.prototype = { + D.Body.prototype = { init: function () { this._buildBaseHtml(); this._render(); @@ -1073,7 +1132,7 @@ var Datepicker; * @private */ _getDaysHtml: function (date) { - var totalMonthDays = Datepicker.getDaysCount(date), + var totalMonthDays = D.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, @@ -1099,7 +1158,7 @@ var Datepicker; _getDayHtml: function (date) { var _class = "datepicker--cell datepicker--cell-day", currentDate = new Date(), - d = Datepicker.getParsedDate(date), + d = D.getParsedDate(date), render = {}, html = d.date; @@ -1110,8 +1169,8 @@ var Datepicker; } if (this.d.isWeekend(d.day)) _class += " -weekend-"; - if (Datepicker.isSame(currentDate, date)) _class += ' -current-'; - if (this.d.focused && Datepicker.isSame(date, this.d.focused)) _class += ' -focus-'; + if (D.isSame(currentDate, date)) _class += ' -current-'; + if (this.d.focused && D.isSame(date, this.d.focused)) _class += ' -focus-'; if (this.d._isSelected(date, 'day')) _class += ' -selected-'; if (!this.d._isInRange(date) || render.disabled) _class += ' -disabled-'; if (d.month != this.d.parsedDate.month) { @@ -1138,7 +1197,7 @@ var Datepicker; */ _getMonthsHtml: function (date) { var html = '', - d = Datepicker.getParsedDate(date), + d = D.getParsedDate(date), i = 0; while(i < 12) { @@ -1151,7 +1210,7 @@ var Datepicker; _getMonthHtml: function (date) { var _class = "datepicker--cell datepicker--cell-month", - d = Datepicker.getParsedDate(date), + d = D.getParsedDate(date), currentDate = new Date(), loc = this.d.loc, html = loc[this.opts.monthsFiled][d.month], @@ -1163,17 +1222,17 @@ var Datepicker; _class += render.classes ? ' ' + render.classes : ''; } - if (Datepicker.isSame(currentDate, date, 'month')) _class += ' -current-'; + if (D.isSame(currentDate, date, 'month')) _class += ' -current-'; if (this.d._isSelected(date, 'month')) _class += ' -selected-'; - if (this.d.focused && Datepicker.isSame(date, this.d.focused, 'month')) _class += ' -focus-'; + if (this.d.focused && D.isSame(date, this.d.focused, 'month')) _class += ' -focus-'; if (!this.d._isInRange(date, 'month') || render.disabled) _class += ' -disabled-'; return '
' + html + '
' }, _getYearsHtml: function (date) { - var d = Datepicker.getParsedDate(date), - decade = Datepicker.getDecade(date), + var d = D.getParsedDate(date), + decade = D.getDecade(date), firstYear = decade[0] - 1, html = '', i = firstYear; @@ -1187,9 +1246,9 @@ var Datepicker; _getYearHtml: function (date) { var _class = "datepicker--cell datepicker--cell-year", - decade = Datepicker.getDecade(this.d.date), + decade = D.getDecade(this.d.date), currentDate = new Date(), - d = Datepicker.getParsedDate(date), + d = D.getParsedDate(date), html = d.year, render = {}; @@ -1209,9 +1268,9 @@ var Datepicker; if (!this.opts.showOtherYears) html = ''; } - if (Datepicker.isSame(currentDate, date, 'year')) _class += ' -current-'; + if (D.isSame(currentDate, date, 'year')) _class += ' -current-'; if (this.d._isSelected(date, 'year')) _class += ' -selected-'; - if (this.d.focused && Datepicker.isSame(date, this.d.focused, 'year')) _class += ' -focus-'; + if (this.d.focused && D.isSame(date, this.d.focused, 'year')) _class += ' -focus-'; if (!this.d._isInRange(date, 'year') || render.disabled) _class += ' -disabled-'; return '
' + html + '
' diff --git a/dist/js/datepicker.min.js b/dist/js/datepicker.min.js index 56eeb79..77e9a6b 100644 --- a/dist/js/datepicker.min.js +++ b/dist/js/datepicker.min.js @@ -1 +1 @@ -var Datepicker;!function(t,e,i){var s,a,n="datepicker",h=".datepicker-here",r=!1,o='
',c={classes:"",inline:!1,language:"ru",startDate:new Date,firstDay:"",weekends:[6,0],dateFormat:"",toggleSelected:!0,position:"bottom left",offset:12,view:"days",minView:"days",showOtherMonths:!0,selectOtherMonths:!0,moveToOtherMonthsOnSelect:!0,showOtherYears:!0,selectOtherYears:!0,moveToOtherYearsOnSelect:!0,minDate:"",maxDate:"",disableNavWhenOutOfRange:!0,multipleDates:!1,multipleDatesSeparator:",",todayButton:!1,clearButton:!1,showEvent:"focus",autoClose:!1,monthsFiled:"monthsShort",prevHtml:'',nextHtml:'',navTitles:{days:"MM, yyyy",months:"yyyy",years:"yyyy1 - yyyy2"},onSelect:"",onChangeMonth:"",onChangeYear:"",onChangeDecade:"",onChangeView:"",onRenderCell:""},d={ctrlRight:[17,39],ctrlUp:[17,38],ctrlLeft:[17,37],ctrlDown:[17,40],shiftRight:[16,39],shiftUp:[16,38],shiftLeft:[16,37],shiftDown:[16,40],ctrlShiftUp:[16,17,38]};Datepicker=function(t,a){this.el=t,this.$el=e(t),this.opts=e.extend(!0,{},c,a,this.$el.data()),s==i&&(s=e("body")),this.opts.startDate||(this.opts.startDate=new Date),"INPUT"==this.el.nodeName&&(this.elIsInput=!0),this.inited=!1,this.visible=!1,this.silent=!1,this.currentDate=this.opts.startDate,this.currentView=this.opts.view,this._createShortCuts(),this.selectedDates=[],this.views={},this.keys=[],this.init()},Datepicker.prototype={viewIndexes:["days","months","years"],init:function(){r||this.opts.inline||!this.elIsInput||this._buildDatepickersContainer(),this._buildBaseHtml(),this._defineLocale(this.opts.language),this._syncWithMinMaxDates(),this.elIsInput&&(this.opts.inline||(this._setPositionClasses(this.opts.position),this._bindEvents())),this.opts.classes&&this.$datepicker.addClass(this.opts.classes),this.views[this.currentView]=new Datepicker.Body(this,this.currentView,this.opts),this.views[this.currentView].show(),this.nav=new Datepicker.Navigation(this,this.opts),this.view=this.currentView,this.inited=!0},_createShortCuts:function(){this.minDate=this.opts.minDate?this.opts.minDate:new Date(-86399999136e5),this.maxDate=this.opts.maxDate?this.opts.maxDate:new Date(86399999136e5)},_bindEvents:function(){this.$el.on(this.opts.showEvent,this._onShowEvent.bind(this)),this.$el.on("blur",this._onBlur.bind(this)),this.$el.on("input",this._onInput.bind(this)),this.$datepicker.on("mousedown",this._onMouseDownDatepicker.bind(this)),this.$datepicker.on("mouseup",this._onMouseUpDatepicker.bind(this)),e(t).on("resize",this._onResize.bind(this)),this.$el.on("keydown",this._onKeyDown.bind(this)),this.$el.on("keyup",this._onKeyUp.bind(this)),this.$el.on("hotKey",this._onHotKey.bind(this))},isWeekend:function(t){return-1!==this.opts.weekends.indexOf(t)},_defineLocale:function(t){"string"==typeof t?(this.loc=Datepicker.language[t],this.loc||(console.warn("Can't find language \""+t+'" in Datepicker.language, will use "ru" instead'),this.loc=e.extend(!0,{},Datepicker.language.ru)),this.loc=e.extend(!0,{},Datepicker.language.ru,Datepicker.language[t])):this.loc=e.extend(!0,{},Datepicker.language.ru,t),this.opts.dateFormat&&(this.loc.dateFormat=this.opts.dateFormat),this.opts.firstDay&&(this.loc.firstDay=this.opts.firstDay)},_buildDatepickersContainer:function(){r=!0,s.append('
'),a=e("#datepickers-container")},_buildBaseHtml:function(){var t,i=e('
');t="INPUT"==this.el.nodeName?this.opts.inline?i.insertAfter(this.$el):a:i.appendTo(this.$el),this.$datepicker=e(o).appendTo(t),this.$content=e(".datepicker--content",this.$datepicker),this.$nav=e(".datepicker--nav",this.$datepicker)},_triggerOnChange:function(){if(!this.selectedDates.length)return this.opts.onSelect("","",this);var t,e=this.selectedDates,i=Datepicker.getParsedDate(e[0]),s=this,a=new Date(i.year,i.month,i.date);t=e.map(function(t){return s.formatDate(s.loc.dateFormat,t)}).join(this.opts.multipleDatesSeparator),this.opts.multipleDates&&(a=e.map(function(t){var e=Datepicker.getParsedDate(t);return new Date(e.year,e.month,e.date)})),this.opts.onSelect(t,a,this)},next:function(){var t=this.parsedDate,e=this.opts;switch(this.view){case"days":this.date=new Date(t.year,t.month+1,1),e.onChangeMonth&&e.onChangeMonth(this.parsedDate.month,this.parsedDate.year);break;case"months":this.date=new Date(t.year+1,t.month,1),e.onChangeYear&&e.onChangeYear(this.parsedDate.year);break;case"years":this.date=new Date(t.year+10,0,1),e.onChangeDecade&&e.onChangeDecade(this.curDecade)}},prev:function(){var t=this.parsedDate,e=this.opts;switch(this.view){case"days":this.date=new Date(t.year,t.month-1,1),e.onChangeMonth&&e.onChangeMonth(this.parsedDate.month,this.parsedDate.year);break;case"months":this.date=new Date(t.year-1,t.month,1),e.onChangeYear&&e.onChangeYear(this.parsedDate.year);break;case"years":this.date=new Date(t.year-10,0,1),e.onChangeDecade&&e.onChangeDecade(this.curDecade)}},formatDate:function(t,e){e=e||this.date;var i=t,s=this.loc,a=Datepicker.getDecade(e),n=Datepicker.getParsedDate(e);switch(!0){case/dd/.test(i):i=i.replace(/\bdd\b/,n.fullDate);case/d/.test(i):i=i.replace(/\bd\b/,n.date);case/DD/.test(i):i=i.replace(/\bDD\b/,s.days[n.day]);case/D/.test(i):i=i.replace(/\bD\b/,s.daysShort[n.day]);case/mm/.test(i):i=i.replace(/\bmm\b/,n.fullMonth);case/m/.test(i):i=i.replace(/\bm\b/,n.month+1);case/MM/.test(i):i=i.replace(/\bMM\b/,this.loc.months[n.month]);case/M/.test(i):i=i.replace(/\bM\b/,s.monthsShort[n.month]);case/yyyy/.test(i):i=i.replace(/\byyyy\b/,n.year);case/yyyy1/.test(i):i=i.replace(/\byyyy1\b/,a[0]);case/yyyy2/.test(i):i=i.replace(/\byyyy2\b/,a[1]);case/yy/.test(i):i=i.replace(/\byy\b/,n.year.toString().slice(-2))}return i},selectDate:function(t){var e=this.parsedDate,i="";if(t instanceof Date){if("days"==this.view&&t.getMonth()!=e.month&&this.opts.moveToOtherMonthsOnSelect&&(i=new Date(t.getFullYear(),t.getMonth(),1)),"years"==this.view&&t.getFullYear()!=e.year&&this.opts.moveToOtherYearsOnSelect&&(i=new Date(t.getFullYear(),0,1)),i&&(this.silent=!0,this.date=i,this.silent=!1,this.nav._render()),this.opts.multipleDates){if(this.selectedDates.length===this.opts.multipleDates)return;this._isSelected(t)||this.selectedDates.push(t)}else this.selectedDates=[t];this._setInputValue(),this.opts.onSelect&&this._triggerOnChange(),this.opts.autoClose?this.hide():this.views[this.currentView]._render()}},removeDate:function(t){var e=this.selectedDates,i=this;if(t instanceof Date)return e.some(function(s,a){return Datepicker.isSame(s,t)?(e.splice(a,1),i.views[i.currentView]._render(),i._setInputValue(),i.opts.onSelect&&i._triggerOnChange(),!0):void 0})},today:function(){this.silent=!0,this.view=this.opts.minView,this.silent=!1,this.date=new Date},clear:function(){this.selectedDates=[],this.views[this.currentView]._render(),this.opts.onSelect&&this._triggerOnChange()},update:function(t,i){var s=arguments.length;return 2==s?this.opts[t]=i:1==s&&"object"==typeof t&&(this.opts=e.extend(!0,this.opts,t)),this._createShortCuts(),this._syncWithMinMaxDates(),this._defineLocale(this.opts.language),this.nav._addButtonsIfNeed(),this.nav._render(),this.views[this.currentView]._render(),this.elIsInput&&!this.opts.inline&&(this._setPositionClasses(this.opts.position),this.visible&&this.setPosition(this.opts.position)),this.opts.classes&&this.$datepicker.addClass(this.opts.classes),this},_syncWithMinMaxDates:function(){var t=this.date.getTime();this.silent=!0,this.minTime>t&&(this.date=this.minDate),this.maxTime=this.minTime&&i<=this.maxTime,month:h>=this.minTime&&r<=this.maxTime,year:s.year>=a.year&&s.year<=n.year};return e?o[e]:o.day},_getDimensions:function(t){var e=t.offset();return{width:t.outerWidth(),height:t.outerHeight(),left:e.left,top:e.top}},_setPositionClasses:function(t){t=t.split(" ");var e=t[0],i=t[1],s="datepicker -"+e+"-"+i+"- -from-"+e+"-";this.visible&&(s+=" active"),this.$datepicker.removeAttr("class").addClass(s)},setPosition:function(t){t=t||this.opts.position;var e,i,s=this._getDimensions(this.$el),a=this._getDimensions(this.$datepicker),n=t.split(" "),h=this.opts.offset,r=n[0],o=n[1];switch(r){case"top":e=s.top-a.height-h;break;case"right":i=s.left+s.width+h;break;case"bottom":e=s.top+s.height+h;break;case"left":i=s.left-a.width-h}switch(o){case"top":e=s.top;break;case"right":i=s.left+s.width-a.width;break;case"bottom":e=s.top+s.height-a.height;break;case"left":i=s.left;break;case"center":/left|right/.test(r)?e=s.top+s.height/2-a.height/2:i=s.left+s.width/2-a.width/2}this.$datepicker.css({left:i,top:e})},show:function(){this.setPosition(this.opts.position),this.$datepicker.addClass("active"),this.visible=!0},hide:function(){this.$datepicker.removeClass("active").css({left:"-100000px"}),this.inFocus=!1,this.visible=!1,this.$el.blur()},down:function(t){t=t||this.focused||this.date;var e=this.viewIndex-1;0>e&&(e=0),this.silent=!0,this.date=new Date(t.getFullYear(),t.getMonth(),1),this.silent=!1,this.view=this.viewIndexes[e]},up:function(t){t=t||this.focused||this.date;var e=this.viewIndex+1;e>2&&(e=2),this.silent=!0,this.date=new Date(t.getFullYear(),t.getMonth(),1),this.silent=!1,this.view=this.viewIndexes[e]},_onShowEvent:function(){this.visible||this.show()},_onBlur:function(){!this.inFocus&&this.visible&&this.hide()},_onMouseDownDatepicker:function(t){this.inFocus=!0},_onMouseUpDatepicker:function(t){this.inFocus=!1,this.$el.focus()},_onInput:function(){var t=this.$el.val();t||this.clear()},_onResize:function(){this.visible&&this.setPosition()},_onKeyDown:function(t){var e=t.which;if(this._registerKey(e),e>=37&&40>=e&&(t.preventDefault(),this._focusNextCell(e)),13==e&&this.focused){if(this._getCell(this.focused).hasClass("-disabled-"))return;if(this.view!=this.opts.minView)this.down();else{var i=this._isSelected(this.focused,this.cellType);i?i&&this.opts.toggleSelected&&this.removeDate(this.focused):this.selectDate(this.focused)}}},_onKeyUp:function(t){var e=t.which;this._unRegisterKey(e)},_onHotKey:function(t,e){this._handleHotKey(e)},_handleHotKey:function(t){var e,i,s=Datepicker.getParsedDate(this._getFocusedDate()),a=s.year,n=s.month,h=s.date;switch(t){case"ctrlRight":case"ctrlUp":n+=1;break;case"ctrlLeft":case"ctrlDown":n-=1;break;case"shiftRight":case"shiftUp":a+=1;break;case"shiftLeft":case"shiftDown":a-=1;break;case"ctrlShiftUp":this.up()}i=Datepicker.getDaysCount(new Date(a,n)),e=new Date(a,n,h),h>i&&(h=i),e.getTime()this.maxTime&&(e=this.maxDate),this.focused=e},_registerKey:function(t){var e=this.keys.some(function(e){return e==t});e||this.keys.push(t)},_unRegisterKey:function(t){var e=this.keys.indexOf(t);this.keys.splice(e,1)},_isHotKeyPressed:function(){var t,e=!1,i=this,s=this.keys.sort();for(var a in d)t=d[a],s.length==t.length&&t.every(function(t,e){return t==s[e]})&&(i._trigger("hotKey",a),e=!0);return e},_trigger:function(t,e){this.$el.trigger(t,e)},_focusNextCell:function(t,e){e=e||this.cellType;var i=Datepicker.getParsedDate(this._getFocusedDate()),s=i.year,a=i.month,n=i.date;if(!this._isHotKeyPressed()){switch(t){case 37:"day"==e?n-=1:"","month"==e?a-=1:"","year"==e?s-=1:"";break;case 38:"day"==e?n-=7:"","month"==e?a-=3:"","year"==e?s-=4:"";break;case 39:"day"==e?n+=1:"","month"==e?a+=1:"","year"==e?s+=1:"";break;case 40:"day"==e?n+=7:"","month"==e?a+=3:"","year"==e?s+=4:""}var h=new Date(s,a,n);h.getTime()this.maxTime&&(h=this.maxDate),this.focused=h}},_getFocusedDate:function(){var t=this.focused||this.selectedDates[this.selectedDates.length-1],e=this.parsedDate;if(!t)switch(this.view){case"days":t=new Date(e.year,e.month,(new Date).getDate());break;case"months":t=new Date(e.year,e.month,1);break;case"years":t=new Date(e.year,0,1)}return t},_getCell:function(t,e){e=e||this.cellType;var i,s=Datepicker.getParsedDate(t),a='.datepicker--cell[data-year="'+s.year+'"]';switch(e){case"month":a='[data-month="'+s.month+'"]';break;case"day":a+='[data-month="'+s.month+'"][data-date="'+s.date+'"]'}return i=this.views[this.currentView].$el.find(a),i.length?i:""},set focused(t){this._focused=t,this.date=t},get focused(){return this._focused},get parsedDate(){return Datepicker.getParsedDate(this.date)},set date(t){return t instanceof Date?(this.currentDate=t,this.inited&&!this.silent&&(this.views[this.view]._render(),this.nav._render(),this.visible&&this.elIsInput&&this.setPosition()),t):void 0},get date(){return this.currentDate},set view(t){return this.viewIndex=this.viewIndexes.indexOf(t),this.viewIndex<0?void 0:(this.prevView=this.currentView,this.currentView=t,this.inited&&(this.views[t]?this.views[t]._render():this.views[t]=new Datepicker.Body(this,t,this.opts),this.views[this.prevView].hide(),this.views[t].show(),this.nav._render(),this.opts.onChangeView&&this.opts.onChangeView(t),this.elIsInput&&this.visible&&this.setPosition()),t)},get view(){return this.currentView},get cellType(){return this.view.substring(0,this.view.length-1)},get minTime(){var t=Datepicker.getParsedDate(this.minDate);return new Date(t.year,t.month,t.date).getTime()},get maxTime(){var t=Datepicker.getParsedDate(this.maxDate);return new Date(t.year,t.month,t.date).getTime()},get curDecade(){return Datepicker.getDecade(this.date)}},Datepicker.getDaysCount=function(t){return new Date(t.getFullYear(),t.getMonth()+1,0).getDate()},Datepicker.getParsedDate=function(t){return{year:t.getFullYear(),month:t.getMonth(),fullMonth:t.getMonth()+1<10?"0"+(t.getMonth()+1):t.getMonth()+1,date:t.getDate(),fullDate:t.getDate()<10?"0"+t.getDate():t.getDate(),day:t.getDay()}},Datepicker.getDecade=function(t){var e=10*Math.floor(t.getFullYear()/10);return[e,e+9]},Datepicker.template=function(t,e){return t.replace(/#\{([\w]+)\}/g,function(t,i){return e[i]||0===e[i]?e[i]:void 0})},Datepicker.isSame=function(t,e,i){var s=Datepicker.getParsedDate(t),a=Datepicker.getParsedDate(e),n=i?i:"day",h={day:s.date==a.date&&s.month==a.month&&s.year==a.year,month:s.month==a.month&&s.year==a.year,year:s.year==a.year};return h[n]},Datepicker.language={ru:{days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вос","Пон","Вто","Сре","Чет","Пят","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",dateFormat:"dd.mm.yyyy",firstDay:1}},e.fn[n]=function(t){return Datepicker.prototype[t]?void Datepicker.prototype[t].apply(this.data(n),Array.prototype.slice.call(arguments,1)):this.each(function(){if(e.data(this,n)){var i=e.data(this,n);i.opts=e.extend(!0,i.opts,t),i.update()}else e.data(this,n,new Datepicker(this,t))})},e(function(){e(h).datepicker()})}(window,jQuery),function(){var t={days:'
',months:'
',years:'
'};Datepicker.Body=function(t,e,i){this.d=t,this.type=e,this.opts=i,this.init()},Datepicker.Body.prototype={init:function(){this._buildBaseHtml(),this._render(),this._bindEvents()},_bindEvents:function(){this.$el.on("click",".datepicker--cell",$.proxy(this._onClickCell,this))},_buildBaseHtml:function(){this.$el=$(t[this.type]).appendTo(this.d.$content),this.$names=$(".datepicker--days-names",this.$el),this.$cells=$(".datepicker--cells",this.$el)},_getDayNamesHtml:function(t,e,i,s){return e=void 0!=e?e:t,i=i?i:"",s=void 0!=s?s:0,s>7?i:7==e?this._getDayNamesHtml(t,0,i,++s):(i+='
'+this.d.loc.daysMin[e]+"
",this._getDayNamesHtml(t,++e,i,++s))},_getDaysHtml:function(t){var e=Datepicker.getDaysCount(t),i=new Date(t.getFullYear(),t.getMonth(),1).getDay(),s=new Date(t.getFullYear(),t.getMonth(),e).getDay(),a=i-this.d.loc.firstDay,n=6-s+this.d.loc.firstDay;a=0>a?a+7:a,n=n>6?n-7:n;for(var h,r,o=-a+1,c="",d=o,l=e+n;l>=d;d++)r=t.getFullYear(),h=t.getMonth(),c+=this._getDayHtml(new Date(r,h,d));return c},_getDayHtml:function(t){var e="datepicker--cell datepicker--cell-day",i=new Date,s=Datepicker.getParsedDate(t),a={},n=s.date;return this.opts.onRenderCell&&(a=this.opts.onRenderCell(t,"day")||{},n=a.html?a.html:n,e+=a.classes?" "+a.classes:""),this.d.isWeekend(s.day)&&(e+=" -weekend-"),Datepicker.isSame(i,t)&&(e+=" -current-"),this.d.focused&&Datepicker.isSame(t,this.d.focused)&&(e+=" -focus-"),this.d._isSelected(t,"day")&&(e+=" -selected-"),(!this.d._isInRange(t)||a.disabled)&&(e+=" -disabled-"),s.month!=this.d.parsedDate.month&&(e+=" -other-month-",this.opts.selectOtherMonths||(e+=" -disabled-"),this.opts.showOtherMonths||(n="")),'
'+n+"
"},_getMonthsHtml:function(t){for(var e="",i=Datepicker.getParsedDate(t),s=0;12>s;)e+=this._getMonthHtml(new Date(i.year,s)),s++;return e},_getMonthHtml:function(t){var e="datepicker--cell datepicker--cell-month",i=Datepicker.getParsedDate(t),s=new Date,a=this.d.loc,n=a[this.opts.monthsFiled][i.month],h={};return this.opts.onRenderCell&&(h=this.opts.onRenderCell(t,"month")||{},n=h.html?h.html:n,e+=h.classes?" "+h.classes:""),Datepicker.isSame(s,t,"month")&&(e+=" -current-"),this.d._isSelected(t,"month")&&(e+=" -selected-"),this.d.focused&&Datepicker.isSame(t,this.d.focused,"month")&&(e+=" -focus-"),(!this.d._isInRange(t,"month")||h.disabled)&&(e+=" -disabled-"),'
'+n+"
"},_getYearsHtml:function(t){var e=(Datepicker.getParsedDate(t),Datepicker.getDecade(t)),i=e[0]-1,s="",a=i;for(a;a<=e[1]+1;a++)s+=this._getYearHtml(new Date(a,0));return s},_getYearHtml:function(t){var e="datepicker--cell datepicker--cell-year",i=Datepicker.getDecade(this.d.date),s=new Date,a=Datepicker.getParsedDate(t),n=a.year,h={};return this.opts.onRenderCell&&(h=this.opts.onRenderCell(t,"year")||{},n=h.html?h.html:n,e+=h.classes?" "+h.classes:""),(a.yeari[1])&&(e+=" -other-decade-",this.opts.selectOtherYears||(e+=" -disabled-"),this.opts.showOtherYears||(n="")),Datepicker.isSame(s,t,"year")&&(e+=" -current-"),this.d._isSelected(t,"year")&&(e+=" -selected-"),this.d.focused&&Datepicker.isSame(t,this.d.focused,"year")&&(e+=" -focus-"),(!this.d._isInRange(t,"year")||h.disabled)&&(e+=" -disabled-"),'
'+n+"
"},_renderTypes:{days:function(){var t=this._getDayNamesHtml(this.d.loc.firstDay),e=this._getDaysHtml(this.d.currentDate);this.$cells.html(e),this.$names.html(t)},months:function(){var t=this._getMonthsHtml(this.d.currentDate);this.$cells.html(t)},years:function(){var t=this._getYearsHtml(this.d.currentDate);this.$cells.html(t)}},_render:function(){this._renderTypes[this.type].bind(this)()},show:function(){this.$el.addClass("active"),this.acitve=!0},hide:function(){this.$el.removeClass("active"),this.active=!1},_handleClick:function(t){var e=t.data("date")||1,i=t.data("month")||0,s=t.data("year")||this.d.parsedDate.year;if(this.d.view!=this.opts.minView)return void this.d.down(new Date(s,i,e));var a=new Date(s,i,e),n=this.d._isSelected(a,this.d.cellType);n?n&&this.opts.toggleSelected&&this.d.removeDate(a):this.d.selectDate(a)},_onClickCell:function(t){var e=$(t.target).closest(".datepicker--cell");e.hasClass("-disabled-")||this._handleClick.bind(this)(e)}}}(),function(){var t='
#{prevHtml}
#{title}
#{nextHtml}
',e='
',i='#{label}';Datepicker.Navigation=function(t,e){this.d=t,this.opts=e,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._onClickNavButton,this)),this.d.$nav.on("click",".datepicker--nav-title",$.proxy(this._onClickNavTitle,this)),this.d.$datepicker.on("click",".datepicker--button",$.proxy(this._onClickNavButton,this))},_buildBaseHtml:function(){this._render(),this._addButtonsIfNeed()},_addButtonsIfNeed:function(){this.opts.todayButton&&this._addButton("today"),this.opts.clearButton&&this._addButton("clear")},_render:function(){var e=this._getTitle(this.d.currentDate),i=Datepicker.template(t,$.extend({title:e},this.opts));this.d.$nav.html(i),"years"==this.d.view&&$(".datepicker--nav-title",this.d.$nav).addClass("-disabled-"),this.setNavStatus()},_getTitle:function(t){return this.d.formatDate(this.opts.navTitles[this.d.view],t)},_addButton:function(t){this.$buttonsContainer.length||this._addButtonsContainer();var e={action:t,label:this.d.loc[t]},s=Datepicker.template(i,e);this.$buttonsContainer.append(s)},_addButtonsContainer:function(){this.d.$datepicker.append(e),this.$buttonsContainer=$(".datepicker--buttons",this.d.$datepicker)},setNavStatus:function(){if((this.opts.minDate||this.opts.maxDate)&&this.opts.disableNavWhenOutOfRange){var t=this.d.parsedDate,e=t.month,i=t.year,s=t.date;switch(this.d.view){case"days":this.d._isInRange(new Date(i,e-1,s),"month")||this._disableNav("prev"),this.d._isInRange(new Date(i,e+1,s),"month")||this._disableNav("next");break;case"months":this.d._isInRange(new Date(i-1,e,s),"year")||this._disableNav("prev"),this.d._isInRange(new Date(i+1,e,s),"year")||this._disableNav("next");break;case"years":this.d._isInRange(new Date(i-10,e,s),"year")||this._disableNav("prev"),this.d._isInRange(new Date(i+10,e,s),"year")||this._disableNav("next")}}},_disableNav:function(t){$('[data-action="'+t+'"]',this.d.$nav).addClass("-disabled-")},_activateNav:function(t){$('[data-action="'+t+'"]',this.d.$nav).removeClass("-disabled-")},_onClickNavButton:function(t){var e=$(t.target).closest("[data-action]"),i=e.data("action");this.d[i]()},_onClickNavTitle:function(t){return $(t.target).hasClass("-disabled-")?void 0:"days"==this.d.view?this.d.view="months":void(this.d.view="years")}}}(); \ No newline at end of file +var Datepicker;!function(t,e,i){var s,a,n="datepicker",h=".datepicker-here",o=!1,r='
',c={classes:"",inline:!1,language:"ru",startDate:new Date,firstDay:"",weekends:[6,0],dateFormat:"",toggleSelected:!0,position:"bottom left",offset:12,view:"days",minView:"days",showOtherMonths:!0,selectOtherMonths:!0,moveToOtherMonthsOnSelect:!0,showOtherYears:!0,selectOtherYears:!0,moveToOtherYearsOnSelect:!0,minDate:"",maxDate:"",disableNavWhenOutOfRange:!0,multipleDates:!1,multipleDatesSeparator:",",todayButton:!1,clearButton:!1,showEvent:"focus",autoClose:!1,monthsFiled:"monthsShort",prevHtml:'',nextHtml:'',navTitles:{days:"MM, yyyy",months:"yyyy",years:"yyyy1 - yyyy2"},keyboardNav:!0,onSelect:"",onChangeMonth:"",onChangeYear:"",onChangeDecade:"",onChangeView:"",onRenderCell:""},d={ctrlRight:[17,39],ctrlUp:[17,38],ctrlLeft:[17,37],ctrlDown:[17,40],shiftRight:[16,39],shiftUp:[16,38],shiftLeft:[16,37],shiftDown:[16,40],altUp:[18,38],altRight:[18,39],altLeft:[18,37],altDown:[18,40],ctrlShiftUp:[16,17,38]};Datepicker=function(t,a){this.el=t,this.$el=e(t),this.opts=e.extend(!0,{},c,a,this.$el.data()),s==i&&(s=e("body")),this.opts.startDate||(this.opts.startDate=new Date),"INPUT"==this.el.nodeName&&(this.elIsInput=!0),this.inited=!1,this.visible=!1,this.silent=!1,this.currentDate=this.opts.startDate,this.currentView=this.opts.view,this._createShortCuts(),this.selectedDates=[],this.views={},this.keys=[],this.init()},Datepicker.prototype={viewIndexes:["days","months","years"],init:function(){o||this.opts.inline||!this.elIsInput||this._buildDatepickersContainer(),this._buildBaseHtml(),this._defineLocale(this.opts.language),this._syncWithMinMaxDates(),this.elIsInput&&(this.opts.inline||(this._setPositionClasses(this.opts.position),this._bindEvents())),this.opts.classes&&this.$datepicker.addClass(this.opts.classes),this.views[this.currentView]=new Datepicker.Body(this,this.currentView,this.opts),this.views[this.currentView].show(),this.nav=new Datepicker.Navigation(this,this.opts),this.view=this.currentView,this.inited=!0},_createShortCuts:function(){this.minDate=this.opts.minDate?this.opts.minDate:new Date(-86399999136e5),this.maxDate=this.opts.maxDate?this.opts.maxDate:new Date(86399999136e5)},_bindEvents:function(){this.$el.on(this.opts.showEvent,this._onShowEvent.bind(this)),this.$el.on("blur",this._onBlur.bind(this)),this.$el.on("input",this._onInput.bind(this)),this.$datepicker.on("mousedown",this._onMouseDownDatepicker.bind(this)),this.$datepicker.on("mouseup",this._onMouseUpDatepicker.bind(this)),e(t).on("resize",this._onResize.bind(this)),this.opts.keyboardNav&&(this.$el.on("keydown",this._onKeyDown.bind(this)),this.$el.on("keyup",this._onKeyUp.bind(this)),this.$el.on("hotKey",this._onHotKey.bind(this)))},isWeekend:function(t){return-1!==this.opts.weekends.indexOf(t)},_defineLocale:function(t){"string"==typeof t?(this.loc=Datepicker.language[t],this.loc||(console.warn("Can't find language \""+t+'" in Datepicker.language, will use "ru" instead'),this.loc=e.extend(!0,{},Datepicker.language.ru)),this.loc=e.extend(!0,{},Datepicker.language.ru,Datepicker.language[t])):this.loc=e.extend(!0,{},Datepicker.language.ru,t),this.opts.dateFormat&&(this.loc.dateFormat=this.opts.dateFormat),this.opts.firstDay&&(this.loc.firstDay=this.opts.firstDay)},_buildDatepickersContainer:function(){o=!0,s.append('
'),a=e("#datepickers-container")},_buildBaseHtml:function(){var t,i=e('
');t="INPUT"==this.el.nodeName?this.opts.inline?i.insertAfter(this.$el):a:i.appendTo(this.$el),this.$datepicker=e(r).appendTo(t),this.$content=e(".datepicker--content",this.$datepicker),this.$nav=e(".datepicker--nav",this.$datepicker)},_triggerOnChange:function(){if(!this.selectedDates.length)return this.opts.onSelect("","",this);var t,e=this.selectedDates,i=Datepicker.getParsedDate(e[0]),s=this,a=new Date(i.year,i.month,i.date);t=e.map(function(t){return s.formatDate(s.loc.dateFormat,t)}).join(this.opts.multipleDatesSeparator),this.opts.multipleDates&&(a=e.map(function(t){var e=Datepicker.getParsedDate(t);return new Date(e.year,e.month,e.date)})),this.opts.onSelect(t,a,this)},next:function(){var t=this.parsedDate,e=this.opts;switch(this.view){case"days":this.date=new Date(t.year,t.month+1,1),e.onChangeMonth&&e.onChangeMonth(this.parsedDate.month,this.parsedDate.year);break;case"months":this.date=new Date(t.year+1,t.month,1),e.onChangeYear&&e.onChangeYear(this.parsedDate.year);break;case"years":this.date=new Date(t.year+10,0,1),e.onChangeDecade&&e.onChangeDecade(this.curDecade)}},prev:function(){var t=this.parsedDate,e=this.opts;switch(this.view){case"days":this.date=new Date(t.year,t.month-1,1),e.onChangeMonth&&e.onChangeMonth(this.parsedDate.month,this.parsedDate.year);break;case"months":this.date=new Date(t.year-1,t.month,1),e.onChangeYear&&e.onChangeYear(this.parsedDate.year);break;case"years":this.date=new Date(t.year-10,0,1),e.onChangeDecade&&e.onChangeDecade(this.curDecade)}},formatDate:function(t,e){e=e||this.date;var i=t,s=this.loc,a=Datepicker.getDecade(e),n=Datepicker.getParsedDate(e);switch(!0){case/dd/.test(i):i=i.replace(/\bdd\b/,n.fullDate);case/d/.test(i):i=i.replace(/\bd\b/,n.date);case/DD/.test(i):i=i.replace(/\bDD\b/,s.days[n.day]);case/D/.test(i):i=i.replace(/\bD\b/,s.daysShort[n.day]);case/mm/.test(i):i=i.replace(/\bmm\b/,n.fullMonth);case/m/.test(i):i=i.replace(/\bm\b/,n.month+1);case/MM/.test(i):i=i.replace(/\bMM\b/,this.loc.months[n.month]);case/M/.test(i):i=i.replace(/\bM\b/,s.monthsShort[n.month]);case/yyyy/.test(i):i=i.replace(/\byyyy\b/,n.year);case/yyyy1/.test(i):i=i.replace(/\byyyy1\b/,a[0]);case/yyyy2/.test(i):i=i.replace(/\byyyy2\b/,a[1]);case/yy/.test(i):i=i.replace(/\byy\b/,n.year.toString().slice(-2))}return i},selectDate:function(t){var e=this.parsedDate,i="";if(t instanceof Date){if("days"==this.view&&t.getMonth()!=e.month&&this.opts.moveToOtherMonthsOnSelect&&(i=new Date(t.getFullYear(),t.getMonth(),1)),"years"==this.view&&t.getFullYear()!=e.year&&this.opts.moveToOtherYearsOnSelect&&(i=new Date(t.getFullYear(),0,1)),i&&(this.silent=!0,this.date=i,this.silent=!1,this.nav._render()),this.opts.multipleDates){if(this.selectedDates.length===this.opts.multipleDates)return;this._isSelected(t)||this.selectedDates.push(t)}else this.selectedDates=[t];this._setInputValue(),this.opts.onSelect&&this._triggerOnChange(),this.opts.autoClose?this.hide():this.views[this.currentView]._render()}},removeDate:function(t){var e=this.selectedDates,i=this;if(t instanceof Date)return e.some(function(s,a){return Datepicker.isSame(s,t)?(e.splice(a,1),i.views[i.currentView]._render(),i._setInputValue(),i.opts.onSelect&&i._triggerOnChange(),!0):void 0})},today:function(){this.silent=!0,this.view=this.opts.minView,this.silent=!1,this.date=new Date},clear:function(){this.selectedDates=[],this.views[this.currentView]._render(),this.opts.onSelect&&this._triggerOnChange()},update:function(t,i){var s=arguments.length;return 2==s?this.opts[t]=i:1==s&&"object"==typeof t&&(this.opts=e.extend(!0,this.opts,t)),this._createShortCuts(),this._syncWithMinMaxDates(),this._defineLocale(this.opts.language),this.nav._addButtonsIfNeed(),this.nav._render(),this.views[this.currentView]._render(),this.elIsInput&&!this.opts.inline&&(this._setPositionClasses(this.opts.position),this.visible&&this.setPosition(this.opts.position)),this.opts.classes&&this.$datepicker.addClass(this.opts.classes),this},_syncWithMinMaxDates:function(){var t=this.date.getTime();this.silent=!0,this.minTime>t&&(this.date=this.minDate),this.maxTime=this.minTime&&i<=this.maxTime,month:h>=this.minTime&&o<=this.maxTime,year:s.year>=a.year&&s.year<=n.year};return e?r[e]:r.day},_getDimensions:function(t){var e=t.offset();return{width:t.outerWidth(),height:t.outerHeight(),left:e.left,top:e.top}},_setPositionClasses:function(t){t=t.split(" ");var e=t[0],i=t[1],s="datepicker -"+e+"-"+i+"- -from-"+e+"-";this.visible&&(s+=" active"),this.$datepicker.removeAttr("class").addClass(s)},setPosition:function(t){t=t||this.opts.position;var e,i,s=this._getDimensions(this.$el),a=this._getDimensions(this.$datepicker),n=t.split(" "),h=this.opts.offset,o=n[0],r=n[1];switch(o){case"top":e=s.top-a.height-h;break;case"right":i=s.left+s.width+h;break;case"bottom":e=s.top+s.height+h;break;case"left":i=s.left-a.width-h}switch(r){case"top":e=s.top;break;case"right":i=s.left+s.width-a.width;break;case"bottom":e=s.top+s.height-a.height;break;case"left":i=s.left;break;case"center":/left|right/.test(o)?e=s.top+s.height/2-a.height/2:i=s.left+s.width/2-a.width/2}this.$datepicker.css({left:i,top:e})},show:function(){this.setPosition(this.opts.position),this.$datepicker.addClass("active"),this.visible=!0},hide:function(){this.$datepicker.removeClass("active").css({left:"-100000px"}),this.focused="",this.keys=[],this.inFocus=!1,this.visible=!1,this.$el.blur()},down:function(t){this._changeView(t,"down")},up:function(t){this._changeView(t,"up")},_changeView:function(t,e){t=t||this.focused||this.date;var i="up"==e?this.viewIndex+1:this.viewIndex-1;i>2&&(i=2),0>i&&(i=0),this.silent=!0,this.date=new Date(t.getFullYear(),t.getMonth(),1),this.silent=!1,this.view=this.viewIndexes[i]},_handleHotKey:function(t){var e,i,s,a=Datepicker.getParsedDate(this._getFocusedDate()),n=this.opts,h=!1,o=!1,r=!1,c=a.year,d=a.month,l=a.date;switch(t){case"ctrlRight":case"ctrlUp":d+=1,h=!0;break;case"ctrlLeft":case"ctrlDown":d-=1,h=!0;break;case"shiftRight":case"shiftUp":o=!0,c+=1;break;case"shiftLeft":case"shiftDown":o=!0,c-=1;break;case"altRight":case"altUp":r=!0,c+=10;break;case"altLeft":case"altDown":r=!0,c-=10;break;case"ctrlShiftUp":this.up()}s=Datepicker.getDaysCount(new Date(c,d)),i=new Date(c,d,l),l>s&&(l=s),i.getTime()this.maxTime&&(i=this.maxDate),this.focused=i,e=Datepicker.getParsedDate(i),h&&n.onChangeMonth&&n.onChangeMonth(e.month,e.year),o&&n.onChangeYear&&n.onChangeYear(e.year),r&&n.onChangeDecade&&n.onChangeDecade(this.curDecade)},_registerKey:function(t){var e=this.keys.some(function(e){return e==t});e||this.keys.push(t)},_unRegisterKey:function(t){var e=this.keys.indexOf(t);this.keys.splice(e,1)},_isHotKeyPressed:function(){var t,e=!1,i=this,s=this.keys.sort();for(var a in d)t=d[a],s.length==t.length&&t.every(function(t,e){return t==s[e]})&&(i._trigger("hotKey",a),e=!0);return e},_trigger:function(t,e){this.$el.trigger(t,e)},_focusNextCell:function(t,e){e=e||this.cellType;var i=Datepicker.getParsedDate(this._getFocusedDate()),s=i.year,a=i.month,n=i.date;if(!this._isHotKeyPressed()){switch(t){case 37:"day"==e?n-=1:"","month"==e?a-=1:"","year"==e?s-=1:"";break;case 38:"day"==e?n-=7:"","month"==e?a-=3:"","year"==e?s-=4:"";break;case 39:"day"==e?n+=1:"","month"==e?a+=1:"","year"==e?s+=1:"";break;case 40:"day"==e?n+=7:"","month"==e?a+=3:"","year"==e?s+=4:""}var h=new Date(s,a,n);h.getTime()this.maxTime&&(h=this.maxDate),this.focused=h}},_getFocusedDate:function(){var t=this.focused||this.selectedDates[this.selectedDates.length-1],e=this.parsedDate;if(!t)switch(this.view){case"days":t=new Date(e.year,e.month,(new Date).getDate());break;case"months":t=new Date(e.year,e.month,1);break;case"years":t=new Date(e.year,0,1)}return t},_getCell:function(t,e){e=e||this.cellType;var i,s=Datepicker.getParsedDate(t),a='.datepicker--cell[data-year="'+s.year+'"]';switch(e){case"month":a='[data-month="'+s.month+'"]';break;case"day":a+='[data-month="'+s.month+'"][data-date="'+s.date+'"]'}return i=this.views[this.currentView].$el.find(a),i.length?i:""},_onShowEvent:function(){this.visible||this.show()},_onBlur:function(){!this.inFocus&&this.visible&&this.hide()},_onMouseDownDatepicker:function(t){this.inFocus=!0},_onMouseUpDatepicker:function(t){this.inFocus=!1,this.$el.focus()},_onInput:function(){var t=this.$el.val();t||this.clear()},_onResize:function(){this.visible&&this.setPosition()},_onKeyDown:function(t){var e=t.which;if(this._registerKey(e),e>=37&&40>=e&&(t.preventDefault(),this._focusNextCell(e)),13==e&&this.focused){if(this._getCell(this.focused).hasClass("-disabled-"))return;if(this.view!=this.opts.minView)this.down();else{var i=this._isSelected(this.focused,this.cellType);i?i&&this.opts.toggleSelected&&this.removeDate(this.focused):this.selectDate(this.focused)}}27==e&&this.hide()},_onKeyUp:function(t){var e=t.which;this._unRegisterKey(e)},_onHotKey:function(t,e){this._handleHotKey(e)},set focused(t){if(!t&&this.focused){var e=this._getCell(this.focused);e.length&&e.removeClass("-focus-")}this._focused=t,this.date=t},get focused(){return this._focused},get parsedDate(){return Datepicker.getParsedDate(this.date)},set date(t){return t instanceof Date?(this.currentDate=t,this.inited&&!this.silent&&(this.views[this.view]._render(),this.nav._render(),this.visible&&this.elIsInput&&this.setPosition()),t):void 0},get date(){return this.currentDate},set view(t){return this.viewIndex=this.viewIndexes.indexOf(t),this.viewIndex<0?void 0:(this.prevView=this.currentView,this.currentView=t,this.inited&&(this.views[t]?this.views[t]._render():this.views[t]=new Datepicker.Body(this,t,this.opts),this.views[this.prevView].hide(),this.views[t].show(),this.nav._render(),this.opts.onChangeView&&this.opts.onChangeView(t),this.elIsInput&&this.visible&&this.setPosition()),t)},get view(){return this.currentView},get cellType(){return this.view.substring(0,this.view.length-1)},get minTime(){var t=Datepicker.getParsedDate(this.minDate);return new Date(t.year,t.month,t.date).getTime()},get maxTime(){var t=Datepicker.getParsedDate(this.maxDate);return new Date(t.year,t.month,t.date).getTime()},get curDecade(){return Datepicker.getDecade(this.date)}},Datepicker.getDaysCount=function(t){return new Date(t.getFullYear(),t.getMonth()+1,0).getDate()},Datepicker.getParsedDate=function(t){return{year:t.getFullYear(),month:t.getMonth(),fullMonth:t.getMonth()+1<10?"0"+(t.getMonth()+1):t.getMonth()+1,date:t.getDate(),fullDate:t.getDate()<10?"0"+t.getDate():t.getDate(),day:t.getDay()}},Datepicker.getDecade=function(t){var e=10*Math.floor(t.getFullYear()/10);return[e,e+9]},Datepicker.template=function(t,e){return t.replace(/#\{([\w]+)\}/g,function(t,i){return e[i]||0===e[i]?e[i]:void 0})},Datepicker.isSame=function(t,e,i){var s=Datepicker.getParsedDate(t),a=Datepicker.getParsedDate(e),n=i?i:"day",h={day:s.date==a.date&&s.month==a.month&&s.year==a.year,month:s.month==a.month&&s.year==a.year,year:s.year==a.year};return h[n]},Datepicker.language={ru:{days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вос","Пон","Вто","Сре","Чет","Пят","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",dateFormat:"dd.mm.yyyy",firstDay:1}},e.fn[n]=function(t){return Datepicker.prototype[t]?void Datepicker.prototype[t].apply(this.data(n),Array.prototype.slice.call(arguments,1)):this.each(function(){if(e.data(this,n)){var i=e.data(this,n);i.opts=e.extend(!0,i.opts,t),i.update()}else e.data(this,n,new Datepicker(this,t))})},e(function(){e(h).datepicker()})}(window,jQuery),function(){var t={days:'
',months:'
',years:'
'},e=Datepicker;e.Body=function(t,e,i){this.d=t,this.type=e,this.opts=i,this.init()},e.Body.prototype={init:function(){this._buildBaseHtml(),this._render(),this._bindEvents()},_bindEvents:function(){this.$el.on("click",".datepicker--cell",$.proxy(this._onClickCell,this))},_buildBaseHtml:function(){this.$el=$(t[this.type]).appendTo(this.d.$content),this.$names=$(".datepicker--days-names",this.$el),this.$cells=$(".datepicker--cells",this.$el)},_getDayNamesHtml:function(t,e,i,s){return e=void 0!=e?e:t,i=i?i:"",s=void 0!=s?s:0,s>7?i:7==e?this._getDayNamesHtml(t,0,i,++s):(i+='
'+this.d.loc.daysMin[e]+"
",this._getDayNamesHtml(t,++e,i,++s))},_getDaysHtml:function(t){var i=e.getDaysCount(t),s=new Date(t.getFullYear(),t.getMonth(),1).getDay(),a=new Date(t.getFullYear(),t.getMonth(),i).getDay(),n=s-this.d.loc.firstDay,h=6-a+this.d.loc.firstDay;n=0>n?n+7:n,h=h>6?h-7:h;for(var o,r,c=-n+1,d="",l=c,p=i+h;p>=l;l++)r=t.getFullYear(),o=t.getMonth(),d+=this._getDayHtml(new Date(r,o,l));return d},_getDayHtml:function(t){var i="datepicker--cell datepicker--cell-day",s=new Date,a=e.getParsedDate(t),n={},h=a.date;return this.opts.onRenderCell&&(n=this.opts.onRenderCell(t,"day")||{},h=n.html?n.html:h,i+=n.classes?" "+n.classes:""),this.d.isWeekend(a.day)&&(i+=" -weekend-"),e.isSame(s,t)&&(i+=" -current-"),this.d.focused&&e.isSame(t,this.d.focused)&&(i+=" -focus-"),this.d._isSelected(t,"day")&&(i+=" -selected-"),(!this.d._isInRange(t)||n.disabled)&&(i+=" -disabled-"),a.month!=this.d.parsedDate.month&&(i+=" -other-month-",this.opts.selectOtherMonths||(i+=" -disabled-"),this.opts.showOtherMonths||(h="")),'
'+h+"
"},_getMonthsHtml:function(t){for(var i="",s=e.getParsedDate(t),a=0;12>a;)i+=this._getMonthHtml(new Date(s.year,a)),a++;return i},_getMonthHtml:function(t){var i="datepicker--cell datepicker--cell-month",s=e.getParsedDate(t),a=new Date,n=this.d.loc,h=n[this.opts.monthsFiled][s.month],o={};return this.opts.onRenderCell&&(o=this.opts.onRenderCell(t,"month")||{},h=o.html?o.html:h,i+=o.classes?" "+o.classes:""),e.isSame(a,t,"month")&&(i+=" -current-"),this.d._isSelected(t,"month")&&(i+=" -selected-"),this.d.focused&&e.isSame(t,this.d.focused,"month")&&(i+=" -focus-"),(!this.d._isInRange(t,"month")||o.disabled)&&(i+=" -disabled-"),'
'+h+"
"},_getYearsHtml:function(t){var i=(e.getParsedDate(t),e.getDecade(t)),s=i[0]-1,a="",n=s;for(n;n<=i[1]+1;n++)a+=this._getYearHtml(new Date(n,0));return a},_getYearHtml:function(t){var i="datepicker--cell datepicker--cell-year",s=e.getDecade(this.d.date),a=new Date,n=e.getParsedDate(t),h=n.year,o={};return this.opts.onRenderCell&&(o=this.opts.onRenderCell(t,"year")||{},h=o.html?o.html:h,i+=o.classes?" "+o.classes:""),(n.years[1])&&(i+=" -other-decade-",this.opts.selectOtherYears||(i+=" -disabled-"),this.opts.showOtherYears||(h="")),e.isSame(a,t,"year")&&(i+=" -current-"),this.d._isSelected(t,"year")&&(i+=" -selected-"),this.d.focused&&e.isSame(t,this.d.focused,"year")&&(i+=" -focus-"),(!this.d._isInRange(t,"year")||o.disabled)&&(i+=" -disabled-"),'
'+h+"
"},_renderTypes:{days:function(){var t=this._getDayNamesHtml(this.d.loc.firstDay),e=this._getDaysHtml(this.d.currentDate);this.$cells.html(e),this.$names.html(t)},months:function(){var t=this._getMonthsHtml(this.d.currentDate);this.$cells.html(t)},years:function(){var t=this._getYearsHtml(this.d.currentDate);this.$cells.html(t)}},_render:function(){this._renderTypes[this.type].bind(this)()},show:function(){this.$el.addClass("active"),this.acitve=!0},hide:function(){this.$el.removeClass("active"),this.active=!1},_handleClick:function(t){var e=t.data("date")||1,i=t.data("month")||0,s=t.data("year")||this.d.parsedDate.year;if(this.d.view!=this.opts.minView)return void this.d.down(new Date(s,i,e));var a=new Date(s,i,e),n=this.d._isSelected(a,this.d.cellType);n?n&&this.opts.toggleSelected&&this.d.removeDate(a):this.d.selectDate(a)},_onClickCell:function(t){var e=$(t.target).closest(".datepicker--cell");e.hasClass("-disabled-")||this._handleClick.bind(this)(e)}}}(),function(){var t='
#{prevHtml}
#{title}
#{nextHtml}
',e='
',i='#{label}';Datepicker.Navigation=function(t,e){this.d=t,this.opts=e,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._onClickNavButton,this)),this.d.$nav.on("click",".datepicker--nav-title",$.proxy(this._onClickNavTitle,this)),this.d.$datepicker.on("click",".datepicker--button",$.proxy(this._onClickNavButton,this))},_buildBaseHtml:function(){this._render(),this._addButtonsIfNeed()},_addButtonsIfNeed:function(){this.opts.todayButton&&this._addButton("today"),this.opts.clearButton&&this._addButton("clear")},_render:function(){var e=this._getTitle(this.d.currentDate),i=Datepicker.template(t,$.extend({title:e},this.opts));this.d.$nav.html(i),"years"==this.d.view&&$(".datepicker--nav-title",this.d.$nav).addClass("-disabled-"),this.setNavStatus()},_getTitle:function(t){return this.d.formatDate(this.opts.navTitles[this.d.view],t)},_addButton:function(t){this.$buttonsContainer.length||this._addButtonsContainer();var e={action:t,label:this.d.loc[t]},s=Datepicker.template(i,e);this.$buttonsContainer.append(s)},_addButtonsContainer:function(){this.d.$datepicker.append(e),this.$buttonsContainer=$(".datepicker--buttons",this.d.$datepicker)},setNavStatus:function(){if((this.opts.minDate||this.opts.maxDate)&&this.opts.disableNavWhenOutOfRange){var t=this.d.parsedDate,e=t.month,i=t.year,s=t.date;switch(this.d.view){case"days":this.d._isInRange(new Date(i,e-1,s),"month")||this._disableNav("prev"),this.d._isInRange(new Date(i,e+1,s),"month")||this._disableNav("next");break;case"months":this.d._isInRange(new Date(i-1,e,s),"year")||this._disableNav("prev"),this.d._isInRange(new Date(i+1,e,s),"year")||this._disableNav("next");break;case"years":this.d._isInRange(new Date(i-10,e,s),"year")||this._disableNav("prev"),this.d._isInRange(new Date(i+10,e,s),"year")||this._disableNav("next")}}},_disableNav:function(t){$('[data-action="'+t+'"]',this.d.$nav).addClass("-disabled-")},_activateNav:function(t){$('[data-action="'+t+'"]',this.d.$nav).removeClass("-disabled-")},_onClickNavButton:function(t){var e=$(t.target).closest("[data-action]"),i=e.data("action");this.d[i]()},_onClickNavTitle:function(t){return $(t.target).hasClass("-disabled-")?void 0:"days"==this.d.view?this.d.view="months":void(this.d.view="years")}}}(); \ No newline at end of file diff --git a/docs/jade/pages/index-ru.jade b/docs/jade/pages/index-ru.jade index a19d8dd..e1ddbd0 100644 --- a/docs/jade/pages/index-ru.jade +++ b/docs/jade/pages/index-ru.jade @@ -71,27 +71,6 @@ block content :code - script. - $(function () { - $('#test').datepicker({ - onRenderCell: function (d, type) { - if (type == 'day' && d.getDate() == 4) { - return { - disabled: true - } - } - }, - classes: 'hello', - onChangeYear: function () { - console.log(arguments); - }, - onChangeMonth: function (m, y) { - console.log(arguments); - } - }) - - }) - h3 Выбор нескольких дат p | Передайте параметр diff --git a/src/js/body.js b/src/js/body.js index 26d3689..9685cf0 100644 --- a/src/js/body.js +++ b/src/js/body.js @@ -13,9 +13,10 @@ '
' + '
' + '
' - }; + }, + D = Datepicker; - Datepicker.Body = function (d, type, opts) { + D.Body = function (d, type, opts) { this.d = d; this.type = type; this.opts = opts; @@ -23,7 +24,7 @@ this.init(); }; - Datepicker.Body.prototype = { + D.Body.prototype = { init: function () { this._buildBaseHtml(); this._render(); @@ -61,7 +62,7 @@ * @private */ _getDaysHtml: function (date) { - var totalMonthDays = Datepicker.getDaysCount(date), + var totalMonthDays = D.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, @@ -87,7 +88,7 @@ _getDayHtml: function (date) { var _class = "datepicker--cell datepicker--cell-day", currentDate = new Date(), - d = Datepicker.getParsedDate(date), + d = D.getParsedDate(date), render = {}, html = d.date; @@ -98,8 +99,8 @@ } if (this.d.isWeekend(d.day)) _class += " -weekend-"; - if (Datepicker.isSame(currentDate, date)) _class += ' -current-'; - if (this.d.focused && Datepicker.isSame(date, this.d.focused)) _class += ' -focus-'; + if (D.isSame(currentDate, date)) _class += ' -current-'; + if (this.d.focused && D.isSame(date, this.d.focused)) _class += ' -focus-'; if (this.d._isSelected(date, 'day')) _class += ' -selected-'; if (!this.d._isInRange(date) || render.disabled) _class += ' -disabled-'; if (d.month != this.d.parsedDate.month) { @@ -126,7 +127,7 @@ */ _getMonthsHtml: function (date) { var html = '', - d = Datepicker.getParsedDate(date), + d = D.getParsedDate(date), i = 0; while(i < 12) { @@ -139,7 +140,7 @@ _getMonthHtml: function (date) { var _class = "datepicker--cell datepicker--cell-month", - d = Datepicker.getParsedDate(date), + d = D.getParsedDate(date), currentDate = new Date(), loc = this.d.loc, html = loc[this.opts.monthsFiled][d.month], @@ -151,17 +152,17 @@ _class += render.classes ? ' ' + render.classes : ''; } - if (Datepicker.isSame(currentDate, date, 'month')) _class += ' -current-'; + if (D.isSame(currentDate, date, 'month')) _class += ' -current-'; if (this.d._isSelected(date, 'month')) _class += ' -selected-'; - if (this.d.focused && Datepicker.isSame(date, this.d.focused, 'month')) _class += ' -focus-'; + if (this.d.focused && D.isSame(date, this.d.focused, 'month')) _class += ' -focus-'; if (!this.d._isInRange(date, 'month') || render.disabled) _class += ' -disabled-'; return '
' + html + '
' }, _getYearsHtml: function (date) { - var d = Datepicker.getParsedDate(date), - decade = Datepicker.getDecade(date), + var d = D.getParsedDate(date), + decade = D.getDecade(date), firstYear = decade[0] - 1, html = '', i = firstYear; @@ -175,9 +176,9 @@ _getYearHtml: function (date) { var _class = "datepicker--cell datepicker--cell-year", - decade = Datepicker.getDecade(this.d.date), + decade = D.getDecade(this.d.date), currentDate = new Date(), - d = Datepicker.getParsedDate(date), + d = D.getParsedDate(date), html = d.year, render = {}; @@ -197,9 +198,9 @@ if (!this.opts.showOtherYears) html = ''; } - if (Datepicker.isSame(currentDate, date, 'year')) _class += ' -current-'; + if (D.isSame(currentDate, date, 'year')) _class += ' -current-'; if (this.d._isSelected(date, 'year')) _class += ' -selected-'; - if (this.d.focused && Datepicker.isSame(date, this.d.focused, 'year')) _class += ' -focus-'; + if (this.d.focused && D.isSame(date, this.d.focused, 'year')) _class += ' -focus-'; if (!this.d._isInRange(date, 'year') || render.disabled) _class += ' -disabled-'; return '
' + html + '
' diff --git a/src/js/datepicker.js b/src/js/datepicker.js index 46a0bc5..516ffaf 100644 --- a/src/js/datepicker.js +++ b/src/js/datepicker.js @@ -57,6 +57,7 @@ var Datepicker; months: 'yyyy', years: 'yyyy1 - yyyy2' }, + keyboardNav: true, // events onSelect: '', @@ -75,6 +76,10 @@ var Datepicker; 'shiftUp': [16, 38], 'shiftLeft': [16, 37], 'shiftDown': [16, 40], + 'altUp': [18, 38], + 'altRight': [18, 39], + 'altLeft': [18, 37], + 'altDown': [18, 40], 'ctrlShiftUp': [16, 17, 38] }; @@ -155,9 +160,11 @@ var Datepicker; this.$datepicker.on('mouseup', this._onMouseUpDatepicker.bind(this)); $(window).on('resize', this._onResize.bind(this)); - this.$el.on('keydown', this._onKeyDown.bind(this)); - this.$el.on('keyup', this._onKeyUp.bind(this)); - this.$el.on('hotKey', this._onHotKey.bind(this)); + if (this.opts.keyboardNav) { + this.$el.on('keydown', this._onKeyDown.bind(this)); + this.$el.on('keyup', this._onKeyUp.bind(this)); + this.$el.on('hotKey', this._onHotKey.bind(this)); + } }, isWeekend: function (day) { @@ -572,109 +579,45 @@ var Datepicker; left: '-100000px' }); + this.focused = ''; + this.keys = []; + this.inFocus = false; this.visible = false; this.$el.blur(); }, down: function (date) { - date = date || this.focused || this.date; - - var nextViewIndex = this.viewIndex - 1; - if (nextViewIndex < 0) nextViewIndex = 0; - this.silent = true; - this.date = new Date(date.getFullYear(), date.getMonth(), 1); - this.silent = false; - this.view = this.viewIndexes[nextViewIndex]; + this._changeView(date, 'down'); }, up: function (date) { + this._changeView(date, 'up'); + }, + + _changeView: function (date, dir) { date = date || this.focused || this.date; - var nextViewIndex = this.viewIndex + 1; - if (nextViewIndex > 2) nextViewIndex = 2; + var nextView = dir == 'up' ? this.viewIndex + 1 : this.viewIndex - 1; + if (nextView > 2) nextView = 2; + if (nextView < 0) nextView = 0; + this.silent = true; this.date = new Date(date.getFullYear(), date.getMonth(), 1); this.silent = false; - this.view = this.viewIndexes[nextViewIndex]; - }, + this.view = this.viewIndexes[nextView]; - _onShowEvent: function () { - 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; - this.$el.focus() - }, - - _onInput: function () { - var val = this.$el.val(); - - if (!val) { - this.clear(); - } - }, - - _onResize: function () { - if (this.visible) { - this.setPosition(); - } - }, -//TODO добавить esc - _onKeyDown: function (e) { - var code = e.which; - - this._registerKey(code); - - if (code >= 37 && code <= 40) { - e.preventDefault(); - this._focusNextCell(code); - } - - if (code == 13) { - if (this.focused) { - if (this._getCell(this.focused).hasClass('-disabled-')) return; - if (this.view != this.opts.minView) { - this.down() - } else { - var alreadySelected = this._isSelected(this.focused, this.cellType); - - if (!alreadySelected) { - this.selectDate(this.focused); - } else if (alreadySelected && this.opts.toggleSelected){ - this.removeDate(this.focused); - } - } - } - } - }, - - _onKeyUp: function (e) { - var code = e.which; - this._unRegisterKey(code); - }, - - _onHotKey: function (e, hotKey) { - this._handleHotKey(hotKey); }, _handleHotKey: function (key) { var date = Datepicker.getParsedDate(this._getFocusedDate()), - nd, + focusedParsed, + o = this.opts, + newDate, totalDaysInNextMonth, + monthChanged = false, + yearChanged = false, + decadeChanged = false, y = date.year, m = date.month, d = date.date; @@ -683,36 +626,63 @@ var Datepicker; case 'ctrlRight': case 'ctrlUp': m += 1; + monthChanged = true; break; case 'ctrlLeft': case 'ctrlDown': m -= 1; + monthChanged = true; break; case 'shiftRight': case 'shiftUp': + yearChanged = true; y += 1; break; case 'shiftLeft': case 'shiftDown': + yearChanged = true; y -= 1; break; + case 'altRight': + case 'altUp': + decadeChanged = true; + y += 10; + break; + case 'altLeft': + case 'altDown': + decadeChanged = true; + y -= 10; + break; case 'ctrlShiftUp': this.up(); break; } totalDaysInNextMonth = Datepicker.getDaysCount(new Date(y,m)); + newDate = new Date(y,m,d); - nd = new Date(y,m,d); + // If next month has less days than current, set date to total days in that month if (totalDaysInNextMonth < d) d = totalDaysInNextMonth; - if (nd.getTime() < this.minTime) { - nd = this.minDate; - } else if (nd.getTime() > this.maxTime) { - nd = this.maxDate; + // 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 = nd; + this.focused = newDate; + + focusedParsed = Datepicker.getParsedDate(newDate); + if (monthChanged && o.onChangeMonth) { + o.onChangeMonth(focusedParsed.month, focusedParsed.year) + } + if (yearChanged && o.onChangeYear) { + o.onChangeYear(focusedParsed.year) + } + if (decadeChanged && o.onChangeDecade) { + o.onChangeDecade(this.curDecade) + } }, _registerKey: function (key) { @@ -841,7 +811,95 @@ var Datepicker; return $cell.length ? $cell : ''; }, + _onShowEvent: function () { + 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; + this.$el.focus() + }, + + _onInput: function () { + var val = this.$el.val(); + + if (!val) { + this.clear(); + } + }, + + _onResize: function () { + if (this.visible) { + this.setPosition(); + } + }, + + _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.focused, this.cellType); + + if (!alreadySelected) { + this.selectDate(this.focused); + } else if (alreadySelected && this.opts.toggleSelected){ + this.removeDate(this.focused); + } + } + } + } + + // Esc + if (code == 27) { + this.hide(); + } + }, + + _onKeyUp: function (e) { + var code = e.which; + this._unRegisterKey(code); + }, + + _onHotKey: function (e, hotKey) { + this._handleHotKey(hotKey); + }, + + + set focused(val) { + if (!val && this.focused) { + var $cell = this._getCell(this.focused); + + if ($cell.length) { + $cell.removeClass('-focus-') + } + } this._focused = val; this.date = val; }, diff --git a/src/sass/_datepicker-config.scss b/src/sass/_datepicker-config.scss index fddda26..366d6a5 100644 --- a/src/sass/_datepicker-config.scss +++ b/src/sass/_datepicker-config.scss @@ -22,6 +22,7 @@ $textColor: ( $bg: ( selected: #5cc4ef, + selectedHover: darken(#5cc4ef, 5), hover: #f0f0f0 ); diff --git a/src/sass/cell.scss b/src/sass/cell.scss index 6215551..786ee67 100644 --- a/src/sass/cell.scss +++ b/src/sass/cell.scss @@ -61,6 +61,10 @@ color: #fff; background: map_get($bg, selected); } + + &.-focus- { + background: map_get($bg, selectedHover); + } } }