diff --git a/dist/css/datepicker.css b/dist/css/datepicker.css index 7a7f51b..788c05f 100644 --- a/dist/css/datepicker.css +++ b/dist/css/datepicker.css @@ -1,3 +1,13 @@ +.datepicker--cell-day.-other-month-, .datepicker--cell-year.-other-decade- { + color: #ddd; + font-size: .9em; } + .-selected-.datepicker--cell-day.-other-month-, .-selected-.datepicker--cell-year.-other-decade- { + color: #fff; + background: #def2fa; } + .datepicker--cell-day.-other-month-:empty, .datepicker--cell-year.-other-decade-:empty { + background: none; + border: none; } + /* ------------------------------------------------- Datepicker ------------------------------------------------- */ @@ -24,6 +34,16 @@ height: 32px; text-align: center; } +.datepicker--cell-day.-other-month-, .datepicker--cell-year.-other-decade- { + color: #ddd; + font-size: .9em; } + .-selected-.datepicker--cell-day.-other-month-, .-selected-.datepicker--cell-year.-other-decade- { + color: #fff; + background: #def2fa; } + .datepicker--cell-day.-other-month-:empty, .datepicker--cell-year.-other-decade-:empty { + background: none; + border: none; } + /* ------------------------------------------------- Navigation ------------------------------------------------- */ @@ -57,6 +77,16 @@ cursor: default; background: none; } +.datepicker--cell-day.-other-month-, .datepicker--cell-year.-other-decade- { + color: #ddd; + font-size: .9em; } + .-selected-.datepicker--cell-day.-other-month-, .-selected-.datepicker--cell-year.-other-decade- { + color: #fff; + background: #def2fa; } + .datepicker--cell-day.-other-month-:empty, .datepicker--cell-year.-other-decade-:empty { + background: none; + border: none; } + /* ------------------------------------------------- Datepicker cells ------------------------------------------------- */ @@ -94,14 +124,6 @@ .datepicker--cell-day { border-radius: 50%; } - .datepicker--cell-day.-other-month- { - color: #ddd; } - .datepicker--cell-day.-other-month-.-selected- { - color: #fff; - background: #def2fa; } - .datepicker--cell-day.-other-month-.-selected-.-disabled- { - background: none; - border: none; } .datepicker--cell-month { width: 33.33%; @@ -110,5 +132,3 @@ .datepicker--cell-year { width: 25%; height: 40px; } - .datepicker--cell-year.-other-decade- { - color: #ddd; } diff --git a/dist/js/datepicker.js b/dist/js/datepicker.js index 9ab386b..ece52d4 100644 --- a/dist/js/datepicker.js +++ b/dist/js/datepicker.js @@ -12,20 +12,23 @@ var Datepicker; //TODO сделать работу с инпутом inline: true, region: 'ru', - firstDay: 1, // Week's first day start: '', // Start date + firstDay: 1, // Week's first day weekends: [6, 0], - defaultView: 'days', - //TODO сделать минимальный вид - minView: 'days', dateFormat: 'dd.mm.yyyy', toggleSelected: true, - //TODO сделать тоже самое с годами + defaultView: 'years', + minView: 'years', + showOtherMonths: true, selectOtherMonths: true, moveToOtherMonthsOnSelect: true, + showOtherYears: true, + selectOtherYears: true, + moveToOtherYearsOnSelect: true, + minDate: '', maxDate: '', disableNavWhenOutOfRange: true, @@ -77,13 +80,15 @@ var Datepicker; Datepicker.prototype = { containerBuilt: false, + viewIndexes: ['days', 'months', 'years'], + init: function () { this._buildBaseHtml(); this.nav = new Datepicker.Navigation(this, this.opts); this.views[this.currentView] = new Datepicker.Body(this, this.currentView, this.opts); - this.views[this.currentView].show(); + this.view = this.currentView; this.inited = true; }, @@ -193,11 +198,25 @@ var Datepicker; }, selectDate: function (date) { - var d = this.parsedDate; + var d = this.parsedDate, + newDate = ''; - if (date.getMonth() != d.month && this.opts.moveToOtherMonthsOnSelect) { + if (this.view == 'days') { + if (date.getMonth() != d.month && this.opts.moveToOtherMonthsOnSelect) { + newDate = new Date(date.getFullYear(), date.getMonth(), 1); + + } + } + + if (this.view == 'years') { + if (date.getFullYear() != d.year && this.opts.moveToOtherYearsOnSelect) { + newDate = new Date(date.getFullYear(), 0, 1); + } + } + + if (newDate) { this.silent = true; - this.date = new Date(date.getFullYear(),date.getMonth(), 1); + this.date = newDate; this.silent = false; this.nav._render() } @@ -276,6 +295,7 @@ var Datepicker; set view (val) { this.prevView = this.currentView; this.currentView = val; + this.viewIndex = this.viewIndexes.indexOf(val); if (this.inited) { if (!this.views[val]) { @@ -297,7 +317,6 @@ var Datepicker; }, get minTime() { - // Reset hours to 00:00, in case of new Date() is passed as option to minDate var min = Datepicker.getParsedDate(this.minDate); return new Date(min.year, min.month, min.date).getTime() }, @@ -308,6 +327,9 @@ var Datepicker; } }; + // Utils + // ------------------------------------------------- + Datepicker.getDaysCount = function (date) { return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(); }; @@ -606,7 +628,7 @@ Datepicker.Cell = function () { if (d.month != this.d.parsedDate.month) { _class += " -other-month-"; - if (!this.opts.selectOtherMonths || !this.opts.showOtherMonths) { + if (!this.opts.selectOtherMonths) { _class += " -disabled-"; } @@ -653,6 +675,7 @@ Datepicker.Cell = function () { } if (Datepicker.isSame(currentDate, date, 'month')) _class += ' -current-'; + if (this.d._isSelected(date, 'month')) _class += ' -selected-'; if (!this.d._isInRange(date, 'month') || render.disabled) _class += ' -disabled-'; return '
' + html + '
' @@ -688,9 +711,16 @@ Datepicker.Cell = function () { if (d.year < decade[0] || d.year > decade[1]) { _class += ' -other-decade-'; + + if (!this.opts.selectOtherYears) { + _class += " -disabled-"; + } + + if (!this.opts.showOtherYears) html = ''; } if (Datepicker.isSame(currentDate, date, 'year')) _class += ' -current-'; + if (this.d._isSelected(date, 'year')) _class += ' -selected-'; if (!this.d._isInRange(date, 'year') || render.disabled) _class += ' -disabled-'; return '
' + html + '
' @@ -733,43 +763,38 @@ Datepicker.Cell = function () { // Events // ------------------------------------------------- - _handleClick: { - days: function (el) { - var date = el.data('date'), - month = el.data('month'), - year = el.data('year'), - selectedDate = new Date(year, month, date), - alreadySelected = this.d._isSelected(selectedDate, 'day'), - triggerOnChange = true; + _handleClick: function (el) { + var date = el.data('date') || 1, + month = el.data('month') || 0, + year = el.data('year') || this.d.parsedDate.year; - if (!alreadySelected) { - this.d.selectDate(selectedDate); - } else if (alreadySelected && this.opts.toggleSelected){ - this.d.removeDate(selectedDate); - } else if (alreadySelected && !this.opts.toggleSelected) { - triggerOnChange = false; - } - - if (triggerOnChange) { - this.d._triggerOnChange() - } - }, - months: function (el) { - var month = el.data('month'), - d = this.d.parsedDate; + // Change view if min view does not reach yet + if (this.d.view != this.opts.minView) { + var nextViewIndex = this.d.viewIndex - 1; this.d.silent = true; - this.d.date = new Date(d.year, month, 1); + this.d.date = new Date(year, month, date); this.d.silent = false; - this.d.view = 'days'; - }, - years: function (el) { - var year = el.data('year'); + this.d.view = this.d.viewIndexes[nextViewIndex]; - this.d.silent = true; - this.d.date = new Date(year, 0, 1); - this.d.silent = false; - this.d.view = 'months'; + return; + } + + // Select date if min view is reached + var selectedDate = new Date(year, month, date), + alreadySelected = this.d._isSelected(selectedDate, this.d.view.substring(0, this.d.view.length - 1)), + triggerOnChange = true; + + if (!alreadySelected) { + this.d.selectDate(selectedDate); + } else if (alreadySelected && this.opts.toggleSelected){ + this.d.removeDate(selectedDate); + } else if (alreadySelected && !this.opts.toggleSelected) { + triggerOnChange = false; + } + + if (triggerOnChange) { + this.d._triggerOnChange() } }, @@ -778,7 +803,7 @@ Datepicker.Cell = function () { if ($el.hasClass('-disabled-')) return; - this._handleClick[this.d.currentView].bind(this)($el); + this._handleClick.bind(this)($el); } }; })(); diff --git a/js/datepicker/body.js b/js/datepicker/body.js index bc003c4..3b139a8 100644 --- a/js/datepicker/body.js +++ b/js/datepicker/body.js @@ -104,7 +104,7 @@ if (d.month != this.d.parsedDate.month) { _class += " -other-month-"; - if (!this.opts.selectOtherMonths || !this.opts.showOtherMonths) { + if (!this.opts.selectOtherMonths) { _class += " -disabled-"; } @@ -151,6 +151,7 @@ } if (Datepicker.isSame(currentDate, date, 'month')) _class += ' -current-'; + if (this.d._isSelected(date, 'month')) _class += ' -selected-'; if (!this.d._isInRange(date, 'month') || render.disabled) _class += ' -disabled-'; return '
' + html + '
' @@ -186,9 +187,16 @@ if (d.year < decade[0] || d.year > decade[1]) { _class += ' -other-decade-'; + + if (!this.opts.selectOtherYears) { + _class += " -disabled-"; + } + + if (!this.opts.showOtherYears) html = ''; } if (Datepicker.isSame(currentDate, date, 'year')) _class += ' -current-'; + if (this.d._isSelected(date, 'year')) _class += ' -selected-'; if (!this.d._isInRange(date, 'year') || render.disabled) _class += ' -disabled-'; return '
' + html + '
' @@ -231,43 +239,38 @@ // Events // ------------------------------------------------- - _handleClick: { - days: function (el) { - var date = el.data('date'), - month = el.data('month'), - year = el.data('year'), - selectedDate = new Date(year, month, date), - alreadySelected = this.d._isSelected(selectedDate, 'day'), - triggerOnChange = true; + _handleClick: function (el) { + var date = el.data('date') || 1, + month = el.data('month') || 0, + year = el.data('year') || this.d.parsedDate.year; - if (!alreadySelected) { - this.d.selectDate(selectedDate); - } else if (alreadySelected && this.opts.toggleSelected){ - this.d.removeDate(selectedDate); - } else if (alreadySelected && !this.opts.toggleSelected) { - triggerOnChange = false; - } - - if (triggerOnChange) { - this.d._triggerOnChange() - } - }, - months: function (el) { - var month = el.data('month'), - d = this.d.parsedDate; + // Change view if min view does not reach yet + if (this.d.view != this.opts.minView) { + var nextViewIndex = this.d.viewIndex - 1; this.d.silent = true; - this.d.date = new Date(d.year, month, 1); + this.d.date = new Date(year, month, date); this.d.silent = false; - this.d.view = 'days'; - }, - years: function (el) { - var year = el.data('year'); + this.d.view = this.d.viewIndexes[nextViewIndex]; - this.d.silent = true; - this.d.date = new Date(year, 0, 1); - this.d.silent = false; - this.d.view = 'months'; + return; + } + + // Select date if min view is reached + var selectedDate = new Date(year, month, date), + alreadySelected = this.d._isSelected(selectedDate, this.d.view.substring(0, this.d.view.length - 1)), + triggerOnChange = true; + + if (!alreadySelected) { + this.d.selectDate(selectedDate); + } else if (alreadySelected && this.opts.toggleSelected){ + this.d.removeDate(selectedDate); + } else if (alreadySelected && !this.opts.toggleSelected) { + triggerOnChange = false; + } + + if (triggerOnChange) { + this.d._triggerOnChange() } }, @@ -276,7 +279,7 @@ if ($el.hasClass('-disabled-')) return; - this._handleClick[this.d.currentView].bind(this)($el); + this._handleClick.bind(this)($el); } }; })(); diff --git a/js/datepicker/datepicker.js b/js/datepicker/datepicker.js index a82d65a..435ba35 100644 --- a/js/datepicker/datepicker.js +++ b/js/datepicker/datepicker.js @@ -12,20 +12,23 @@ var Datepicker; //TODO сделать работу с инпутом inline: true, region: 'ru', - firstDay: 1, // Week's first day start: '', // Start date + firstDay: 1, // Week's first day weekends: [6, 0], - defaultView: 'days', - //TODO сделать минимальный вид - minView: 'days', dateFormat: 'dd.mm.yyyy', toggleSelected: true, - //TODO сделать тоже самое с годами + defaultView: 'years', + minView: 'years', + showOtherMonths: true, selectOtherMonths: true, moveToOtherMonthsOnSelect: true, + showOtherYears: true, + selectOtherYears: true, + moveToOtherYearsOnSelect: true, + minDate: '', maxDate: '', disableNavWhenOutOfRange: true, @@ -77,13 +80,15 @@ var Datepicker; Datepicker.prototype = { containerBuilt: false, + viewIndexes: ['days', 'months', 'years'], + init: function () { this._buildBaseHtml(); this.nav = new Datepicker.Navigation(this, this.opts); this.views[this.currentView] = new Datepicker.Body(this, this.currentView, this.opts); - this.views[this.currentView].show(); + this.view = this.currentView; this.inited = true; }, @@ -193,11 +198,25 @@ var Datepicker; }, selectDate: function (date) { - var d = this.parsedDate; + var d = this.parsedDate, + newDate = ''; - if (date.getMonth() != d.month && this.opts.moveToOtherMonthsOnSelect) { + if (this.view == 'days') { + if (date.getMonth() != d.month && this.opts.moveToOtherMonthsOnSelect) { + newDate = new Date(date.getFullYear(), date.getMonth(), 1); + + } + } + + if (this.view == 'years') { + if (date.getFullYear() != d.year && this.opts.moveToOtherYearsOnSelect) { + newDate = new Date(date.getFullYear(), 0, 1); + } + } + + if (newDate) { this.silent = true; - this.date = new Date(date.getFullYear(),date.getMonth(), 1); + this.date = newDate; this.silent = false; this.nav._render() } @@ -276,6 +295,7 @@ var Datepicker; set view (val) { this.prevView = this.currentView; this.currentView = val; + this.viewIndex = this.viewIndexes.indexOf(val); if (this.inited) { if (!this.views[val]) { @@ -297,7 +317,6 @@ var Datepicker; }, get minTime() { - // Reset hours to 00:00, in case of new Date() is passed as option to minDate var min = Datepicker.getParsedDate(this.minDate); return new Date(min.year, min.month, min.date).getTime() }, @@ -308,6 +327,9 @@ var Datepicker; } }; + // Utils + // ------------------------------------------------- + Datepicker.getDaysCount = function (date) { return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(); }; diff --git a/sass/datepicker/_cell.scss b/sass/datepicker/_cell.scss index 4eeb6af..a8d7d07 100644 --- a/sass/datepicker/_cell.scss +++ b/sass/datepicker/_cell.scss @@ -57,18 +57,7 @@ border-radius: 50%; &.-other-month- { - color: $colorAnotherMonth; - - &.-selected- { - color: #fff; - background: lighten($colorCellSelected, 20%); - - &.-disabled- { - background: none; - border: none; - } - - } + @extend %otherMonth; } } @@ -99,6 +88,6 @@ height: 40px; &.-other-decade- { - color: $colorAnotherMonth; + @extend %otherMonth; } } \ No newline at end of file diff --git a/sass/datepicker/datepicker-config.scss b/sass/datepicker/datepicker-config.scss index ea59101..97655ee 100644 --- a/sass/datepicker/datepicker-config.scss +++ b/sass/datepicker/datepicker-config.scss @@ -13,4 +13,20 @@ $colorAnotherMonth: #ddd; $colorCellHover: #eee; $colorCellCurrent: #60C4F5; $colorCellSelected: skyblue; -$colorCellWeekend: ''; \ No newline at end of file +$colorCellWeekend: ''; + +// Objects +%otherMonth { + color: $colorAnotherMonth; + font-size: .9em; + + &.-selected- { + color: #fff; + background: lighten($colorCellSelected, 20%); + } + + &:empty { + background: none; + border: none; + } +} \ No newline at end of file