From ff0294ea9b0e4de7857a111b7cce63a59c5e062a Mon Sep 17 00:00:00 2001 From: slackero Date: Tue, 15 Feb 2022 16:38:16 +0300 Subject: [PATCH] feat: add option to emphasize some featured dates Based on https://github.com/fengyuanchen/datepicker/pull/129 --- .babelrc | 5 +- CHANGELOG.md | 4 + README.md | 32 +++- dist/datepicker.common.js | 97 ++++++++++++- dist/datepicker.css | 9 +- dist/datepicker.esm.js | 97 ++++++++++++- dist/datepicker.js | 97 ++++++++++++- dist/datepicker.min.css | 6 +- dist/datepicker.min.js | 6 +- docs/css/datepicker.css | 242 ++++++++++++++++--------------- docs/css/main.css | 2 +- docs/index.html | 8 +- docs/js/datepicker.js | 97 ++++++++++++- package-lock.json | 4 +- package.json | 2 +- src/css/datepicker.css | 3 + src/css/datepicker.scss | 5 + src/js/datepicker.js | 19 ++- src/js/defaults.js | 3 + src/js/methods.js | 14 ++ src/js/render.js | 42 ++++++ test/methods/setFeaturedDates.js | 8 + test/options/featuredDates.js | 22 +++ 23 files changed, 658 insertions(+), 166 deletions(-) create mode 100644 test/methods/setFeaturedDates.js create mode 100644 test/options/featuredDates.js diff --git a/.babelrc b/.babelrc index 9da67db..ba10620 100644 --- a/.babelrc +++ b/.babelrc @@ -3,7 +3,10 @@ [ "@babel/preset-env", { - "modules": false + "modules": false, + "targets": { + "browsers": ["last 3 versions", "firefox esr", "ie >= 11", "not dead"] + } } ] ] diff --git a/CHANGELOG.md b/CHANGELOG.md index d847d4f..ff806d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.0.11 (Sep 29, 2020) + +- Add option to emphasize some featured dates + ## 1.0.10 (Sep 29, 2020) - Add some new i18n languages. diff --git a/README.md b/README.md index 89a931c..67ab363 100644 --- a/README.md +++ b/README.md @@ -301,6 +301,13 @@ A class (CSS) for disabled item. A class (CSS) for highlight date item. +### featuredClass + +- Type: `String` +- Default: `'featured'` + +A class (CSS) for featured date item. + ### template - Type: `String` @@ -360,7 +367,7 @@ The CSS `z-index` style for the datepicker. - Default: `null` - Syntax: `filter(date, view)` - `date`: the date for checking. - - `view`: the the current view, one of `day`, `month` or `year`. + - `view`: the current view, one of `day`, `month` or `year`. Filter each date item. If return a `false` value, the related date will be disabled. @@ -376,6 +383,13 @@ $().datepicker({ }); ``` +### featuredDates + +- Type: `Array` +- Default: `[]` + +A list of dates that will be emphasized in the calendar. + ### show - Type: `Function` @@ -523,6 +537,13 @@ Set the start view date with a new date. Set the end view date with a new date. +### setFeaturedDates(dates) + +- **dates**: + - Type: `Array` of `Date` or `String` or null + +Set the list of featured dates with a new list. + ### parseDate(date) - **date**: @@ -630,12 +651,9 @@ If you have to use other plugin with the same namespace, just call the `$.fn.dat ## Browser support -- Chrome (latest) -- Firefox (latest) -- Safari (latest) -- Opera (latest) -- Edge (latest) -- Internet Explorer 9+ +- Latest 3 versions (Chrome, Safari, Firefox, Firefox ESR, Edge etc.) +- Not dead (currently used browsers) +- Internet Explorer 11+ ## Versioning diff --git a/dist/datepicker.common.js b/dist/datepicker.common.js index 7335564..d320d57 100644 --- a/dist/datepicker.common.js +++ b/dist/datepicker.common.js @@ -1,11 +1,11 @@ /*! - * Datepicker v1.0.10 + * Datepicker v1.0.11 * https://fengyuanchen.github.io/datepicker * * Copyright 2014-present Chen Fengyuan * Released under the MIT license * - * Date: 2022-02-15T10:47:58.195Z + * Date: 2022-02-15T13:33:48.926Z */ 'use strict'; @@ -95,6 +95,8 @@ var DEFAULTS = { disabledClass: 'disabled', // A class (CSS) for highlight date item highlightedClass: 'highlighted', + // A class (CSS) for featured date item + featuredClass: 'featured', // The template of the datepicker template: '
' + '
' + '
    ' + '
  • ' + '
  • ' + '
  • ' + '
' + '
    ' + '
    ' + '
    ' + '
      ' + '
    • ' + '
    • ' + '
    • ' + '
    ' + '
      ' + '
      ' + '
      ' + '
        ' + '
      • ' + '
      • ' + '
      • ' + '
      ' + '
        ' + '
          ' + '
          ' + '
          ', // The offset top or bottom of the datepicker from the element @@ -491,6 +493,24 @@ var methods = { } }, + /** + * Sets the list of featured dates with a new list + * + * @param dates + */ + setFeaturedDates: function setFeaturedDates(dates) { + var _this = this; + + dates = Array.isArray(dates) ? dates : [dates]; + this.featuredDates = dates.map(function (date) { + return _this.parseDate(date); + }); + + if (this.built) { + this.render(); + } + }, + /** * Parse a date string with the set date format * @@ -824,7 +844,8 @@ var render = { renderYears: function renderYears() { var options = this.options, startDate = this.startDate, - endDate = this.endDate; + endDate = this.endDate, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass, filter = options.filter, yearSuffix = options.yearSuffix; @@ -842,6 +863,7 @@ var render = { for (i = start; i <= end; i += 1) { var date = new Date(viewYear + i, 1, 1); var disabled = false; + var featured = false; if (startDate) { disabled = date.getFullYear() < startDate.getFullYear(); @@ -865,9 +887,22 @@ var render = { var picked = viewYear + i === year; var view = picked ? 'year picked' : 'year'; + var featuredDateLowerLimit = date.getTime(); + var featuredDateUpperLimit = new Date(viewYear + i + 1, 1, 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + items.push(this.createItem({ picked: picked, disabled: disabled, + featured: featured, text: viewYear + i, view: disabled ? 'year disabled' : view, highlighted: date.getFullYear() === thisYear @@ -883,7 +918,8 @@ var render = { var options = this.options, startDate = this.startDate, endDate = this.endDate, - viewDate = this.viewDate; + viewDate = this.viewDate, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass || ''; var months = options.monthsShort; var filter = $__default['default'].isFunction(options.filter) && options.filter; @@ -901,6 +937,7 @@ var render = { for (i = 0; i <= 11; i += 1) { var date = new Date(viewYear, i, 1); var disabled = false; + var featured = false; if (startDate) { prevDisabled = date.getFullYear() === startDate.getFullYear(); @@ -916,12 +953,25 @@ var render = { disabled = filter.call(this.$element, date, 'month') === false; } + var featuredDateLowerLimit = date.getTime(); + var featuredDateUpperLimit = new Date(viewYear, i + 1, 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + var picked = viewYear === year && i === month; var view = picked ? 'month picked' : 'month'; items.push(this.createItem({ disabled: disabled, picked: picked, highlighted: viewYear === thisYear && date.getMonth() === thisMonth, + featured: featured, index: i, text: months[i], view: disabled ? 'month disabled' : view @@ -939,7 +989,8 @@ var render = { startDate = this.startDate, endDate = this.endDate, viewDate = this.viewDate, - currentDate = this.date; + currentDate = this.date, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass, filter = options.filter, months = options.months, @@ -1065,6 +1116,7 @@ var render = { var _date = new Date(viewYear, viewMonth, i); var _disabled2 = false; + var featured = false; if (startDate) { _disabled2 = _date.getTime() < startDate.getTime(); @@ -1078,6 +1130,19 @@ var render = { _disabled2 = filter.call($element, _date, 'day') === false; } + var featuredDateLowerLimit = _date.getTime(); + + var featuredDateUpperLimit = new Date(viewYear, viewMonth, i + 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + var _picked = viewYear === year && viewMonth === month && i === day; var view = _picked ? 'day picked' : 'day'; @@ -1085,6 +1150,7 @@ var render = { disabled: _disabled2, picked: _picked, highlighted: viewYear === thisYear && viewMonth === thisMonth && _date.getDate() === thisDay, + featured: featured, text: i, view: _disabled2 ? 'day disabled' : view })); @@ -1123,17 +1189,21 @@ var Datepicker = /*#__PURE__*/function () { this.initialDate = null; this.startDate = null; this.endDate = null; + this.featuredDates = []; this.init(); } _createClass(Datepicker, [{ key: "init", value: function init() { + var _this = this; + var $this = this.$element, options = this.options; var startDate = options.startDate, endDate = options.endDate, - date = options.date; + date = options.date, + featuredDates = options.featuredDates; this.$trigger = $__default['default'](options.trigger); this.isInput = $this.is('input') || $this.is('textarea'); this.inline = options.inline && (options.container || !this.isInput); @@ -1167,6 +1237,14 @@ var Datepicker = /*#__PURE__*/function () { this.endDate = endDate; } + if (featuredDates) { + featuredDates = Array.isArray(featuredDates) ? featuredDates : [featuredDates]; + featuredDates = featuredDates.map(function (featuredDate) { + return _this.parseDate(featuredDate); + }); + this.featuredDates = featuredDates; + } + this.date = date; this.viewDate = new Date(date); this.initialDate = new Date(this.date); @@ -1422,7 +1500,8 @@ var Datepicker = /*#__PURE__*/function () { muted: false, picked: false, disabled: false, - highlighted: false + highlighted: false, + featured: false }; var classes = []; $__default['default'].extend(item, data); @@ -1443,6 +1522,10 @@ var Datepicker = /*#__PURE__*/function () { classes.push(options.disabledClass); } + if (item.featured) { + classes.push(options.featuredClass); + } + return "<".concat(itemTag).concat(classes.length > 0 ? " class=\"".concat(classes.join(' '), "\"") : '').concat(item.view ? " data-view=\"".concat(item.view, "\"") : '').concat(item.title ? " title=\"".concat(item.title, "\"") : '').concat(item.picked ? ' aria-selected="true"' : '', ">").concat(item.text, ""); } }, { diff --git a/dist/datepicker.css b/dist/datepicker.css index 0007e7d..d57d159 100644 --- a/dist/datepicker.css +++ b/dist/datepicker.css @@ -1,11 +1,11 @@ /*! - * Datepicker v1.0.10 + * Datepicker v1.0.11 * https://fengyuanchen.github.io/datepicker * * Copyright 2014-present Chen Fengyuan * Released under the MIT license * - * Date: 2022-02-15T12:46:47.044Z + * Date: 2022-02-15T13:33:47.813Z */ .datepicker-container { background-color: #fff; @@ -171,6 +171,11 @@ background-color: #e5f2ff; } +.datepicker-panel > ul > li.featured, +.datepicker-panel > ul > li.featured:hover { + color: #5f9ea0; +} + .datepicker-panel > ul > li[data-view="years prev"], .datepicker-panel > ul > li[data-view="year prev"], .datepicker-panel > ul > li[data-view="month prev"], diff --git a/dist/datepicker.esm.js b/dist/datepicker.esm.js index 7ce0717..78ab4d4 100644 --- a/dist/datepicker.esm.js +++ b/dist/datepicker.esm.js @@ -1,11 +1,11 @@ /*! - * Datepicker v1.0.10 + * Datepicker v1.0.11 * https://fengyuanchen.github.io/datepicker * * Copyright 2014-present Chen Fengyuan * Released under the MIT license * - * Date: 2022-02-15T10:47:58.195Z + * Date: 2022-02-15T13:33:48.926Z */ import $ from 'jquery'; @@ -89,6 +89,8 @@ var DEFAULTS = { disabledClass: 'disabled', // A class (CSS) for highlight date item highlightedClass: 'highlighted', + // A class (CSS) for featured date item + featuredClass: 'featured', // The template of the datepicker template: '
          ' + '
          ' + '
            ' + '
          • ' + '
          • ' + '
          • ' + '
          ' + '
            ' + '
            ' + '
            ' + '
              ' + '
            • ' + '
            • ' + '
            • ' + '
            ' + '
              ' + '
              ' + '
              ' + '
                ' + '
              • ' + '
              • ' + '
              • ' + '
              ' + '
                ' + '
                  ' + '
                  ' + '
                  ', // The offset top or bottom of the datepicker from the element @@ -485,6 +487,24 @@ var methods = { } }, + /** + * Sets the list of featured dates with a new list + * + * @param dates + */ + setFeaturedDates: function setFeaturedDates(dates) { + var _this = this; + + dates = Array.isArray(dates) ? dates : [dates]; + this.featuredDates = dates.map(function (date) { + return _this.parseDate(date); + }); + + if (this.built) { + this.render(); + } + }, + /** * Parse a date string with the set date format * @@ -818,7 +838,8 @@ var render = { renderYears: function renderYears() { var options = this.options, startDate = this.startDate, - endDate = this.endDate; + endDate = this.endDate, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass, filter = options.filter, yearSuffix = options.yearSuffix; @@ -836,6 +857,7 @@ var render = { for (i = start; i <= end; i += 1) { var date = new Date(viewYear + i, 1, 1); var disabled = false; + var featured = false; if (startDate) { disabled = date.getFullYear() < startDate.getFullYear(); @@ -859,9 +881,22 @@ var render = { var picked = viewYear + i === year; var view = picked ? 'year picked' : 'year'; + var featuredDateLowerLimit = date.getTime(); + var featuredDateUpperLimit = new Date(viewYear + i + 1, 1, 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + items.push(this.createItem({ picked: picked, disabled: disabled, + featured: featured, text: viewYear + i, view: disabled ? 'year disabled' : view, highlighted: date.getFullYear() === thisYear @@ -877,7 +912,8 @@ var render = { var options = this.options, startDate = this.startDate, endDate = this.endDate, - viewDate = this.viewDate; + viewDate = this.viewDate, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass || ''; var months = options.monthsShort; var filter = $.isFunction(options.filter) && options.filter; @@ -895,6 +931,7 @@ var render = { for (i = 0; i <= 11; i += 1) { var date = new Date(viewYear, i, 1); var disabled = false; + var featured = false; if (startDate) { prevDisabled = date.getFullYear() === startDate.getFullYear(); @@ -910,12 +947,25 @@ var render = { disabled = filter.call(this.$element, date, 'month') === false; } + var featuredDateLowerLimit = date.getTime(); + var featuredDateUpperLimit = new Date(viewYear, i + 1, 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + var picked = viewYear === year && i === month; var view = picked ? 'month picked' : 'month'; items.push(this.createItem({ disabled: disabled, picked: picked, highlighted: viewYear === thisYear && date.getMonth() === thisMonth, + featured: featured, index: i, text: months[i], view: disabled ? 'month disabled' : view @@ -933,7 +983,8 @@ var render = { startDate = this.startDate, endDate = this.endDate, viewDate = this.viewDate, - currentDate = this.date; + currentDate = this.date, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass, filter = options.filter, months = options.months, @@ -1059,6 +1110,7 @@ var render = { var _date = new Date(viewYear, viewMonth, i); var _disabled2 = false; + var featured = false; if (startDate) { _disabled2 = _date.getTime() < startDate.getTime(); @@ -1072,6 +1124,19 @@ var render = { _disabled2 = filter.call($element, _date, 'day') === false; } + var featuredDateLowerLimit = _date.getTime(); + + var featuredDateUpperLimit = new Date(viewYear, viewMonth, i + 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + var _picked = viewYear === year && viewMonth === month && i === day; var view = _picked ? 'day picked' : 'day'; @@ -1079,6 +1144,7 @@ var render = { disabled: _disabled2, picked: _picked, highlighted: viewYear === thisYear && viewMonth === thisMonth && _date.getDate() === thisDay, + featured: featured, text: i, view: _disabled2 ? 'day disabled' : view })); @@ -1117,17 +1183,21 @@ var Datepicker = /*#__PURE__*/function () { this.initialDate = null; this.startDate = null; this.endDate = null; + this.featuredDates = []; this.init(); } _createClass(Datepicker, [{ key: "init", value: function init() { + var _this = this; + var $this = this.$element, options = this.options; var startDate = options.startDate, endDate = options.endDate, - date = options.date; + date = options.date, + featuredDates = options.featuredDates; this.$trigger = $(options.trigger); this.isInput = $this.is('input') || $this.is('textarea'); this.inline = options.inline && (options.container || !this.isInput); @@ -1161,6 +1231,14 @@ var Datepicker = /*#__PURE__*/function () { this.endDate = endDate; } + if (featuredDates) { + featuredDates = Array.isArray(featuredDates) ? featuredDates : [featuredDates]; + featuredDates = featuredDates.map(function (featuredDate) { + return _this.parseDate(featuredDate); + }); + this.featuredDates = featuredDates; + } + this.date = date; this.viewDate = new Date(date); this.initialDate = new Date(this.date); @@ -1416,7 +1494,8 @@ var Datepicker = /*#__PURE__*/function () { muted: false, picked: false, disabled: false, - highlighted: false + highlighted: false, + featured: false }; var classes = []; $.extend(item, data); @@ -1437,6 +1516,10 @@ var Datepicker = /*#__PURE__*/function () { classes.push(options.disabledClass); } + if (item.featured) { + classes.push(options.featuredClass); + } + return "<".concat(itemTag).concat(classes.length > 0 ? " class=\"".concat(classes.join(' '), "\"") : '').concat(item.view ? " data-view=\"".concat(item.view, "\"") : '').concat(item.title ? " title=\"".concat(item.title, "\"") : '').concat(item.picked ? ' aria-selected="true"' : '', ">").concat(item.text, ""); } }, { diff --git a/dist/datepicker.js b/dist/datepicker.js index 5acf77f..7054210 100644 --- a/dist/datepicker.js +++ b/dist/datepicker.js @@ -1,11 +1,11 @@ /*! - * Datepicker v1.0.10 + * Datepicker v1.0.11 * https://fengyuanchen.github.io/datepicker * * Copyright 2014-present Chen Fengyuan * Released under the MIT license * - * Date: 2022-02-15T10:47:58.195Z + * Date: 2022-02-15T13:33:48.926Z */ (function (global, factory) { @@ -97,6 +97,8 @@ disabledClass: 'disabled', // A class (CSS) for highlight date item highlightedClass: 'highlighted', + // A class (CSS) for featured date item + featuredClass: 'featured', // The template of the datepicker template: '
                  ' + '
                  ' + '
                    ' + '
                  • ' + '
                  • ' + '
                  • ' + '
                  ' + '
                    ' + '
                    ' + '
                    ' + '
                      ' + '
                    • ' + '
                    • ' + '
                    • ' + '
                    ' + '
                      ' + '
                      ' + '
                      ' + '
                        ' + '
                      • ' + '
                      • ' + '
                      • ' + '
                      ' + '
                        ' + '
                          ' + '
                          ' + '
                          ', // The offset top or bottom of the datepicker from the element @@ -493,6 +495,24 @@ } }, + /** + * Sets the list of featured dates with a new list + * + * @param dates + */ + setFeaturedDates: function setFeaturedDates(dates) { + var _this = this; + + dates = Array.isArray(dates) ? dates : [dates]; + this.featuredDates = dates.map(function (date) { + return _this.parseDate(date); + }); + + if (this.built) { + this.render(); + } + }, + /** * Parse a date string with the set date format * @@ -826,7 +846,8 @@ renderYears: function renderYears() { var options = this.options, startDate = this.startDate, - endDate = this.endDate; + endDate = this.endDate, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass, filter = options.filter, yearSuffix = options.yearSuffix; @@ -844,6 +865,7 @@ for (i = start; i <= end; i += 1) { var date = new Date(viewYear + i, 1, 1); var disabled = false; + var featured = false; if (startDate) { disabled = date.getFullYear() < startDate.getFullYear(); @@ -867,9 +889,22 @@ var picked = viewYear + i === year; var view = picked ? 'year picked' : 'year'; + var featuredDateLowerLimit = date.getTime(); + var featuredDateUpperLimit = new Date(viewYear + i + 1, 1, 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + items.push(this.createItem({ picked: picked, disabled: disabled, + featured: featured, text: viewYear + i, view: disabled ? 'year disabled' : view, highlighted: date.getFullYear() === thisYear @@ -885,7 +920,8 @@ var options = this.options, startDate = this.startDate, endDate = this.endDate, - viewDate = this.viewDate; + viewDate = this.viewDate, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass || ''; var months = options.monthsShort; var filter = $__default['default'].isFunction(options.filter) && options.filter; @@ -903,6 +939,7 @@ for (i = 0; i <= 11; i += 1) { var date = new Date(viewYear, i, 1); var disabled = false; + var featured = false; if (startDate) { prevDisabled = date.getFullYear() === startDate.getFullYear(); @@ -918,12 +955,25 @@ disabled = filter.call(this.$element, date, 'month') === false; } + var featuredDateLowerLimit = date.getTime(); + var featuredDateUpperLimit = new Date(viewYear, i + 1, 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + var picked = viewYear === year && i === month; var view = picked ? 'month picked' : 'month'; items.push(this.createItem({ disabled: disabled, picked: picked, highlighted: viewYear === thisYear && date.getMonth() === thisMonth, + featured: featured, index: i, text: months[i], view: disabled ? 'month disabled' : view @@ -941,7 +991,8 @@ startDate = this.startDate, endDate = this.endDate, viewDate = this.viewDate, - currentDate = this.date; + currentDate = this.date, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass, filter = options.filter, months = options.months, @@ -1067,6 +1118,7 @@ var _date = new Date(viewYear, viewMonth, i); var _disabled2 = false; + var featured = false; if (startDate) { _disabled2 = _date.getTime() < startDate.getTime(); @@ -1080,6 +1132,19 @@ _disabled2 = filter.call($element, _date, 'day') === false; } + var featuredDateLowerLimit = _date.getTime(); + + var featuredDateUpperLimit = new Date(viewYear, viewMonth, i + 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + var _picked = viewYear === year && viewMonth === month && i === day; var view = _picked ? 'day picked' : 'day'; @@ -1087,6 +1152,7 @@ disabled: _disabled2, picked: _picked, highlighted: viewYear === thisYear && viewMonth === thisMonth && _date.getDate() === thisDay, + featured: featured, text: i, view: _disabled2 ? 'day disabled' : view })); @@ -1125,17 +1191,21 @@ this.initialDate = null; this.startDate = null; this.endDate = null; + this.featuredDates = []; this.init(); } _createClass(Datepicker, [{ key: "init", value: function init() { + var _this = this; + var $this = this.$element, options = this.options; var startDate = options.startDate, endDate = options.endDate, - date = options.date; + date = options.date, + featuredDates = options.featuredDates; this.$trigger = $__default['default'](options.trigger); this.isInput = $this.is('input') || $this.is('textarea'); this.inline = options.inline && (options.container || !this.isInput); @@ -1169,6 +1239,14 @@ this.endDate = endDate; } + if (featuredDates) { + featuredDates = Array.isArray(featuredDates) ? featuredDates : [featuredDates]; + featuredDates = featuredDates.map(function (featuredDate) { + return _this.parseDate(featuredDate); + }); + this.featuredDates = featuredDates; + } + this.date = date; this.viewDate = new Date(date); this.initialDate = new Date(this.date); @@ -1424,7 +1502,8 @@ muted: false, picked: false, disabled: false, - highlighted: false + highlighted: false, + featured: false }; var classes = []; $__default['default'].extend(item, data); @@ -1445,6 +1524,10 @@ classes.push(options.disabledClass); } + if (item.featured) { + classes.push(options.featuredClass); + } + return "<".concat(itemTag).concat(classes.length > 0 ? " class=\"".concat(classes.join(' '), "\"") : '').concat(item.view ? " data-view=\"".concat(item.view, "\"") : '').concat(item.title ? " title=\"".concat(item.title, "\"") : '').concat(item.picked ? ' aria-selected="true"' : '', ">").concat(item.text, ""); } }, { diff --git a/dist/datepicker.min.css b/dist/datepicker.min.css index 1e1f570..99b387e 100644 --- a/dist/datepicker.min.css +++ b/dist/datepicker.min.css @@ -1,9 +1,9 @@ /*! - * Datepicker v1.0.10 + * Datepicker v1.0.11 * https://fengyuanchen.github.io/datepicker * * Copyright 2014-present Chen Fengyuan * Released under the MIT license * - * Date: 2022-02-15T10:47:57.089Z - */.datepicker-container{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;background-color:#fff;direction:ltr;font-size:12px;left:0;line-height:30px;position:fixed;top:0;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:210px;z-index:-1}.datepicker-container:after,.datepicker-container:before{border:5px solid transparent;content:" ";display:block;height:0;position:absolute;width:0}.datepicker-dropdown{border:1px solid #ccc;-webkit-box-shadow:0 3px 6px #ccc;box-shadow:0 3px 6px #ccc;-webkit-box-sizing:content-box;box-sizing:content-box;position:absolute;z-index:1}.datepicker-inline{position:static}.datepicker-top-left,.datepicker-top-right{border-top-color:#39f}.datepicker-top-left:after,.datepicker-top-left:before,.datepicker-top-right:after,.datepicker-top-right:before{border-top:0;left:10px;top:-5px}.datepicker-top-left:before,.datepicker-top-right:before{border-bottom-color:#39f}.datepicker-top-left:after,.datepicker-top-right:after{border-bottom-color:#fff;top:-4px}.datepicker-bottom-left,.datepicker-bottom-right{border-bottom-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-left:before,.datepicker-bottom-right:after,.datepicker-bottom-right:before{border-bottom:0;bottom:-5px;left:10px}.datepicker-bottom-left:before,.datepicker-bottom-right:before{border-top-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-right:after{border-top-color:#fff;bottom:-4px}.datepicker-bottom-right:after,.datepicker-bottom-right:before,.datepicker-top-right:after,.datepicker-top-right:before{left:auto;right:10px}.datepicker-panel>ul{margin:0;padding:0;width:102%}.datepicker-panel>ul:after,.datepicker-panel>ul:before{content:" ";display:table}.datepicker-panel>ul:after{clear:both}.datepicker-panel>ul>li{background-color:#fff;cursor:pointer;float:left;height:30px;list-style:none;margin:0;padding:0;text-align:center;width:30px}.datepicker-panel>ul>li:hover{background-color:#e5f2ff}.datepicker-panel>ul>li.muted,.datepicker-panel>ul>li.muted:hover{color:#999}.datepicker-panel>ul>li.highlighted{background-color:#e5f2ff}.datepicker-panel>ul>li.highlighted:hover{background-color:#cce5ff}.datepicker-panel>ul>li.picked,.datepicker-panel>ul>li.picked:hover{color:#39f}.datepicker-panel>ul>li.disabled,.datepicker-panel>ul>li.disabled:hover{background-color:#fff;color:#ccc;cursor:default}.datepicker-panel>ul>li.disabled.highlighted,.datepicker-panel>ul>li.disabled.highlighted:hover{background-color:#e5f2ff}.datepicker-panel>ul>li[data-view="month next"],.datepicker-panel>ul>li[data-view="month prev"],.datepicker-panel>ul>li[data-view="year next"],.datepicker-panel>ul>li[data-view="year prev"],.datepicker-panel>ul>li[data-view="years next"],.datepicker-panel>ul>li[data-view="years prev"],.datepicker-panel>ul>li[data-view=next]{font-size:18px}.datepicker-panel>ul>li[data-view="month current"],.datepicker-panel>ul>li[data-view="year current"],.datepicker-panel>ul>li[data-view="years current"]{width:150px}.datepicker-panel>ul[data-view=months]>li,.datepicker-panel>ul[data-view=years]>li{height:52.5px;line-height:52.5px;width:52.5px}.datepicker-panel>ul[data-view=week]>li,.datepicker-panel>ul[data-view=week]>li:hover{background-color:#fff;cursor:default}.datepicker-hide{display:none} \ No newline at end of file + * Date: 2022-02-15T13:33:47.813Z + */.datepicker-container{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;background-color:#fff;direction:ltr;font-size:12px;left:0;line-height:30px;position:fixed;top:0;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:210px;z-index:-1}.datepicker-container:after,.datepicker-container:before{border:5px solid transparent;content:" ";display:block;height:0;position:absolute;width:0}.datepicker-dropdown{border:1px solid #ccc;-webkit-box-shadow:0 3px 6px #ccc;box-shadow:0 3px 6px #ccc;-webkit-box-sizing:content-box;box-sizing:content-box;position:absolute;z-index:1}.datepicker-inline{position:static}.datepicker-top-left,.datepicker-top-right{border-top-color:#39f}.datepicker-top-left:after,.datepicker-top-left:before,.datepicker-top-right:after,.datepicker-top-right:before{border-top:0;left:10px;top:-5px}.datepicker-top-left:before,.datepicker-top-right:before{border-bottom-color:#39f}.datepicker-top-left:after,.datepicker-top-right:after{border-bottom-color:#fff;top:-4px}.datepicker-bottom-left,.datepicker-bottom-right{border-bottom-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-left:before,.datepicker-bottom-right:after,.datepicker-bottom-right:before{border-bottom:0;bottom:-5px;left:10px}.datepicker-bottom-left:before,.datepicker-bottom-right:before{border-top-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-right:after{border-top-color:#fff;bottom:-4px}.datepicker-bottom-right:after,.datepicker-bottom-right:before,.datepicker-top-right:after,.datepicker-top-right:before{left:auto;right:10px}.datepicker-panel>ul{margin:0;padding:0;width:102%}.datepicker-panel>ul:after,.datepicker-panel>ul:before{content:" ";display:table}.datepicker-panel>ul:after{clear:both}.datepicker-panel>ul>li{background-color:#fff;cursor:pointer;float:left;height:30px;list-style:none;margin:0;padding:0;text-align:center;width:30px}.datepicker-panel>ul>li:hover{background-color:#e5f2ff}.datepicker-panel>ul>li.muted,.datepicker-panel>ul>li.muted:hover{color:#999}.datepicker-panel>ul>li.highlighted{background-color:#e5f2ff}.datepicker-panel>ul>li.highlighted:hover{background-color:#cce5ff}.datepicker-panel>ul>li.picked,.datepicker-panel>ul>li.picked:hover{color:#39f}.datepicker-panel>ul>li.disabled,.datepicker-panel>ul>li.disabled:hover{background-color:#fff;color:#ccc;cursor:default}.datepicker-panel>ul>li.disabled.highlighted,.datepicker-panel>ul>li.disabled:hover.highlighted{background-color:#e5f2ff}.datepicker-panel>ul>li.featured,.datepicker-panel>ul>li.featured:hover{color:#5f9ea0}.datepicker-panel>ul>li[data-view="month next"],.datepicker-panel>ul>li[data-view="month prev"],.datepicker-panel>ul>li[data-view="year next"],.datepicker-panel>ul>li[data-view="year prev"],.datepicker-panel>ul>li[data-view="years next"],.datepicker-panel>ul>li[data-view="years prev"],.datepicker-panel>ul>li[data-view=next]{font-size:18px}.datepicker-panel>ul>li[data-view="month current"],.datepicker-panel>ul>li[data-view="year current"],.datepicker-panel>ul>li[data-view="years current"]{width:150px}.datepicker-panel>ul[data-view=months]>li,.datepicker-panel>ul[data-view=years]>li{height:52.5px;line-height:52.5px;width:52.5px}.datepicker-panel>ul[data-view=week]>li,.datepicker-panel>ul[data-view=week]>li:hover{background-color:#fff;cursor:default}.datepicker-hide{display:none} \ No newline at end of file diff --git a/dist/datepicker.min.js b/dist/datepicker.min.js index 11c4c4c..88bdacf 100644 --- a/dist/datepicker.min.js +++ b/dist/datepicker.min.js @@ -1,10 +1,10 @@ /*! - * Datepicker v1.0.10 + * Datepicker v1.0.11 * https://fengyuanchen.github.io/datepicker * * Copyright 2014-present Chen Fengyuan * Released under the MIT license * - * Date: 2022-02-15T10:47:58.195Z + * Date: 2022-02-15T13:33:48.926Z */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jQuery)}(this,function(t){"use strict";function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var k=e(t);function o(t,e){for(var a=0;a
                                  ',offset:10,zIndex:1e3,filter:null,show:null,hide:null,pick:null},t="undefined"!=typeof window,a=t?window:{},s=t&&"ontouchstart"in a.document.documentElement,h="datepicker",i="click.".concat(h),p="focus.".concat(h),g="hide.".concat(h),y="keyup.".concat(h),m="pick.".concat(h),v="resize.".concat(h),w="scroll.".concat(h),b="show.".concat(h),D="touchstart.".concat(h),n="".concat(h,"-hide"),C={},$=0,d=1,x=2,F=Object.prototype.toString;function u(t){return"string"==typeof t}var M=Number.isNaN||a.isNaN;function Y(t){return"number"==typeof t&&!M(t)}function V(t){return void 0===t}function r(t){return"date"===F.call(t).slice(8,-1).toLowerCase()&&!M(t.getTime())}function T(i,s){for(var t=arguments.length,n=new Array(2a.getFullYear(),6===l&&(f=h)),!h&&s&&(h=!1===s.call(this.$element,o,"year")),n+l===u);r.push(this.createItem({picked:p,disabled:h,text:n+l,view:h?"year disabled":p?"year picked":"year",highlighted:o.getFullYear()===d}))}this.$yearsPrev.toggleClass(i,c),this.$yearsNext.toggleClass(i,f),this.$yearsCurrent.toggleClass(i,!0).html("".concat(n+-5+t," - ").concat(n+6).concat(t)),this.$years.html(r.join(""))},renderMonths:function(){for(var t=this.options,e=this.startDate,a=this.endDate,i=this.viewDate,s=t.disabledClass||"",d=t.monthsShort,u=k.default.isFunction(t.filter)&&t.filter,n=i.getFullYear(),i=new Date,c=i.getFullYear(),f=i.getMonth(),p=this.date.getFullYear(),g=this.date.getMonth(),y=[],r=!1,m=!1,l=0;l<=11;l+=1){var o=new Date(n,l,1),h=!1,v=(!(h=!(h=e?(r=o.getFullYear()===e.getFullYear())&&o.getMonth()a.getMonth():h)&&u&&(h=!1===u.call(this.$element,o,"month")),n===p&&l===g),w=v?"month picked":"month";y.push(this.createItem({disabled:h,picked:v,highlighted:n===c&&o.getMonth()===f,index:l,text:d[l],view:h?"month disabled":w}))}this.$yearPrev.toggleClass(s,r),this.$yearNext.toggleClass(s,m),this.$yearCurrent.toggleClass(s,r&&m).html(n+t.yearSuffix||""),this.$months.html(y.join(""))},renderDays:function(){var t,d=this.$element,e=this.options,a=this.startDate,i=this.endDate,s=this.viewDate,n=this.date,u=e.disabledClass,c=e.filter,f=e.months,p=e.weekStart,g=e.yearSuffix,r=s.getFullYear(),l=s.getMonth(),s=new Date,y=s.getFullYear(),m=s.getMonth(),v=s.getDate(),w=n.getFullYear(),k=n.getMonth(),b=n.getDate(),D=[],C=r,$=l,s=!1,n=(0===l?(--C,$=11):--$,t=O(C,$),new Date(r,l,1)),x=n.getDay()-parseInt(p,10)%7;for(x<=0&&(x+=7),a&&(s=n.getTime()<=a.getTime()),o=t-(x-1);o<=t;o+=1){var F=new Date(C,$,o),M=!1;!(M=a?F.getTime()=i.getTime()),o=1;o<=x;o+=1){var I=new Date(V,T,o),S=V===w&&T===k&&o===b,P=!1;!(P=i?I.getTime()>i.getTime():P)&&c&&(P=!1===c.call(d,I,"day")),Y.push(this.createItem({disabled:P,picked:S,highlighted:V===y&&T===m&&I.getDate()===v,muted:!0,text:o,view:"day next"}))}for(var N=[],o=1;o<=t;o+=1){var j=new Date(r,l,o),h=!1,A=(!(h=!(h=a?j.getTime()i.getTime():h)&&c&&(h=!1===c.call(d,j,"day")),r===w&&l===k&&o===b),q=A?"day picked":"day";N.push(this.createItem({disabled:h,picked:A,highlighted:r===y&&l===m&&j.getDate()===v,text:o,view:h?"day disabled":q}))}this.$monthPrev.toggleClass(u,s),this.$monthNext.toggleClass(u,p),this.$monthCurrent.toggleClass(u,s&&p).html(e.yearFirst?"".concat(r+g," ").concat(f[l]):"".concat(f[l]," ").concat(r).concat(g)),this.$days.html(D.join("")+N.join("")+Y.join(""))}},A="".concat(h,"-top-left"),q="".concat(h,"-top-right"),W="".concat(h,"-bottom-left"),z="".concat(h,"-bottom-right"),J=[A,q,W,z].join(" "),E=function(){function s(t){var e=1i.getTime()&&(s=new Date(i)),this.endDate=i),this.date=s,this.viewDate=new Date(s),this.initialDate=new Date(this.date),this.bind(),(e.autoShow||this.inline)&&this.show(),e.autoPick&&this.pick()}},{key:"build",value:function(){var t,e,a;this.built||(this.built=!0,t=this.$element,e=this.options,a=k.default(e.template),this.$picker=a,this.$week=a.find(l("week")),this.$yearsPicker=a.find(l("years picker")),this.$yearsPrev=a.find(l("years prev")),this.$yearsNext=a.find(l("years next")),this.$yearsCurrent=a.find(l("years current")),this.$years=a.find(l("years")),this.$monthsPicker=a.find(l("months picker")),this.$yearPrev=a.find(l("year prev")),this.$yearNext=a.find(l("year next")),this.$yearCurrent=a.find(l("year current")),this.$months=a.find(l("months")),this.$daysPicker=a.find(l("days picker")),this.$monthPrev=a.find(l("month prev")),this.$monthNext=a.find(l("month next")),this.$monthCurrent=a.find(l("month current")),this.$days=a.find(l("days")),this.inline?k.default(e.container||t).append(a.addClass("".concat(h,"-inline"))):(k.default(document.body).append(a.addClass("".concat(h,"-dropdown"))),a.addClass(n).attr("tabindex","-1").attr("aria-hidden","true").css({zIndex:parseInt(e.zIndex,10)})),this.renderWeek())}},{key:"unbuild",value:function(){this.built&&(this.built=!1,this.$picker.remove())}},{key:"bind",value:function(){var t=this.options,e=this.$element;k.default.isFunction(t.show)&&e.on(b,t.show),k.default.isFunction(t.hide)&&e.on(g,t.hide),k.default.isFunction(t.pick)&&e.on(m,t.pick),this.isInput&&e.on(y,k.default.proxy(this.keyup,this)),this.inline||(t.trigger?this.$trigger.on(i,k.default.proxy(this.toggle,this)):this.isInput?e.on(p,k.default.proxy(this.show,this)):e.on(i,k.default.proxy(this.show,this)))}},{key:"unbind",value:function(){var t=this.$element,e=this.options;k.default.isFunction(e.show)&&t.off(b,e.show),k.default.isFunction(e.hide)&&t.off(g,e.hide),k.default.isFunction(e.pick)&&t.off(m,e.pick),this.isInput&&t.off(y,this.keyup),this.inline||(e.trigger?this.$trigger.off(i,this.toggle):this.isInput?t.off(p,this.show):t.off(i,this.show))}},{key:"showView",value:function(t){var e=this.$yearsPicker,a=this.$monthsPicker,i=this.$daysPicker,s=this.format;if(s.hasYear||s.hasMonth||s.hasDay)switch(Number(t)){case x:a.addClass(n),i.addClass(n),s.hasYear?(this.renderYears(),e.removeClass(n),this.place()):this.showView($);break;case d:e.addClass(n),i.addClass(n),s.hasMonth?(this.renderMonths(),a.removeClass(n),this.place()):this.showView(x);break;default:e.addClass(n),a.addClass(n),s.hasDay?(this.renderDays(),i.removeClass(n),this.place()):this.showView(d)}}},{key:"hideView",value:function(){!this.inline&&this.options.autoHide&&this.hide()}},{key:"place",value:function(){var t,e,a,d,i,s,n,r,l,o,h;this.inline||(l=this.$element,o=this.options,t=this.$picker,e=k.default(document).outerWidth(),a=k.default(document).outerHeight(),d=l.outerWidth(),i=l.outerHeight(),s=t.width(),n=t.height(),r=(l=l.offset()).left,l=l.top,o=parseFloat(o.offset),h=A,M(o)&&(o=10),n").concat(i.text,"")}},{key:"getValue",value:function(){var t=this.$element;return this.isInput?t.val():t.text()}},{key:"setValue",value:function(){var t=0
                                          ',offset:10,zIndex:1e3,filter:null,show:null,hide:null,pick:null},e="undefined"!=typeof window,a=e?window:{},s=e&&"ontouchstart"in a.document.documentElement,o="datepicker",i="click.".concat(o),p="focus.".concat(o),g="hide.".concat(o),y="keyup.".concat(o),m="pick.".concat(o),v="resize.".concat(o),w="scroll.".concat(o),k="show.".concat(o),D="touchstart.".concat(o),n="".concat(o,"-hide"),b={},C=0,d=1,$=2,x=Object.prototype.toString;function u(e){return"string"==typeof e}var T=Number.isNaN||a.isNaN;function M(e){return"number"==typeof e&&!T(e)}function Y(e){return void 0===e}function r(e){return"date"===x.call(e).slice(8,-1).toLowerCase()&&!T(e.getTime())}function V(i,s){for(var e=arguments.length,n=new Array(2a.getFullYear(),6===r&&(g=h)),!h&&d&&(h=!1===d.call(this.$element,l,"year")),n+r===c),v=m?"year picked":"year",w=l.getTime(),k=new Date(n+r+1,1,1).getTime(),o=0;o=w&&D.getTime()a.getMonth():o)&&c&&(o=!1===c.call(this.$element,h,"month")),h.getTime()),D=new Date(n,l+1,1).getTime(),b=0;b=k&&C.getTime()=i.getTime()),h=1;h<=F;h+=1){var S=new Date(V,I,h),P=V===k&&I===D&&h===b,N=!1;!(N=i?S.getTime()>i.getTime():N)&&f&&(N=!1===f.call(d,S,"day")),Y.push(this.createItem({disabled:N,picked:P,highlighted:V===m&&I===v&&S.getDate()===w,muted:!0,text:h,view:"day next"}))}for(var j=[],h=1;h<=e;h+=1){for(var A=new Date(r,l,h),o=!1,q=!1,O=(!(o=!(o=a?A.getTime()i.getTime():o)&&f&&(o=!1===f.call(d,A,"day")),A.getTime()),W=new Date(r,l,h+1).getTime(),z=0;z=O&&J.getTime()s.getTime()&&(n=new Date(s)),this.endDate=s),r&&(r=(r=Array.isArray(r)?r:[r]).map(function(e){return t.parseDate(e)}),this.featuredDates=r),this.date=n,this.viewDate=new Date(n),this.initialDate=new Date(this.date),this.bind(),(a.autoShow||this.inline)&&this.show(),a.autoPick&&this.pick()}},{key:"build",value:function(){var e,t,a;this.built||(this.built=!0,e=this.$element,t=this.options,a=F.default(t.template),this.$picker=a,this.$week=a.find(l("week")),this.$yearsPicker=a.find(l("years picker")),this.$yearsPrev=a.find(l("years prev")),this.$yearsNext=a.find(l("years next")),this.$yearsCurrent=a.find(l("years current")),this.$years=a.find(l("years")),this.$monthsPicker=a.find(l("months picker")),this.$yearPrev=a.find(l("year prev")),this.$yearNext=a.find(l("year next")),this.$yearCurrent=a.find(l("year current")),this.$months=a.find(l("months")),this.$daysPicker=a.find(l("days picker")),this.$monthPrev=a.find(l("month prev")),this.$monthNext=a.find(l("month next")),this.$monthCurrent=a.find(l("month current")),this.$days=a.find(l("days")),this.inline?F.default(t.container||e).append(a.addClass("".concat(o,"-inline"))):(F.default(document.body).append(a.addClass("".concat(o,"-dropdown"))),a.addClass(n).attr("tabindex","-1").attr("aria-hidden","true").css({zIndex:parseInt(t.zIndex,10)})),this.renderWeek())}},{key:"unbuild",value:function(){this.built&&(this.built=!1,this.$picker.remove())}},{key:"bind",value:function(){var e=this.options,t=this.$element;F.default.isFunction(e.show)&&t.on(k,e.show),F.default.isFunction(e.hide)&&t.on(g,e.hide),F.default.isFunction(e.pick)&&t.on(m,e.pick),this.isInput&&t.on(y,F.default.proxy(this.keyup,this)),this.inline||(e.trigger?this.$trigger.on(i,F.default.proxy(this.toggle,this)):this.isInput?t.on(p,F.default.proxy(this.show,this)):t.on(i,F.default.proxy(this.show,this)))}},{key:"unbind",value:function(){var e=this.$element,t=this.options;F.default.isFunction(t.show)&&e.off(k,t.show),F.default.isFunction(t.hide)&&e.off(g,t.hide),F.default.isFunction(t.pick)&&e.off(m,t.pick),this.isInput&&e.off(y,this.keyup),this.inline||(t.trigger?this.$trigger.off(i,this.toggle):this.isInput?e.off(p,this.show):e.off(i,this.show))}},{key:"showView",value:function(e){var t=this.$yearsPicker,a=this.$monthsPicker,i=this.$daysPicker,s=this.format;if(s.hasYear||s.hasMonth||s.hasDay)switch(Number(e)){case $:a.addClass(n),i.addClass(n),s.hasYear?(this.renderYears(),t.removeClass(n),this.place()):this.showView(C);break;case d:t.addClass(n),i.addClass(n),s.hasMonth?(this.renderMonths(),a.removeClass(n),this.place()):this.showView($);break;default:t.addClass(n),a.addClass(n),s.hasDay?(this.renderDays(),i.removeClass(n),this.place()):this.showView(d)}}},{key:"hideView",value:function(){!this.inline&&this.options.autoHide&&this.hide()}},{key:"place",value:function(){var e,t,a,d,i,s,n,r,l,h,o;this.inline||(l=this.$element,h=this.options,e=this.$picker,t=F.default(document).outerWidth(),a=F.default(document).outerHeight(),d=l.outerWidth(),i=l.outerHeight(),s=e.width(),n=e.height(),r=(l=l.offset()).left,l=l.top,h=parseFloat(h.offset),o=A,T(h)&&(h=10),n").concat(i.text,"")}},{key:"getValue",value:function(){var e=this.$element;return this.isInput?e.val():e.text()}},{key:"setValue",value:function(){var e=0 ul { - margin: 0; - padding: 0; - width: 102% - } + margin: 0; + padding: 0; + width: 102%; +} .datepicker-panel > ul::before, - .datepicker-panel > ul::after { - content: " "; - display: table; - } +.datepicker-panel > ul::after { + content: " "; + display: table; +} .datepicker-panel > ul::after { - clear: both; - } + clear: both; +} .datepicker-panel > ul > li { - background-color: #fff; - cursor: pointer; - float: left; - height: 30px; - list-style: none; - margin: 0; - padding: 0; - text-align: center; - width: 30px - } + background-color: #fff; + cursor: pointer; + float: left; + height: 30px; + list-style: none; + margin: 0; + padding: 0; + text-align: center; + width: 30px; +} .datepicker-panel > ul > li:hover { - background-color: rgb(229, 242, 255); - } + background-color: #e5f2ff; +} .datepicker-panel > ul > li.muted, - .datepicker-panel > ul > li.muted:hover { - color: #999; - } +.datepicker-panel > ul > li.muted:hover { + color: #999; +} .datepicker-panel > ul > li.highlighted { - background-color: rgb(229, 242, 255) - } + background-color: #e5f2ff; +} .datepicker-panel > ul > li.highlighted:hover { - background-color: rgb(204, 229, 255); - } + background-color: #cce5ff; +} .datepicker-panel > ul > li.picked, - .datepicker-panel > ul > li.picked:hover { - color: #39f; - } +.datepicker-panel > ul > li.picked:hover { + color: #39f; +} .datepicker-panel > ul > li.disabled, - .datepicker-panel > ul > li.disabled:hover { - background-color: #fff; - color: #ccc; - cursor: default - } +.datepicker-panel > ul > li.disabled:hover { + background-color: #fff; + color: #ccc; + cursor: default; +} -.datepicker-panel > ul > li.disabled.highlighted, .datepicker-panel > ul > li.disabled.highlighted:hover { - background-color: rgb(229, 242, 255); - } +.datepicker-panel > ul > li.disabled.highlighted, +.datepicker-panel > ul > li.disabled:hover.highlighted { + background-color: #e5f2ff; +} + +.datepicker-panel > ul > li.featured, +.datepicker-panel > ul > li.featured:hover { + color: #5f9ea0; +} .datepicker-panel > ul > li[data-view="years prev"], - .datepicker-panel > ul > li[data-view="year prev"], - .datepicker-panel > ul > li[data-view="month prev"], - .datepicker-panel > ul > li[data-view="years next"], - .datepicker-panel > ul > li[data-view="year next"], - .datepicker-panel > ul > li[data-view="month next"], - .datepicker-panel > ul > li[data-view="next"] { - font-size: 18px; - } +.datepicker-panel > ul > li[data-view="year prev"], +.datepicker-panel > ul > li[data-view="month prev"], +.datepicker-panel > ul > li[data-view="years next"], +.datepicker-panel > ul > li[data-view="year next"], +.datepicker-panel > ul > li[data-view="month next"], +.datepicker-panel > ul > li[data-view=next] { + font-size: 18px; +} .datepicker-panel > ul > li[data-view="years current"], - .datepicker-panel > ul > li[data-view="year current"], - .datepicker-panel > ul > li[data-view="month current"] { - width: 150px; - } - -.datepicker-panel > ul[data-view="years"] > li, .datepicker-panel > ul[data-view="months"] > li { - height: 52.5px; - line-height: 52.5px; - width: 52.5px; - } - -.datepicker-panel > ul[data-view="week"] > li, - .datepicker-panel > ul[data-view="week"] > li:hover { - background-color: #fff; - cursor: default; - } +.datepicker-panel > ul > li[data-view="year current"], +.datepicker-panel > ul > li[data-view="month current"] { + width: 150px; +} + +.datepicker-panel > ul[data-view=years] > li, +.datepicker-panel > ul[data-view=months] > li { + height: 52.5px; + line-height: 52.5px; + width: 52.5px; +} + +.datepicker-panel > ul[data-view=week] > li, +.datepicker-panel > ul[data-view=week] > li:hover { + background-color: #fff; + cursor: default; +} .datepicker-hide { display: none; diff --git a/docs/css/main.css b/docs/css/main.css index 0a8bac1..7d8aa8c 100644 --- a/docs/css/main.css +++ b/docs/css/main.css @@ -120,7 +120,7 @@ .docs-options > .input-group .input-group-text { justify-content: center; - min-width: 6rem; + min-width: 8rem; } .docs-actions > .input-group, diff --git a/docs/index.html b/docs/index.html index 32f85f3..4e0e636 100644 --- a/docs/index.html +++ b/docs/index.html @@ -62,7 +62,7 @@
                                          -

                                          Datepicker v1.0.10

                                          +

                                          Datepicker v1.0.11

                                          A simple jQuery datepicker plugin.

                                          @@ -119,6 +119,12 @@
                                          +
                                          +
                                          + featuredDates +
                                          + +
                                          language diff --git a/docs/js/datepicker.js b/docs/js/datepicker.js index 5acf77f..7054210 100644 --- a/docs/js/datepicker.js +++ b/docs/js/datepicker.js @@ -1,11 +1,11 @@ /*! - * Datepicker v1.0.10 + * Datepicker v1.0.11 * https://fengyuanchen.github.io/datepicker * * Copyright 2014-present Chen Fengyuan * Released under the MIT license * - * Date: 2022-02-15T10:47:58.195Z + * Date: 2022-02-15T13:33:48.926Z */ (function (global, factory) { @@ -97,6 +97,8 @@ disabledClass: 'disabled', // A class (CSS) for highlight date item highlightedClass: 'highlighted', + // A class (CSS) for featured date item + featuredClass: 'featured', // The template of the datepicker template: '
                                          ' + '
                                          ' + '
                                            ' + '
                                          • ' + '
                                          • ' + '
                                          • ' + '
                                          ' + '
                                            ' + '
                                            ' + '
                                            ' + '
                                              ' + '
                                            • ' + '
                                            • ' + '
                                            • ' + '
                                            ' + '
                                              ' + '
                                              ' + '
                                              ' + '
                                                ' + '
                                              • ' + '
                                              • ' + '
                                              • ' + '
                                              ' + '
                                                ' + '
                                                  ' + '
                                                  ' + '
                                                  ', // The offset top or bottom of the datepicker from the element @@ -493,6 +495,24 @@ } }, + /** + * Sets the list of featured dates with a new list + * + * @param dates + */ + setFeaturedDates: function setFeaturedDates(dates) { + var _this = this; + + dates = Array.isArray(dates) ? dates : [dates]; + this.featuredDates = dates.map(function (date) { + return _this.parseDate(date); + }); + + if (this.built) { + this.render(); + } + }, + /** * Parse a date string with the set date format * @@ -826,7 +846,8 @@ renderYears: function renderYears() { var options = this.options, startDate = this.startDate, - endDate = this.endDate; + endDate = this.endDate, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass, filter = options.filter, yearSuffix = options.yearSuffix; @@ -844,6 +865,7 @@ for (i = start; i <= end; i += 1) { var date = new Date(viewYear + i, 1, 1); var disabled = false; + var featured = false; if (startDate) { disabled = date.getFullYear() < startDate.getFullYear(); @@ -867,9 +889,22 @@ var picked = viewYear + i === year; var view = picked ? 'year picked' : 'year'; + var featuredDateLowerLimit = date.getTime(); + var featuredDateUpperLimit = new Date(viewYear + i + 1, 1, 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + items.push(this.createItem({ picked: picked, disabled: disabled, + featured: featured, text: viewYear + i, view: disabled ? 'year disabled' : view, highlighted: date.getFullYear() === thisYear @@ -885,7 +920,8 @@ var options = this.options, startDate = this.startDate, endDate = this.endDate, - viewDate = this.viewDate; + viewDate = this.viewDate, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass || ''; var months = options.monthsShort; var filter = $__default['default'].isFunction(options.filter) && options.filter; @@ -903,6 +939,7 @@ for (i = 0; i <= 11; i += 1) { var date = new Date(viewYear, i, 1); var disabled = false; + var featured = false; if (startDate) { prevDisabled = date.getFullYear() === startDate.getFullYear(); @@ -918,12 +955,25 @@ disabled = filter.call(this.$element, date, 'month') === false; } + var featuredDateLowerLimit = date.getTime(); + var featuredDateUpperLimit = new Date(viewYear, i + 1, 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + var picked = viewYear === year && i === month; var view = picked ? 'month picked' : 'month'; items.push(this.createItem({ disabled: disabled, picked: picked, highlighted: viewYear === thisYear && date.getMonth() === thisMonth, + featured: featured, index: i, text: months[i], view: disabled ? 'month disabled' : view @@ -941,7 +991,8 @@ startDate = this.startDate, endDate = this.endDate, viewDate = this.viewDate, - currentDate = this.date; + currentDate = this.date, + featuredDates = this.featuredDates; var disabledClass = options.disabledClass, filter = options.filter, months = options.months, @@ -1067,6 +1118,7 @@ var _date = new Date(viewYear, viewMonth, i); var _disabled2 = false; + var featured = false; if (startDate) { _disabled2 = _date.getTime() < startDate.getTime(); @@ -1080,6 +1132,19 @@ _disabled2 = filter.call($element, _date, 'day') === false; } + var featuredDateLowerLimit = _date.getTime(); + + var featuredDateUpperLimit = new Date(viewYear, viewMonth, i + 1).getTime(); + + for (var j = 0; j < featuredDates.length; j += 1) { + var featuredDate = featuredDates[j]; + + if (featuredDate.getTime() >= featuredDateLowerLimit && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + var _picked = viewYear === year && viewMonth === month && i === day; var view = _picked ? 'day picked' : 'day'; @@ -1087,6 +1152,7 @@ disabled: _disabled2, picked: _picked, highlighted: viewYear === thisYear && viewMonth === thisMonth && _date.getDate() === thisDay, + featured: featured, text: i, view: _disabled2 ? 'day disabled' : view })); @@ -1125,17 +1191,21 @@ this.initialDate = null; this.startDate = null; this.endDate = null; + this.featuredDates = []; this.init(); } _createClass(Datepicker, [{ key: "init", value: function init() { + var _this = this; + var $this = this.$element, options = this.options; var startDate = options.startDate, endDate = options.endDate, - date = options.date; + date = options.date, + featuredDates = options.featuredDates; this.$trigger = $__default['default'](options.trigger); this.isInput = $this.is('input') || $this.is('textarea'); this.inline = options.inline && (options.container || !this.isInput); @@ -1169,6 +1239,14 @@ this.endDate = endDate; } + if (featuredDates) { + featuredDates = Array.isArray(featuredDates) ? featuredDates : [featuredDates]; + featuredDates = featuredDates.map(function (featuredDate) { + return _this.parseDate(featuredDate); + }); + this.featuredDates = featuredDates; + } + this.date = date; this.viewDate = new Date(date); this.initialDate = new Date(this.date); @@ -1424,7 +1502,8 @@ muted: false, picked: false, disabled: false, - highlighted: false + highlighted: false, + featured: false }; var classes = []; $__default['default'].extend(item, data); @@ -1445,6 +1524,10 @@ classes.push(options.disabledClass); } + if (item.featured) { + classes.push(options.featuredClass); + } + return "<".concat(itemTag).concat(classes.length > 0 ? " class=\"".concat(classes.join(' '), "\"") : '').concat(item.view ? " data-view=\"".concat(item.view, "\"") : '').concat(item.title ? " title=\"".concat(item.title, "\"") : '').concat(item.picked ? ' aria-selected="true"' : '', ">").concat(item.text, ""); } }, { diff --git a/package-lock.json b/package-lock.json index 2bf2f25..60427f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@chenfengyuan/datepicker", - "version": "1.0.10", + "version": "1.0.11", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@chenfengyuan/datepicker", - "version": "1.0.10", + "version": "1.0.11", "license": "MIT", "devDependencies": { "@babel/core": "^7.17.2", diff --git a/package.json b/package.json index bbdc348..cfb2820 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@chenfengyuan/datepicker", - "version": "1.0.10", + "version": "1.0.11", "description": "A simple jQuery datepicker plugin.", "main": "dist/datepicker.common.js", "module": "dist/datepicker.esm.js", diff --git a/src/css/datepicker.css b/src/css/datepicker.css index 1cdc46e..d23f9e9 100644 --- a/src/css/datepicker.css +++ b/src/css/datepicker.css @@ -111,6 +111,9 @@ .datepicker-panel > ul > li.disabled.highlighted, .datepicker-panel > ul > li.disabled:hover.highlighted { background-color: #e5f2ff; } +.datepicker-panel > ul > li.featured, .datepicker-panel > ul > li.featured:hover { + color: #5f9ea0; +} .datepicker-panel > ul > li[data-view="years prev"], .datepicker-panel > ul > li[data-view="year prev"], .datepicker-panel > ul > li[data-view="month prev"], .datepicker-panel > ul > li[data-view="years next"], .datepicker-panel > ul > li[data-view="year next"], .datepicker-panel > ul > li[data-view="month next"], .datepicker-panel > ul > li[data-view=next] { font-size: 18px; } diff --git a/src/css/datepicker.scss b/src/css/datepicker.scss index 98faf75..59bee3d 100644 --- a/src/css/datepicker.scss +++ b/src/css/datepicker.scss @@ -148,6 +148,11 @@ } } + &.featured, + &.featured:hover { + color: #5f9ea0; + } + &[data-view="years prev"], &[data-view="year prev"], &[data-view="month prev"], diff --git a/src/js/datepicker.js b/src/js/datepicker.js index 78b3aae..d65e1d7 100644 --- a/src/js/datepicker.js +++ b/src/js/datepicker.js @@ -53,12 +53,18 @@ class Datepicker { this.initialDate = null; this.startDate = null; this.endDate = null; + this.featuredDates = []; this.init(); } init() { const { $element: $this, options } = this; - let { startDate, endDate, date } = options; + let { + startDate, + endDate, + date, + featuredDates, + } = options; this.$trigger = $(options.trigger); this.isInput = $this.is('input') || $this.is('textarea'); @@ -95,6 +101,12 @@ class Datepicker { this.endDate = endDate; } + if (featuredDates) { + featuredDates = Array.isArray(featuredDates) ? featuredDates : [featuredDates]; + featuredDates = featuredDates.map((featuredDate) => this.parseDate(featuredDate)); + this.featuredDates = featuredDates; + } + this.date = date; this.viewDate = new Date(date); this.initialDate = new Date(this.date); @@ -345,6 +357,7 @@ class Datepicker { picked: false, disabled: false, highlighted: false, + featured: false, }; const classes = []; @@ -366,6 +379,10 @@ class Datepicker { classes.push(options.disabledClass); } + if (item.featured) { + classes.push(options.featuredClass); + } + return (`<${itemTag}${classes.length > 0 ? ` class="${classes.join(' ')}"` : ''}${item.view ? ` data-view="${item.view}"` : '' }${item.title ? ` title="${item.title}"` : ''}${item.picked ? ' aria-selected="true"' : ''}>${item.text}`); } diff --git a/src/js/defaults.js b/src/js/defaults.js index bb7c398..24fd7ac 100644 --- a/src/js/defaults.js +++ b/src/js/defaults.js @@ -76,6 +76,9 @@ export default { // A class (CSS) for highlight date item highlightedClass: 'highlighted', + // A class (CSS) for featured date item + featuredClass: 'featured', + // The template of the datepicker template: ( '
                                                  ' diff --git a/src/js/methods.js b/src/js/methods.js index 5fbbd5a..ec6e2ce 100644 --- a/src/js/methods.js +++ b/src/js/methods.js @@ -278,6 +278,20 @@ export default { } }, + /** + * Sets the list of featured dates with a new list + * + * @param dates + */ + setFeaturedDates(dates) { + dates = Array.isArray(dates) ? dates : [dates]; + this.featuredDates = dates.map((date) => this.parseDate(date)); + + if (this.built) { + this.render(); + } + }, + /** * Parse a date string with the set date format * diff --git a/src/js/render.js b/src/js/render.js index 218dc6b..2df0b26 100644 --- a/src/js/render.js +++ b/src/js/render.js @@ -30,6 +30,7 @@ export default { options, startDate, endDate, + featuredDates, } = this; const { disabledClass, filter, yearSuffix } = options; const viewYear = this.viewDate.getFullYear(); @@ -46,6 +47,7 @@ export default { for (i = start; i <= end; i += 1) { const date = new Date(viewYear + i, 1, 1); let disabled = false; + let featured = false; if (startDate) { disabled = date.getFullYear() < startDate.getFullYear(); @@ -70,9 +72,21 @@ export default { const picked = (viewYear + i) === year; const view = picked ? 'year picked' : 'year'; + const featuredDateLowerLimit = date.getTime(); + const featuredDateUpperLimit = (new Date(viewYear + i + 1, 1, 1)).getTime(); + for (let j = 0; j < featuredDates.length; j += 1) { + const featuredDate = featuredDates[j]; + if (featuredDate.getTime() >= featuredDateLowerLimit + && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + items.push(this.createItem({ picked, disabled, + featured, text: viewYear + i, view: disabled ? 'year disabled' : view, highlighted: date.getFullYear() === thisYear, @@ -93,6 +107,7 @@ export default { startDate, endDate, viewDate, + featuredDates, } = this; const disabledClass = options.disabledClass || ''; const months = options.monthsShort; @@ -111,6 +126,7 @@ export default { for (i = 0; i <= 11; i += 1) { const date = new Date(viewYear, i, 1); let disabled = false; + let featured = false; if (startDate) { prevDisabled = date.getFullYear() === startDate.getFullYear(); @@ -126,6 +142,17 @@ export default { disabled = filter.call(this.$element, date, 'month') === false; } + const featuredDateLowerLimit = date.getTime(); + const featuredDateUpperLimit = (new Date(viewYear, i + 1, 1)).getTime(); + for (let j = 0; j < featuredDates.length; j += 1) { + const featuredDate = featuredDates[j]; + if (featuredDate.getTime() >= featuredDateLowerLimit + && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + const picked = viewYear === year && i === month; const view = picked ? 'month picked' : 'month'; @@ -133,6 +160,7 @@ export default { disabled, picked, highlighted: viewYear === thisYear && date.getMonth() === thisMonth, + featured, index: i, text: months[i], view: disabled ? 'month disabled' : view, @@ -155,6 +183,7 @@ export default { endDate, viewDate, date: currentDate, + featuredDates, } = this; const { disabledClass, @@ -299,6 +328,7 @@ export default { for (i = 1; i <= length; i += 1) { const date = new Date(viewYear, viewMonth, i); let disabled = false; + let featured = false; if (startDate) { disabled = date.getTime() < startDate.getTime(); @@ -312,6 +342,17 @@ export default { disabled = filter.call($element, date, 'day') === false; } + const featuredDateLowerLimit = date.getTime(); + const featuredDateUpperLimit = (new Date(viewYear, viewMonth, i + 1)).getTime(); + for (let j = 0; j < featuredDates.length; j += 1) { + const featuredDate = featuredDates[j]; + if (featuredDate.getTime() >= featuredDateLowerLimit + && featuredDate.getTime() < featuredDateUpperLimit) { + featured = true; + break; + } + } + const picked = viewYear === year && viewMonth === month && i === day; const view = picked ? 'day picked' : 'day'; @@ -323,6 +364,7 @@ export default { && viewMonth === thisMonth && date.getDate() === thisDay ), + featured, text: i, view: disabled ? 'day disabled' : view, })); diff --git a/test/methods/setFeaturedDates.js b/test/methods/setFeaturedDates.js new file mode 100644 index 0000000..85c990f --- /dev/null +++ b/test/methods/setFeaturedDates.js @@ -0,0 +1,8 @@ +QUnit.test('method.setFeaturedDates', function (assert) { + var $input = window.createInput(); + var featuredDates = [new Date(2014, 1, 14)]; + + $input.datepicker('setFeaturedDates', featuredDates); + assert.equal($input.data('datepicker').featuredDates.length, 1); + assert.equal($input.data('datepicker').featuredDates[0].getTime(), featuredDates[0].getTime()); +}); diff --git a/test/options/featuredDates.js b/test/options/featuredDates.js new file mode 100644 index 0000000..d23f3a2 --- /dev/null +++ b/test/options/featuredDates.js @@ -0,0 +1,22 @@ +QUnit.test('options.featuredDates', function (assert) { + var $input = window.createInput(); + var date = new Date(2014, 1, 1); + var featuredDates = [new Date(2014, 1, 14)]; + + var datepicker = $input.datepicker({ + date: date, + featuredDates: featuredDates + }).data('datepicker'); + + $input.datepicker('show'); + + datepicker.$days.children().each(function (i) { + if (i === 19) { + assert.ok($(this).hasClass(datepicker.options.featuredClass)); + } else { + assert.ok(!$(this).hasClass(datepicker.options.featuredClass)); + } + }); + + $input.datepicker('hide'); +});