diff --git a/README.md b/README.md
index d5f4668..be905ee 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,6 @@
- [Website](https://fengyuanchen.github.io/datepicker)
-
-
## Table of contents
- [Features](#features)
@@ -20,8 +18,6 @@
- [Versioning](#versioning)
- [License](#license)
-
-
## Features
- Supports [options](#options)
@@ -32,33 +28,25 @@
- Supports internationalization
- Cross-browser support
-
-
## Main
-```
+```text
dist/
-├── datepicker.css ( 4 KB)
-├── datepicker.min.css ( 4 KB)
-├── datepicker.js (40 KB)
-└── datepicker.min.js (16 KB)
+├── datepicker.css ( 5 KB)
+├── datepicker.min.css ( 4 KB)
+├── datepicker.js (40 KB, UMD)
+├── datepicker.min.js (18 KB, UMD, compressed)
+├── datepicker.common.js (40 KB, CommonJS, default)
+└── datepicker.esm.js (40 KB, ES Module)
```
-
-
## Getting started
-### Quick start
-
-Three quick start options are available:
-
-- [Download the latest release](https://github.com/fengyuanchen/datepicker/archive/master.zip).
-- Clone the repository: `git clone https://github.com/fengyuanchen/datepicker.git`.
-- Install with [NPM](http://npmjs.org): `npm install fengyuanchen/datepicker`.
-- Install with [Bower](http://bower.io): `bower install fengyuanchen/datepicker`.
+### Install
-
-### Installation
+```shell
+npm install @fengyuanchen/datepicker
+```
Include files:
@@ -68,7 +56,6 @@ Include files:
```
-
### Usage
Initialize with `$.fn.datepicker` method.
@@ -83,17 +70,13 @@ Initialize with `$.fn.datepicker` method.
$('[data-toggle="datepicker"]').datepicker();
```
-
[⬆ back to top](#table-of-contents)
-
-
## Options
You may set datepicker options with `$().datepicker(options)`.
If you want to change the global default options, You may use `$.fn.datepicker.setDefaults(options)`.
-
### autoShow
- Type: `Boolean`
@@ -101,7 +84,6 @@ If you want to change the global default options, You may use `$.fn.datepicker.s
Show the datepicker automatically when initialized.
-
### autoHide
- Type: `Boolean`
@@ -109,7 +91,6 @@ Show the datepicker automatically when initialized.
Hide the datepicker automatically when picked.
-
### autoPick
- Type: `Boolean`
@@ -117,7 +98,6 @@ Hide the datepicker automatically when picked.
Pick the initial date automatically when initialized.
-
### inline
- Type: `Boolean`
@@ -128,7 +108,6 @@ Enable inline mode.
If the element is not an input element, will append the datepicker to the element.
If the `container` option is set, will append the datepicker to the container.
-
### container
- Type: `Element` or `String`(selector)
@@ -138,7 +117,6 @@ A element for putting the datepicker. If not set, the datepicker will be appende
> Only works when the `inline` option set to `true`.
-
### trigger
- Type: `Element` or `String`(selector)
@@ -146,7 +124,6 @@ A element for putting the datepicker. If not set, the datepicker will be appende
A element for triggering the datepicker.
-
### language
- Type: `String`
@@ -160,7 +137,6 @@ $().datepicker({
});
```
-
### format
- Type: `String`
@@ -178,7 +154,6 @@ $().datepicker({
});
```
-
### date
- Type: `Date` or `String`
@@ -192,7 +167,6 @@ $().datepicker({
});
```
-
### startDate
- Type: `Date` or `String`
@@ -200,7 +174,6 @@ $().datepicker({
The start view date. All the dates before this date will be disabled.
-
### endDate
- Type: `Date` or `String`
@@ -208,7 +181,6 @@ The start view date. All the dates before this date will be disabled.
The end view date. All the dates after this date will be disabled.
-
### startView
- Type: `Number`
@@ -220,7 +192,6 @@ The end view date. All the dates after this date will be disabled.
The start view when initialized.
-
### weekStart
- Type: `Number`
@@ -236,7 +207,6 @@ The start view when initialized.
The start day of the week.
-
### yearFirst
- Type: `Boolean`
@@ -244,7 +214,6 @@ The start day of the week.
Show year before month on the datepicker header
-
### yearSuffix
- Type: `String`
@@ -265,7 +234,6 @@ $().datepicker({
Days' name of the week.
-
### daysShort
- Type: `Array`
@@ -273,7 +241,6 @@ Days' name of the week.
Shorter days' name.
-
### daysMin
- Type: `Array`
@@ -281,7 +248,6 @@ Shorter days' name.
Shortest days' name.
-
### months
- Type: `Array`
@@ -289,7 +255,6 @@ Shortest days' name.
Months' name.
-
### monthsShort
- Type: `Array`
@@ -297,7 +262,6 @@ Months' name.
Shorter months' name.
-
### itemTag
- Type: `String`
@@ -305,7 +269,6 @@ Shorter months' name.
A element tag for each item of years, months and days.
-
### mutedClass
- Type: `String`
@@ -313,7 +276,6 @@ A element tag for each item of years, months and days.
A class (CSS) for muted item.
-
### pickedClass
- Type: `String`
@@ -321,7 +283,6 @@ A class (CSS) for muted item.
A class (CSS) for picked item.
-
### disabledClass
- Type: `String`
@@ -329,7 +290,6 @@ A class (CSS) for picked item.
A class (CSS) for disabled item.
-
### highlightedClass
- Type: `String`
@@ -337,7 +297,6 @@ A class (CSS) for disabled item.
A class (CSS) for highlight date item.
-
### template
- Type: `String`
@@ -377,7 +336,6 @@ The template of the datepicker.
**Note:** All the `data-view` attributes must be set when you customize it.
-
### offset
- Type: `Number`
@@ -385,7 +343,6 @@ The template of the datepicker.
The offset top or bottom of the datepicker from the element.
-
### zIndex
- Type: `Number`
@@ -393,7 +350,6 @@ The offset top or bottom of the datepicker from the element.
The CSS `z-index` style for the datepicker.
-
### filter
- Type: `Function`
@@ -413,7 +369,6 @@ $().datepicker({
});
```
-
### show
- Type: `Function`
@@ -421,7 +376,6 @@ $().datepicker({
A shortcut of the "show.datepicker" event.
-
### hide
- Type: `Function`
@@ -429,7 +383,6 @@ A shortcut of the "show.datepicker" event.
A shortcut of the "hide.datepicker" event.
-
### pick
- Type: `Function`
@@ -437,11 +390,8 @@ A shortcut of the "hide.datepicker" event.
A shortcut of the "pick.datepicker" event.
-
[⬆ back to top](#table-of-contents)
-
-
## Methods
Common usage:
@@ -450,32 +400,26 @@ Common usage:
$().datepicker('method', argument1, , argument2, ..., argumentN);
```
-
### show()
Show the datepicker.
-
### hide()
Hide the datepicker.
-
### update()
Update the datepicker with the value or text of the current element.
-
### pick()
Pick the current date to the element.
-
### reset()
Reset the datepicker.
-
### getMonthName([month[, short]])
- **month** (optional):
@@ -499,7 +443,6 @@ $().datepicker('getMonthName', 11); // 'December'
$().datepicker('getMonthName', 11, true); // 'Dec'
```
-
### getDayName([day[, short[, min]])
- **day** (optional):
@@ -530,7 +473,6 @@ $().datepicker('getDayName', 6, true); // 'Sat'
$().datepicker('getDayName', 6, true, true); // 'Sa'
```
-
### getDate([formatted])
- **formatted** (optional):
@@ -548,7 +490,6 @@ $().datepicker('getDate'); // date object
$().datepicker('getDate', true); // '02/14/2014'
```
-
### setDate(date)
- **date**:
@@ -561,7 +502,6 @@ $().datepicker('setDate', new Date(2014, 1, 14));
$().datepicker('setDate', '02/14/2014');
```
-
### setStartDate(date)
- **date**:
@@ -569,7 +509,6 @@ $().datepicker('setDate', '02/14/2014');
Set the start view date with a new date.
-
### setEndDate(date)
- **date**:
@@ -577,7 +516,6 @@ Set the start view date with a new date.
Set the end view date with a new date.
-
### parseDate(date)
- **date**:
@@ -589,7 +527,6 @@ Parse a date string with the set date format.
$().datepicker('parseDate', '02/14/2014'); // date object
```
-
### formatDate(date)
- **date**:
@@ -601,28 +538,22 @@ Format a date object to a string with the set date format.
$().datepicker('formatDate', new Date(2014, 1, 14)); // '02/14/2014'
```
-
### destroy()
Destroy the datepicker and remove the instance from the target element.
-
[⬆ back to top](#table-of-contents)
-
-
## Events
### show.datepicker
This event fires when starts to show the datepicker.
-
### hide.datepicker
This event fires when starts to hide the datepicker.
-
### pick.datepicker
- **event.date**:
@@ -645,15 +576,10 @@ $().on('pick.datepicker', function (e) {
});
```
-
[⬆ back to top](#table-of-contents)
-
-
## I18n
-### Config
-
```js
// datepicker.zh-CN.js
$.fn.datepicker.languages['zh-CN'] = {
@@ -670,8 +596,6 @@ $.fn.datepicker.languages['zh-CN'] = {
};
```
-### Usage
-
```html
@@ -682,11 +606,8 @@ $.fn.datepicker.languages['zh-CN'] = {
```
-
[⬆ back to top](#table-of-contents)
-
-
## No conflict
If you have to use other plugin with the same namespace, just call the `$.fn.datepicker.noConflict` method to revert to it.
@@ -700,8 +621,6 @@ If you have to use other plugin with the same namespace, just call the `$.fn.dat
```
-
-
## Browser support
- Chrome (latest 2)
@@ -713,17 +632,12 @@ If you have to use other plugin with the same namespace, just call the `$.fn.dat
As a jQuery plugin, you also need to see the [jQuery Browser Support](http://jquery.com/browser-support/).
-
-
## Versioning
Maintained under the [Semantic Versioning guidelines](http://semver.org/).
-
-
## License
[MIT](http://opensource.org/licenses/MIT) © [Fengyuan Chen](http://chenfengyuan.com)
-
[⬆ back to top](#table-of-contents)
diff --git a/dist/datepicker.common.js b/dist/datepicker.common.js
new file mode 100644
index 0000000..28172d2
--- /dev/null
+++ b/dist/datepicker.common.js
@@ -0,0 +1,1513 @@
+/*!
+ * Datepicker v0.6.0
+ * https://github.com/fengyuanchen/datepicker
+ *
+ * Copyright (c) 2014-2017 Fengyuan Chen
+ * Released under the MIT license
+ *
+ * Date: 2017-09-24T11:42:13.421Z
+ */
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var $ = _interopDefault(require('jquery'));
+
+var DEFAULTS = {
+ // Show the datepicker automatically when initialized
+ autoShow: false,
+
+ // Hide the datepicker automatically when picked
+ autoHide: false,
+
+ // Pick the initial date automatically when initialized
+ autoPick: false,
+
+ // Enable inline mode
+ inline: false,
+
+ // A element (or selector) for putting the datepicker
+ container: null,
+
+ // A element (or selector) for triggering the datepicker
+ trigger: null,
+
+ // The ISO language code (built-in: en-US)
+ language: '',
+
+ // The date string format
+ format: 'mm/dd/yyyy',
+
+ // The initial date
+ date: null,
+
+ // The start view date
+ startDate: null,
+
+ // The end view date
+ endDate: null,
+
+ // The start view when initialized
+ startView: 0, // 0 for days, 1 for months, 2 for years
+
+ // The start day of the week
+ // 0 for Sunday, 1 for Monday, 2 for Tuesday, 3 for Wednesday,
+ // 4 for Thursday, 5 for Friday, 6 for Saturday
+ weekStart: 0,
+
+ // Show year before month on the datepicker header
+ yearFirst: false,
+
+ // A string suffix to the year number.
+ yearSuffix: '',
+
+ // Days' name of the week.
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+
+ // Shorter days' name
+ daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+
+ // Shortest days' name
+ daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
+
+ // Months' name
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+
+ // Shorter months' name
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+
+ // A element tag for each item of years, months and days
+ itemTag: 'li',
+
+ // A class (CSS) for muted date item
+ mutedClass: 'muted',
+
+ // A class (CSS) for picked date item
+ pickedClass: 'picked',
+
+ // A class (CSS) for disabled date item
+ disabledClass: 'disabled',
+
+ // A class (CSS) for highlight date item
+ highlightedClass: 'highlighted',
+
+ // The template of the datepicker
+ template: '
',
+
+ // The offset top or bottom of the datepicker from the element
+ offset: 10,
+
+ // The `z-index` of the datepicker
+ zIndex: 1000,
+
+ // Filter each date item (return `false` to disable a date item)
+ filter: null,
+
+ // Event shortcuts
+ show: null,
+ hide: null,
+ pick: null
+};
+
+var NAMESPACE = 'datepicker';
+var EVENT_CLICK = 'click.' + NAMESPACE;
+var EVENT_FOCUS = 'focus.' + NAMESPACE;
+var EVENT_HIDE = 'hide.' + NAMESPACE;
+var EVENT_KEYUP = 'keyup.' + NAMESPACE;
+var EVENT_PICK = 'pick.' + NAMESPACE;
+var EVENT_RESIZE = 'resize.' + NAMESPACE;
+var EVENT_SHOW = 'show.' + NAMESPACE;
+var CLASS_HIDE = NAMESPACE + '-hide';
+var LANGUAGES = {};
+var VIEWS = {
+ DAYS: 0,
+ MONTHS: 1,
+ YEARS: 2
+};
+
+var toString = Object.prototype.toString;
+
+
+function typeOf(obj) {
+ return toString.call(obj).slice(8, -1).toLowerCase();
+}
+
+function isString(value) {
+ return typeof value === 'string';
+}
+
+var isNaN = Number.isNaN || window.isNaN;
+
+function isNumber(value) {
+ return typeof value === 'number' && !isNaN(value);
+}
+
+function isUndefined(value) {
+ return typeof value === 'undefined';
+}
+
+function isDate(value) {
+ return typeOf(value) === 'date';
+}
+
+function proxy(fn, context) {
+ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
+ }
+
+ return function () {
+ for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args2[_key2] = arguments[_key2];
+ }
+
+ return fn.apply(context, args.concat(args2));
+ };
+}
+
+function selectorOf(view) {
+ return '[data-view="' + view + '"]';
+}
+
+function isLeapYear(year) {
+ return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
+}
+
+function getDaysInMonth(year, month) {
+ return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
+}
+
+function getMinDay(year, month, day) {
+ return Math.min(day, getDaysInMonth(year, month));
+}
+
+var formatParts = /(y|m|d)+/g;
+
+function parseFormat(format) {
+ var source = String(format).toLowerCase();
+ var parts = source.match(formatParts);
+
+ if (!parts || parts.length === 0) {
+ throw new Error('Invalid date format.');
+ }
+
+ format = {
+ source: source,
+ parts: parts
+ };
+
+ $.each(parts, function (i, part) {
+ switch (part) {
+ case 'dd':
+ case 'd':
+ format.hasDay = true;
+ break;
+
+ case 'mm':
+ case 'm':
+ format.hasMonth = true;
+ break;
+
+ case 'yyyy':
+ case 'yy':
+ format.hasYear = true;
+ break;
+
+ default:
+ }
+ });
+
+ return format;
+}
+
+var _window$1 = window;
+var document$2 = _window$1.document;
+
+var $window = $(window);
+var $document$1 = $(document$2);
+var REGEXP_DIGITS = /\d+/g;
+
+var methods = {
+ // Show the datepicker
+ show: function show() {
+ if (!this.built) {
+ this.build();
+ }
+
+ if (this.shown) {
+ return;
+ }
+
+ if (this.trigger(EVENT_SHOW).isDefaultPrevented()) {
+ return;
+ }
+
+ this.shown = true;
+ this.$picker.removeClass(CLASS_HIDE).on(EVENT_CLICK, $.proxy(this.click, this));
+ this.showView(this.options.startView);
+
+ if (!this.inline) {
+ $window.on(EVENT_RESIZE, this.onResize = proxy(this.place, this));
+ $document$1.on(EVENT_CLICK, this.onGlobalClick = proxy(this.globalClick, this));
+ $document$1.on(EVENT_KEYUP, this.onGlobalKeyup = proxy(this.globalKeyup, this));
+ this.place();
+ }
+ },
+
+
+ // Hide the datepicker
+ hide: function hide() {
+ if (!this.shown) {
+ return;
+ }
+
+ if (this.trigger(EVENT_HIDE).isDefaultPrevented()) {
+ return;
+ }
+
+ this.shown = false;
+ this.$picker.addClass(CLASS_HIDE).off(EVENT_CLICK, this.click);
+
+ if (!this.inline) {
+ $window.off(EVENT_RESIZE, this.onResize);
+ $document$1.off(EVENT_CLICK, this.onGlobalClick);
+ $document$1.off(EVENT_KEYUP, this.onGlobalKeyup);
+ }
+ },
+ toggle: function toggle() {
+ if (this.shown) {
+ this.hide();
+ } else {
+ this.show();
+ }
+ },
+
+
+ // Update the datepicker with the current input value
+ update: function update() {
+ var value = this.getValue();
+
+ if (value === this.oldValue) {
+ return;
+ }
+
+ this.setDate(value, true);
+ this.oldValue = value;
+ },
+
+
+ /**
+ * Pick the current date to the element
+ *
+ * @param {String} _view (private)
+ */
+ pick: function pick(_view) {
+ var $this = this.$element;
+ var date = this.date;
+
+
+ if (this.trigger(EVENT_PICK, {
+ view: _view || '',
+ date: date
+ }).isDefaultPrevented()) {
+ return;
+ }
+
+ date = this.formatDate(this.date);
+ this.setValue(date);
+
+ if (this.isInput) {
+ $this.trigger('input');
+ $this.trigger('change');
+ }
+ },
+
+
+ // Reset the datepicker
+ reset: function reset() {
+ this.setDate(this.initialDate, true);
+ this.setValue(this.initialValue);
+
+ if (this.shown) {
+ this.showView(this.options.startView);
+ }
+ },
+
+
+ /**
+ * Get the month name with given argument or the current date
+ *
+ * @param {Number} month (optional)
+ * @param {Boolean} short (optional)
+ * @return {String} (month name)
+ */
+ getMonthName: function getMonthName(month, short) {
+ var options = this.options;
+ var monthsShort = options.monthsShort;
+ var months = options.months;
+
+
+ if ($.isNumeric(month)) {
+ month = Number(month);
+ } else if (isUndefined(short)) {
+ short = month;
+ }
+
+ if (short === true) {
+ months = monthsShort;
+ }
+
+ return months[isNumber(month) ? month : this.date.getMonth()];
+ },
+
+
+ /**
+ * Get the day name with given argument or the current date
+ *
+ * @param {Number} day (optional)
+ * @param {Boolean} short (optional)
+ * @param {Boolean} min (optional)
+ * @return {String} (day name)
+ */
+ getDayName: function getDayName(day, short, min) {
+ var options = this.options;
+ var days = options.days;
+
+
+ if ($.isNumeric(day)) {
+ day = Number(day);
+ } else {
+ if (isUndefined(min)) {
+ min = short;
+ }
+
+ if (isUndefined(short)) {
+ short = day;
+ }
+ }
+
+ if (min) {
+ days = options.daysMin;
+ } else if (short) {
+ days = options.daysShort;
+ }
+
+ return days[isNumber(day) ? day : this.date.getDay()];
+ },
+
+
+ /**
+ * Get the current date
+ *
+ * @param {Boolean} formatted (optional)
+ * @return {Date|String} (date)
+ */
+ getDate: function getDate(formatted) {
+ var date = this.date;
+
+
+ return formatted ? this.formatDate(date) : new Date(date);
+ },
+
+
+ /**
+ * Set the current date with a new date
+ *
+ * @param {Date} date
+ * @param {Boolean} _updated (private)
+ */
+ setDate: function setDate(date, _updated) {
+ var filter = this.options.filter;
+
+
+ if (isDate(date) || isString(date)) {
+ date = this.parseDate(date);
+
+ if ($.isFunction(filter) && filter.call(this.$element, date) === false) {
+ return;
+ }
+
+ this.date = date;
+ this.viewDate = new Date(date);
+
+ if (!_updated) {
+ this.pick();
+ }
+
+ if (this.built) {
+ this.render();
+ }
+ }
+ },
+
+
+ /**
+ * Set the start view date with a new date
+ *
+ * @param {Date} date
+ */
+ setStartDate: function setStartDate(date) {
+ if (isDate(date) || isString(date)) {
+ this.startDate = this.parseDate(date);
+
+ if (this.built) {
+ this.render();
+ }
+ }
+ },
+
+
+ /**
+ * Set the end view date with a new date
+ *
+ * @param {Date} date
+ */
+ setEndDate: function setEndDate(date) {
+ if (isDate(date) || isString(date)) {
+ this.endDate = this.parseDate(date);
+
+ if (this.built) {
+ this.render();
+ }
+ }
+ },
+
+
+ /**
+ * Parse a date string with the set date format
+ *
+ * @param {String} date
+ * @return {Date} (parsed date)
+ */
+ parseDate: function parseDate(date) {
+ var format = this.format;
+
+ var parts = [];
+
+ if (isDate(date)) {
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
+ } else if (isString(date)) {
+ parts = date.match(REGEXP_DIGITS) || [];
+ }
+
+ date = new Date();
+
+ var length = format.parts.length;
+
+ var year = date.getFullYear();
+ var day = date.getDate();
+ var month = date.getMonth();
+
+ if (parts.length === length) {
+ $.each(parts, function (i, part) {
+ var value = parseInt(part, 10) || 1;
+
+ switch (format.parts[i]) {
+ case 'dd':
+ case 'd':
+ day = value;
+ break;
+
+ case 'mm':
+ case 'm':
+ month = value - 1;
+ break;
+
+ case 'yy':
+ year = 2000 + value;
+ break;
+
+ case 'yyyy':
+ year = value;
+ break;
+
+ default:
+ }
+ });
+ }
+
+ return new Date(year, month, day);
+ },
+
+
+ /**
+ * Format a date object to a string with the set date format
+ *
+ * @param {Date} date
+ * @return {String} (formatted date)
+ */
+ formatDate: function formatDate(date) {
+ var format = this.format;
+
+ var formatted = '';
+
+ if (isDate(date)) {
+ var year = date.getFullYear();
+ var values = {
+ d: date.getDate(),
+ m: date.getMonth() + 1,
+ yy: year.toString().substring(2),
+ yyyy: year
+ };
+
+ values.dd = (values.d < 10 ? '0' : '') + values.d;
+ values.mm = (values.m < 10 ? '0' : '') + values.m;
+ formatted = format.source;
+ $.each(format.parts, function (i, part) {
+ formatted = formatted.replace(part, values[part]);
+ });
+ }
+
+ return formatted;
+ },
+
+
+ // Destroy the datepicker and remove the instance from the target element
+ destroy: function destroy() {
+ this.unbind();
+ this.unbuild();
+ this.$element.removeData(NAMESPACE);
+ }
+};
+
+var handlers = {
+ click: function click(e) {
+ var $target = $(e.target);
+ var options = this.options,
+ viewDate = this.viewDate,
+ format = this.format;
+
+
+ e.stopPropagation();
+ e.preventDefault();
+
+ if ($target.hasClass('disabled')) {
+ return;
+ }
+
+ var view = $target.data('view');
+ var viewYear = viewDate.getFullYear();
+ var viewMonth = viewDate.getMonth();
+ var viewDay = viewDate.getDate();
+
+ switch (view) {
+ case 'years prev':
+ case 'years next':
+ {
+ viewYear = view === 'years prev' ? viewYear - 10 : viewYear + 10;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderYears();
+ break;
+ }
+
+ case 'year prev':
+ case 'year next':
+ viewYear = view === 'year prev' ? viewYear - 1 : viewYear + 1;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderMonths();
+ break;
+
+ case 'year current':
+ if (format.hasYear) {
+ this.showView(VIEWS.YEARS);
+ }
+
+ break;
+
+ case 'year picked':
+ if (format.hasMonth) {
+ this.showView(VIEWS.MONTHS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
+
+ this.pick('year');
+ break;
+
+ case 'year':
+ viewYear = parseInt($target.text(), 10);
+ this.date = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+
+ if (format.hasMonth) {
+ this.viewDate = new Date(this.date);
+ this.showView(VIEWS.MONTHS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
+
+ this.pick('year');
+ break;
+
+ case 'month prev':
+ case 'month next':
+ viewMonth = view === 'month prev' ? viewMonth - 1 : viewMonth + 1;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderDays();
+ break;
+
+ case 'month current':
+ if (format.hasMonth) {
+ this.showView(VIEWS.MONTHS);
+ }
+
+ break;
+
+ case 'month picked':
+ if (format.hasDay) {
+ this.showView(VIEWS.DAYS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
+
+ this.pick('month');
+ break;
+
+ case 'month':
+ viewMonth = $.inArray($target.text(), options.monthsShort);
+ this.date = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+
+ if (format.hasDay) {
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.showView(VIEWS.DAYS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
+
+ this.pick('month');
+ break;
+
+ case 'day prev':
+ case 'day next':
+ case 'day':
+ if (view === 'day prev') {
+ viewMonth -= 1;
+ } else if (view === 'day next') {
+ viewMonth += 1;
+ }
+
+ viewDay = parseInt($target.text(), 10);
+ this.date = new Date(viewYear, viewMonth, viewDay);
+ this.viewDate = new Date(viewYear, viewMonth, viewDay);
+ this.renderDays();
+
+ if (view === 'day') {
+ this.hideView();
+ }
+
+ this.pick('day');
+ break;
+
+ case 'day picked':
+ this.hideView();
+ this.pick('day');
+ break;
+
+ default:
+ }
+ },
+ globalClick: function globalClick(_ref) {
+ var target = _ref.target;
+ var element = this.element,
+ $trigger = this.$trigger;
+
+ var trigger = $trigger[0];
+ var hidden = true;
+
+ while (target !== document) {
+ if (target === trigger || target === element) {
+ hidden = false;
+ break;
+ }
+
+ target = target.parentNode;
+ }
+
+ if (hidden) {
+ this.hide();
+ }
+ },
+ keyup: function keyup() {
+ this.update();
+ },
+ globalKeyup: function globalKeyup(_ref2) {
+ var target = _ref2.target,
+ key = _ref2.key,
+ keyCode = _ref2.keyCode;
+
+ if (this.isInput && target !== this.element && this.shown && (key === 'Tab' || keyCode === 9)) {
+ this.hide();
+ }
+ }
+};
+
+var render = {
+ render: function render() {
+ this.renderYears();
+ this.renderMonths();
+ this.renderDays();
+ },
+ renderWeek: function renderWeek() {
+ var _this = this;
+
+ var items = [];
+ var _options = this.options,
+ weekStart = _options.weekStart,
+ daysMin = _options.daysMin;
+
+
+ weekStart = parseInt(weekStart, 10) % 7;
+ daysMin = daysMin.slice(weekStart).concat(daysMin.slice(0, weekStart));
+ $.each(daysMin, function (i, day) {
+ items.push(_this.createItem({
+ text: day
+ }));
+ });
+
+ this.$week.html(items.join(''));
+ },
+ renderYears: function renderYears() {
+ var options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate;
+ var disabledClass = options.disabledClass,
+ filter = options.filter,
+ yearSuffix = options.yearSuffix;
+
+ var viewYear = this.viewDate.getFullYear();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var year = this.date.getFullYear();
+ var start = -5;
+ var end = 6;
+ var items = [];
+ var prevDisabled = false;
+ var nextDisabled = false;
+ var i = void 0;
+
+ for (i = start; i <= end; i += 1) {
+ var date = new Date(viewYear + i, 1, 1);
+ var disabled = false;
+
+ if (startDate) {
+ disabled = date.getFullYear() < startDate.getFullYear();
+
+ if (i === start) {
+ prevDisabled = disabled;
+ }
+ }
+
+ if (!disabled && endDate) {
+ disabled = date.getFullYear() > endDate.getFullYear();
+
+ if (i === end) {
+ nextDisabled = disabled;
+ }
+ }
+
+ if (!disabled && filter) {
+ disabled = filter.call(this.$element, date) === false;
+ }
+
+ var picked = viewYear + i === year;
+ var view = picked ? 'year picked' : 'year';
+
+ items.push(this.createItem({
+ picked: picked,
+ disabled: disabled,
+ muted: i === start || i === end,
+ text: viewYear + i,
+ view: disabled ? 'year disabled' : view,
+ highlighted: date.getFullYear() === thisYear
+ }));
+ }
+
+ this.$yearsPrev.toggleClass(disabledClass, prevDisabled);
+ this.$yearsNext.toggleClass(disabledClass, nextDisabled);
+ this.$yearsCurrent.toggleClass(disabledClass, true).html(viewYear + start + yearSuffix + ' - ' + (viewYear + end) + yearSuffix);
+ this.$years.html(items.join(''));
+ },
+ renderMonths: function renderMonths() {
+ var options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate,
+ viewDate = this.viewDate;
+
+ var disabledClass = options.disabledClass || '';
+ var months = options.monthsShort;
+ var filter = $.isFunction(options.filter) && options.filter;
+ var viewYear = viewDate.getFullYear();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var thisMonth = now.getMonth();
+ var year = this.date.getFullYear();
+ var month = this.date.getMonth();
+ var items = [];
+ var prevDisabled = false;
+ var nextDisabled = false;
+ var i = void 0;
+
+ for (i = 0; i <= 11; i += 1) {
+ var date = new Date(viewYear, i, 1);
+ var disabled = false;
+
+ if (startDate) {
+ prevDisabled = date.getFullYear() === startDate.getFullYear();
+ disabled = prevDisabled && date.getMonth() < startDate.getMonth();
+ }
+
+ if (!disabled && endDate) {
+ nextDisabled = date.getFullYear() === endDate.getFullYear();
+ disabled = nextDisabled && date.getMonth() > endDate.getMonth();
+ }
+
+ if (!disabled && filter) {
+ disabled = filter.call(this.$element, date) === false;
+ }
+
+ 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,
+ index: i,
+ text: months[i],
+ view: disabled ? 'month disabled' : view
+ }));
+ }
+
+ this.$yearPrev.toggleClass(disabledClass, prevDisabled);
+ this.$yearNext.toggleClass(disabledClass, nextDisabled);
+ this.$yearCurrent.toggleClass(disabledClass, prevDisabled && nextDisabled).html(viewYear + options.yearSuffix || '');
+ this.$months.html(items.join(''));
+ },
+ renderDays: function renderDays() {
+ var $element = this.$element,
+ options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate,
+ viewDate = this.viewDate,
+ currentDate = this.date;
+ var disabledClass = options.disabledClass,
+ filter = options.filter,
+ monthsShort = options.monthsShort,
+ weekStart = options.weekStart,
+ yearSuffix = options.yearSuffix;
+
+ var viewYear = viewDate.getFullYear();
+ var viewMonth = viewDate.getMonth();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var thisMonth = now.getMonth();
+ var thisDay = now.getDate();
+ var year = currentDate.getFullYear();
+ var month = currentDate.getMonth();
+ var day = currentDate.getDate();
+ var length = void 0;
+ var i = void 0;
+ var n = void 0;
+
+ // Days of prev month
+ // -----------------------------------------------------------------------
+
+ var prevItems = [];
+ var prevViewYear = viewYear;
+ var prevViewMonth = viewMonth;
+ var prevDisabled = false;
+
+ if (viewMonth === 0) {
+ prevViewYear -= 1;
+ prevViewMonth = 11;
+ } else {
+ prevViewMonth -= 1;
+ }
+
+ // The length of the days of prev month
+ length = getDaysInMonth(prevViewYear, prevViewMonth);
+
+ // The first day of current month
+ var firstDay = new Date(viewYear, viewMonth, 1);
+
+ // The visible length of the days of prev month
+ // [0,1,2,3,4,5,6] - [0,1,2,3,4,5,6] => [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6]
+ n = firstDay.getDay() - parseInt(weekStart, 10) % 7;
+
+ // [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6] => [1,2,3,4,5,6,7]
+ if (n <= 0) {
+ n += 7;
+ }
+
+ if (startDate) {
+ prevDisabled = firstDay.getTime() <= startDate.getTime();
+ }
+
+ for (i = length - (n - 1); i <= length; i += 1) {
+ var prevViewDate = new Date(prevViewYear, prevViewMonth, i);
+ var disabled = false;
+
+ if (startDate) {
+ disabled = prevViewDate.getTime() < startDate.getTime();
+ }
+
+ if (!disabled && filter) {
+ disabled = filter.call($element, prevViewDate) === false;
+ }
+
+ prevItems.push(this.createItem({
+ disabled: disabled,
+ highlighted: prevViewYear === thisYear && prevViewMonth === thisMonth && prevViewDate.getDate() === thisDay,
+ muted: true,
+ picked: prevViewYear === year && prevViewMonth === month && i === day,
+ text: i,
+ view: 'day prev'
+ }));
+ }
+
+ // Days of next month
+ // -----------------------------------------------------------------------
+
+ var nextItems = [];
+ var nextViewYear = viewYear;
+ var nextViewMonth = viewMonth;
+ var nextDisabled = false;
+
+ if (viewMonth === 11) {
+ nextViewYear += 1;
+ nextViewMonth = 0;
+ } else {
+ nextViewMonth += 1;
+ }
+
+ // The length of the days of current month
+ length = getDaysInMonth(viewYear, viewMonth);
+
+ // The visible length of next month (42 means 6 rows and 7 columns)
+ n = 42 - (prevItems.length + length);
+
+ // The last day of current month
+ var lastDate = new Date(viewYear, viewMonth, length);
+
+ if (endDate) {
+ nextDisabled = lastDate.getTime() >= endDate.getTime();
+ }
+
+ for (i = 1; i <= n; i += 1) {
+ var date = new Date(nextViewYear, nextViewMonth, i);
+ var picked = nextViewYear === year && nextViewMonth === month && i === day;
+ var _disabled = false;
+
+ if (endDate) {
+ _disabled = date.getTime() > endDate.getTime();
+ }
+
+ if (!_disabled && filter) {
+ _disabled = filter.call($element, date) === false;
+ }
+
+ nextItems.push(this.createItem({
+ disabled: _disabled,
+ picked: picked,
+ highlighted: nextViewYear === thisYear && nextViewMonth === thisMonth && date.getDate() === thisDay,
+ muted: true,
+ text: i,
+ view: 'day next'
+ }));
+ }
+
+ // Days of current month
+ // -----------------------------------------------------------------------
+
+ var items = [];
+
+ for (i = 1; i <= length; i += 1) {
+ var _date = new Date(viewYear, viewMonth, i);
+ var _disabled2 = false;
+
+ if (startDate) {
+ _disabled2 = _date.getTime() < startDate.getTime();
+ }
+
+ if (!_disabled2 && endDate) {
+ _disabled2 = _date.getTime() > endDate.getTime();
+ }
+
+ if (!_disabled2 && filter) {
+ _disabled2 = filter.call($element, _date) === false;
+ }
+
+ var _picked = viewYear === year && viewMonth === month && i === day;
+ var view = _picked ? 'day picked' : 'day';
+
+ items.push(this.createItem({
+ disabled: _disabled2,
+ picked: _picked,
+ highlighted: viewYear === thisYear && viewMonth === thisMonth && _date.getDate() === thisDay,
+ text: i,
+ view: _disabled2 ? 'day disabled' : view
+ }));
+ }
+
+ // Render days picker
+ // -----------------------------------------------------------------------
+
+ this.$monthPrev.toggleClass(disabledClass, prevDisabled);
+ this.$monthNext.toggleClass(disabledClass, nextDisabled);
+ this.$monthCurrent.toggleClass(disabledClass, prevDisabled && nextDisabled).html(options.yearFirst ? viewYear + yearSuffix + ' ' + monthsShort[viewMonth] : monthsShort[viewMonth] + ' ' + viewYear + yearSuffix);
+ this.$days.html(prevItems.join('') + items.join('') + nextItems.join(''));
+ }
+};
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var _window = window;
+var document$1 = _window.document;
+
+var $document = $(document$1);
+
+// Classes
+var CLASS_TOP_LEFT = NAMESPACE + '-top-left';
+var CLASS_TOP_RIGHT = NAMESPACE + '-top-right';
+var CLASS_BOTTOM_LEFT = NAMESPACE + '-bottom-left';
+var CLASS_BOTTOM_RIGHT = NAMESPACE + '-bottom-right';
+var CLASS_PLACEMENTS = [CLASS_TOP_LEFT, CLASS_TOP_RIGHT, CLASS_BOTTOM_LEFT, CLASS_BOTTOM_RIGHT].join(' ');
+
+var Datepicker = function () {
+ function Datepicker(element) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ _classCallCheck(this, Datepicker);
+
+ this.$element = $(element);
+ this.element = element;
+ this.options = $.extend({}, DEFAULTS, LANGUAGES[options.language], options);
+ this.built = false;
+ this.shown = false;
+ this.isInput = false;
+ this.inline = false;
+ this.initialValue = '';
+ this.initialDate = null;
+ this.startDate = null;
+ this.endDate = null;
+ this.init();
+ }
+
+ _createClass(Datepicker, [{
+ key: 'init',
+ value: function init() {
+ var $this = this.$element,
+ options = this.options;
+ var startDate = options.startDate,
+ endDate = options.endDate,
+ date = options.date;
+
+
+ this.$trigger = $(options.trigger);
+ this.isInput = $this.is('input') || $this.is('textarea');
+ this.inline = options.inline && (options.container || !this.isInput);
+ this.format = parseFormat(options.format);
+
+ var initialValue = this.getValue();
+
+ this.initialValue = initialValue;
+ this.oldValue = initialValue;
+ date = this.parseDate(date || initialValue);
+
+ if (startDate) {
+ startDate = this.parseDate(startDate);
+
+ if (date.getTime() < startDate.getTime()) {
+ date = new Date(startDate);
+ }
+
+ this.startDate = startDate;
+ }
+
+ if (endDate) {
+ endDate = this.parseDate(endDate);
+
+ if (startDate && endDate.getTime() < startDate.getTime()) {
+ endDate = new Date(startDate);
+ }
+
+ if (date.getTime() > endDate.getTime()) {
+ date = new Date(endDate);
+ }
+
+ this.endDate = endDate;
+ }
+
+ this.date = date;
+ this.viewDate = new Date(date);
+ this.initialDate = new Date(this.date);
+ this.bind();
+
+ if (options.autoShow || this.inline) {
+ this.show();
+ }
+
+ if (options.autoPick) {
+ this.pick();
+ }
+ }
+ }, {
+ key: 'build',
+ value: function build() {
+ if (this.built) {
+ return;
+ }
+
+ this.built = true;
+
+ var $this = this.$element,
+ options = this.options;
+
+ var $picker = $(options.template);
+
+ this.$picker = $picker;
+ this.$week = $picker.find(selectorOf('week'));
+
+ // Years view
+ this.$yearsPicker = $picker.find(selectorOf('years picker'));
+ this.$yearsPrev = $picker.find(selectorOf('years prev'));
+ this.$yearsNext = $picker.find(selectorOf('years next'));
+ this.$yearsCurrent = $picker.find(selectorOf('years current'));
+ this.$years = $picker.find(selectorOf('years'));
+
+ // Months view
+ this.$monthsPicker = $picker.find(selectorOf('months picker'));
+ this.$yearPrev = $picker.find(selectorOf('year prev'));
+ this.$yearNext = $picker.find(selectorOf('year next'));
+ this.$yearCurrent = $picker.find(selectorOf('year current'));
+ this.$months = $picker.find(selectorOf('months'));
+
+ // Days view
+ this.$daysPicker = $picker.find(selectorOf('days picker'));
+ this.$monthPrev = $picker.find(selectorOf('month prev'));
+ this.$monthNext = $picker.find(selectorOf('month next'));
+ this.$monthCurrent = $picker.find(selectorOf('month current'));
+ this.$days = $picker.find(selectorOf('days'));
+
+ if (this.inline) {
+ $(options.container || $this).append($picker.addClass(NAMESPACE + '-inline'));
+ } else {
+ $(document$1.body).append($picker.addClass(NAMESPACE + '-dropdown'));
+ $picker.addClass(CLASS_HIDE);
+ }
+
+ this.renderWeek();
+ }
+ }, {
+ key: 'unbuild',
+ value: function unbuild() {
+ if (!this.built) {
+ return;
+ }
+
+ this.built = false;
+ this.$picker.remove();
+ }
+ }, {
+ key: 'bind',
+ value: function bind() {
+ var options = this.options,
+ $this = this.$element;
+
+
+ if ($.isFunction(options.show)) {
+ $this.on(EVENT_SHOW, options.show);
+ }
+
+ if ($.isFunction(options.hide)) {
+ $this.on(EVENT_HIDE, options.hide);
+ }
+
+ if ($.isFunction(options.pick)) {
+ $this.on(EVENT_PICK, options.pick);
+ }
+
+ if (this.isInput) {
+ $this.on(EVENT_KEYUP, $.proxy(this.keyup, this));
+ }
+
+ if (!this.inline) {
+ if (options.trigger) {
+ this.$trigger.on(EVENT_CLICK, $.proxy(this.toggle, this));
+ } else if (this.isInput) {
+ $this.on(EVENT_FOCUS, $.proxy(this.show, this));
+ } else {
+ $this.on(EVENT_CLICK, $.proxy(this.show, this));
+ }
+ }
+ }
+ }, {
+ key: 'unbind',
+ value: function unbind() {
+ var $this = this.$element,
+ options = this.options;
+
+
+ if ($.isFunction(options.show)) {
+ $this.off(EVENT_SHOW, options.show);
+ }
+
+ if ($.isFunction(options.hide)) {
+ $this.off(EVENT_HIDE, options.hide);
+ }
+
+ if ($.isFunction(options.pick)) {
+ $this.off(EVENT_PICK, options.pick);
+ }
+
+ if (this.isInput) {
+ $this.off(EVENT_KEYUP, this.keyup);
+ }
+
+ if (!this.inline) {
+ if (options.trigger) {
+ this.$trigger.off(EVENT_CLICK, this.toggle);
+ } else if (this.isInput) {
+ $this.off(EVENT_FOCUS, this.show);
+ } else {
+ $this.off(EVENT_CLICK, this.show);
+ }
+ }
+ }
+ }, {
+ key: 'showView',
+ value: function showView(view) {
+ var $yearsPicker = this.$yearsPicker,
+ $monthsPicker = this.$monthsPicker,
+ $daysPicker = this.$daysPicker,
+ format = this.format;
+
+
+ if (format.hasYear || format.hasMonth || format.hasDay) {
+ switch (Number(view)) {
+ case VIEWS.YEARS:
+ $monthsPicker.addClass(CLASS_HIDE);
+ $daysPicker.addClass(CLASS_HIDE);
+
+ if (format.hasYear) {
+ this.renderYears();
+ $yearsPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.DAYS);
+ }
+
+ break;
+
+ case VIEWS.MONTHS:
+ $yearsPicker.addClass(CLASS_HIDE);
+ $daysPicker.addClass(CLASS_HIDE);
+
+ if (format.hasMonth) {
+ this.renderMonths();
+ $monthsPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.YEARS);
+ }
+
+ break;
+
+ // case VIEWS.DAYS:
+ default:
+ $yearsPicker.addClass(CLASS_HIDE);
+ $monthsPicker.addClass(CLASS_HIDE);
+
+ if (format.hasDay) {
+ this.renderDays();
+ $daysPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.MONTHS);
+ }
+ }
+ }
+ }
+ }, {
+ key: 'hideView',
+ value: function hideView() {
+ if (!this.inline && this.options.autoHide) {
+ this.hide();
+ }
+ }
+ }, {
+ key: 'place',
+ value: function place() {
+ if (this.inline) {
+ return;
+ }
+
+ var $this = this.$element,
+ options = this.options,
+ $picker = this.$picker;
+
+ var containerWidth = $document.outerWidth();
+ var containerHeight = $document.outerHeight();
+ var elementWidth = $this.outerWidth();
+ var elementHeight = $this.outerHeight();
+ var width = $picker.width();
+ var height = $picker.height();
+
+ var _$this$offset = $this.offset(),
+ left = _$this$offset.left,
+ top = _$this$offset.top;
+
+ var offset = parseFloat(options.offset);
+ var placement = CLASS_TOP_LEFT;
+
+ if (isNaN(offset)) {
+ offset = 10;
+ }
+
+ if (top > height && top + elementHeight + height > containerHeight) {
+ top -= height + offset;
+ placement = CLASS_BOTTOM_LEFT;
+ } else {
+ top += elementHeight + offset;
+ }
+
+ if (left + width > containerWidth) {
+ left += elementWidth - width;
+ placement = placement.replace('left', 'right');
+ }
+
+ $picker.removeClass(CLASS_PLACEMENTS).addClass(placement).css({
+ top: top,
+ left: left,
+ zIndex: parseInt(options.zIndex, 10)
+ });
+ }
+
+ // A shortcut for triggering custom events
+
+ }, {
+ key: 'trigger',
+ value: function trigger(type, data) {
+ var e = $.Event(type, data);
+
+ this.$element.trigger(e);
+
+ return e;
+ }
+ }, {
+ key: 'createItem',
+ value: function createItem(data) {
+ var options = this.options;
+ var itemTag = options.itemTag;
+
+ var item = {
+ text: '',
+ view: '',
+ muted: false,
+ picked: false,
+ disabled: false,
+ highlighted: false
+ };
+ var classes = [];
+
+ $.extend(item, data);
+
+ if (item.muted) {
+ classes.push(options.mutedClass);
+ }
+
+ if (item.highlighted) {
+ classes.push(options.highlightedClass);
+ }
+
+ if (item.picked) {
+ classes.push(options.pickedClass);
+ }
+
+ if (item.disabled) {
+ classes.push(options.disabledClass);
+ }
+
+ return '<' + itemTag + ' class="' + classes.join(' ') + '" data-view="' + item.view + '">' + item.text + '' + itemTag + '>';
+ }
+ }, {
+ key: 'getValue',
+ value: function getValue() {
+ var $this = this.$element;
+
+ return this.isInput ? $this.val() : $this.text();
+ }
+ }, {
+ key: 'setValue',
+ value: function setValue() {
+ var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
+
+ var $this = this.$element;
+
+ if (this.isInput) {
+ $this.val(value);
+ } else {
+ $this.text(value);
+ }
+ }
+ }], [{
+ key: 'setDefaults',
+ value: function setDefaults() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ $.extend(DEFAULTS, LANGUAGES[options.language], options);
+ }
+ }]);
+
+ return Datepicker;
+}();
+
+$.extend(Datepicker.prototype, render, handlers, methods);
+
+var AnotherDatepicker = $.fn.datepicker;
+
+$.fn.datepicker = function jQueryDatepicker(option) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ var result = void 0;
+
+ this.each(function each() {
+ var $this = $(this);
+ var data = $this.data('datepicker');
+
+ if (!data) {
+ if (/destroy/.test(option)) {
+ return;
+ }
+
+ var options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
+
+ data = new Datepicker(this, options);
+ $this.data('datepicker', data);
+ }
+
+ if (typeof option === 'string') {
+ var fn = data[option];
+
+ if ($.isFunction(fn)) {
+ result = fn.apply(data, args);
+ }
+ }
+ });
+
+ return typeof result !== 'undefined' ? result : this;
+};
+
+$.fn.datepicker.Constructor = Datepicker;
+$.fn.datepicker.languages = LANGUAGES;
+$.fn.datepicker.setDefaults = Datepicker.setDefaults;
+$.fn.datepicker.noConflict = function noConflict() {
+ $.fn.datepicker = AnotherDatepicker;
+ return this;
+};
diff --git a/dist/datepicker.css b/dist/datepicker.css
index c3d1328..7d5fc20 100644
--- a/dist/datepicker.css
+++ b/dist/datepicker.css
@@ -1,62 +1,50 @@
/*!
- * Datepicker v0.5.3
+ * Datepicker v0.6.0
* https://github.com/fengyuanchen/datepicker
- *
+ *
* Copyright (c) 2014-2017 Fengyuan Chen
* Released under the MIT license
- *
- * Date: 2017-06-15T11:00:53.699Z
+ *
+ * Date: 2017-09-24T11:42:09.338Z
*/
.datepicker-container {
+ background-color: #fff;
+ direction: ltr;
font-size: 12px;
+ left: 0;
line-height: 30px;
-
position: fixed;
- z-index: -1;
top: 0;
- left: 0;
-
- width: 210px;
-
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-
- background-color: #fff;
-
- direction: ltr !important;
-ms-touch-action: none;
- 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;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
}
-.datepicker-container:before,
-.datepicker-container:after {
- position: absolute;
-
+.datepicker-container::before,
+.datepicker-container::after {
+ border: 5px solid transparent;
+ content: " ";
display: block;
-
- width: 0;
height: 0;
-
- content: ' ';
-
- border: 5px solid transparent;
+ position: absolute;
+ width: 0;
}
.datepicker-dropdown {
- position: absolute;
- z-index: 1;
-
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
-
border: 1px solid #ccc;
-webkit-box-shadow: 0 3px 6px #ccc;
- 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 {
@@ -68,26 +56,24 @@
border-top-color: #39f;
}
-.datepicker-top-left:before,
-.datepicker-top-left:after,
-.datepicker-top-right:before,
-.datepicker-top-right:after {
- top: -5px;
- left: 10px;
-
+.datepicker-top-left::before,
+.datepicker-top-left::after,
+.datepicker-top-right::before,
+.datepicker-top-right::after {
border-top: 0;
+ left: 10px;
+ top: -5px;
}
-.datepicker-top-left:before,
-.datepicker-top-right:before {
+.datepicker-top-left::before,
+.datepicker-top-right::before {
border-bottom-color: #39f;
}
-.datepicker-top-left:after,
-.datepicker-top-right:after {
- top: -4px;
-
+.datepicker-top-left::after,
+.datepicker-top-right::after {
border-bottom-color: #fff;
+ top: -4px;
}
.datepicker-bottom-left,
@@ -95,71 +81,64 @@
border-bottom-color: #39f;
}
-.datepicker-bottom-left:before,
-.datepicker-bottom-left:after,
-.datepicker-bottom-right:before,
-.datepicker-bottom-right:after {
+.datepicker-bottom-left::before,
+.datepicker-bottom-left::after,
+.datepicker-bottom-right::before,
+.datepicker-bottom-right::after {
+ border-bottom: 0;
bottom: -5px;
left: 10px;
-
- border-bottom: 0;
}
-.datepicker-bottom-left:before,
-.datepicker-bottom-right:before {
+.datepicker-bottom-left::before,
+.datepicker-bottom-right::before {
border-top-color: #39f;
}
-.datepicker-bottom-left:after,
-.datepicker-bottom-right:after {
- bottom: -4px;
-
+.datepicker-bottom-left::after,
+.datepicker-bottom-right::after {
border-top-color: #fff;
+ bottom: -4px;
}
-.datepicker-top-right:before,
-.datepicker-top-right:after,
-.datepicker-bottom-right:before,
-.datepicker-bottom-right:after {
- right: 10px;
+.datepicker-top-right::before,
+.datepicker-top-right::after,
+.datepicker-bottom-right::before,
+.datepicker-bottom-right::after {
left: auto;
+ right: 10px;
}
-.datepicker-panel > ul:before,
-.datepicker-panel > ul:after {
- display: table;
-
- content: ' ';
+.datepicker-panel > ul {
+ margin: 0;
+ padding: 0;
+ width: 102%;
}
-.datepicker-panel > ul:after {
- clear: both;
+.datepicker-panel > ul::before,
+.datepicker-panel > ul::after {
+ content: " ";
+ display: table;
}
-.datepicker-panel > ul {
- width: 102%;
- margin: 0;
- padding: 0;
+.datepicker-panel > ul::after {
+ clear: both;
}
.datepicker-panel > ul > li {
+ background-color: #fff;
+ cursor: pointer;
float: left;
-
- width: 30px;
height: 30px;
+ list-style: none;
margin: 0;
padding: 0;
-
- list-style: none;
-
- cursor: pointer;
text-align: center;
-
- background-color: #fff;
+ width: 30px;
}
.datepicker-panel > ul > li:hover {
- background-color: #e6f2ff;
+ background-color: lighten(#39f 35%);
}
.datepicker-panel > ul > li.muted,
@@ -168,11 +147,11 @@
}
.datepicker-panel > ul > li.highlighted {
- background-color: #e6f2ff;
+ background-color: lighten(#39f 35%);
}
.datepicker-panel > ul > li.highlighted:hover {
- background-color: #cce6ff;
+ background-color: lighten(#39f 30%);
}
.datepicker-panel > ul > li.picked,
@@ -182,46 +161,43 @@
.datepicker-panel > ul > li.disabled,
.datepicker-panel > ul > li.disabled:hover {
- cursor: default;
-
- color: #ccc;
background-color: #fff;
+ color: #ccc;
+ cursor: default;
}
.datepicker-panel > ul > li.disabled.highlighted,
.datepicker-panel > ul > li.disabled:hover.highlighted {
- background-color: #e6f2ff;
+ background-color: lighten(#39f 35%);
}
-.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'] {
+.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='years current'],
-.datepicker-panel > ul > li[data-view='year current'],
-.datepicker-panel > ul > li[data-view='month current'] {
+.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 {
+.datepicker-panel > ul[data-view="years"] > li,
+.datepicker-panel > ul[data-view="months"] > li {
+ height: 52.5px;
line-height: 52.5px;
-
width: 52.5px;
- height: 52.5px;
}
-.datepicker-panel > ul[data-view='week'] > li,
-.datepicker-panel > ul[data-view='week'] > li:hover {
- cursor: default;
-
+.datepicker-panel > ul[data-view="week"] > li,
+.datepicker-panel > ul[data-view="week"] > li:hover {
background-color: #fff;
+ cursor: default;
}
.datepicker-hide {
diff --git a/dist/datepicker.esm.js b/dist/datepicker.esm.js
new file mode 100644
index 0000000..2f93404
--- /dev/null
+++ b/dist/datepicker.esm.js
@@ -0,0 +1,1509 @@
+/*!
+ * Datepicker v0.6.0
+ * https://github.com/fengyuanchen/datepicker
+ *
+ * Copyright (c) 2014-2017 Fengyuan Chen
+ * Released under the MIT license
+ *
+ * Date: 2017-09-24T11:42:13.421Z
+ */
+import $ from 'jquery';
+
+var DEFAULTS = {
+ // Show the datepicker automatically when initialized
+ autoShow: false,
+
+ // Hide the datepicker automatically when picked
+ autoHide: false,
+
+ // Pick the initial date automatically when initialized
+ autoPick: false,
+
+ // Enable inline mode
+ inline: false,
+
+ // A element (or selector) for putting the datepicker
+ container: null,
+
+ // A element (or selector) for triggering the datepicker
+ trigger: null,
+
+ // The ISO language code (built-in: en-US)
+ language: '',
+
+ // The date string format
+ format: 'mm/dd/yyyy',
+
+ // The initial date
+ date: null,
+
+ // The start view date
+ startDate: null,
+
+ // The end view date
+ endDate: null,
+
+ // The start view when initialized
+ startView: 0, // 0 for days, 1 for months, 2 for years
+
+ // The start day of the week
+ // 0 for Sunday, 1 for Monday, 2 for Tuesday, 3 for Wednesday,
+ // 4 for Thursday, 5 for Friday, 6 for Saturday
+ weekStart: 0,
+
+ // Show year before month on the datepicker header
+ yearFirst: false,
+
+ // A string suffix to the year number.
+ yearSuffix: '',
+
+ // Days' name of the week.
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+
+ // Shorter days' name
+ daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+
+ // Shortest days' name
+ daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
+
+ // Months' name
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+
+ // Shorter months' name
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+
+ // A element tag for each item of years, months and days
+ itemTag: 'li',
+
+ // A class (CSS) for muted date item
+ mutedClass: 'muted',
+
+ // A class (CSS) for picked date item
+ pickedClass: 'picked',
+
+ // A class (CSS) for disabled date item
+ disabledClass: 'disabled',
+
+ // A class (CSS) for highlight date item
+ highlightedClass: 'highlighted',
+
+ // The template of the datepicker
+ template: '',
+
+ // The offset top or bottom of the datepicker from the element
+ offset: 10,
+
+ // The `z-index` of the datepicker
+ zIndex: 1000,
+
+ // Filter each date item (return `false` to disable a date item)
+ filter: null,
+
+ // Event shortcuts
+ show: null,
+ hide: null,
+ pick: null
+};
+
+var NAMESPACE = 'datepicker';
+var EVENT_CLICK = 'click.' + NAMESPACE;
+var EVENT_FOCUS = 'focus.' + NAMESPACE;
+var EVENT_HIDE = 'hide.' + NAMESPACE;
+var EVENT_KEYUP = 'keyup.' + NAMESPACE;
+var EVENT_PICK = 'pick.' + NAMESPACE;
+var EVENT_RESIZE = 'resize.' + NAMESPACE;
+var EVENT_SHOW = 'show.' + NAMESPACE;
+var CLASS_HIDE = NAMESPACE + '-hide';
+var LANGUAGES = {};
+var VIEWS = {
+ DAYS: 0,
+ MONTHS: 1,
+ YEARS: 2
+};
+
+var toString = Object.prototype.toString;
+
+
+function typeOf(obj) {
+ return toString.call(obj).slice(8, -1).toLowerCase();
+}
+
+function isString(value) {
+ return typeof value === 'string';
+}
+
+var isNaN = Number.isNaN || window.isNaN;
+
+function isNumber(value) {
+ return typeof value === 'number' && !isNaN(value);
+}
+
+function isUndefined(value) {
+ return typeof value === 'undefined';
+}
+
+function isDate(value) {
+ return typeOf(value) === 'date';
+}
+
+function proxy(fn, context) {
+ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
+ }
+
+ return function () {
+ for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args2[_key2] = arguments[_key2];
+ }
+
+ return fn.apply(context, args.concat(args2));
+ };
+}
+
+function selectorOf(view) {
+ return '[data-view="' + view + '"]';
+}
+
+function isLeapYear(year) {
+ return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
+}
+
+function getDaysInMonth(year, month) {
+ return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
+}
+
+function getMinDay(year, month, day) {
+ return Math.min(day, getDaysInMonth(year, month));
+}
+
+var formatParts = /(y|m|d)+/g;
+
+function parseFormat(format) {
+ var source = String(format).toLowerCase();
+ var parts = source.match(formatParts);
+
+ if (!parts || parts.length === 0) {
+ throw new Error('Invalid date format.');
+ }
+
+ format = {
+ source: source,
+ parts: parts
+ };
+
+ $.each(parts, function (i, part) {
+ switch (part) {
+ case 'dd':
+ case 'd':
+ format.hasDay = true;
+ break;
+
+ case 'mm':
+ case 'm':
+ format.hasMonth = true;
+ break;
+
+ case 'yyyy':
+ case 'yy':
+ format.hasYear = true;
+ break;
+
+ default:
+ }
+ });
+
+ return format;
+}
+
+var _window$1 = window;
+var document$2 = _window$1.document;
+
+var $window = $(window);
+var $document$1 = $(document$2);
+var REGEXP_DIGITS = /\d+/g;
+
+var methods = {
+ // Show the datepicker
+ show: function show() {
+ if (!this.built) {
+ this.build();
+ }
+
+ if (this.shown) {
+ return;
+ }
+
+ if (this.trigger(EVENT_SHOW).isDefaultPrevented()) {
+ return;
+ }
+
+ this.shown = true;
+ this.$picker.removeClass(CLASS_HIDE).on(EVENT_CLICK, $.proxy(this.click, this));
+ this.showView(this.options.startView);
+
+ if (!this.inline) {
+ $window.on(EVENT_RESIZE, this.onResize = proxy(this.place, this));
+ $document$1.on(EVENT_CLICK, this.onGlobalClick = proxy(this.globalClick, this));
+ $document$1.on(EVENT_KEYUP, this.onGlobalKeyup = proxy(this.globalKeyup, this));
+ this.place();
+ }
+ },
+
+
+ // Hide the datepicker
+ hide: function hide() {
+ if (!this.shown) {
+ return;
+ }
+
+ if (this.trigger(EVENT_HIDE).isDefaultPrevented()) {
+ return;
+ }
+
+ this.shown = false;
+ this.$picker.addClass(CLASS_HIDE).off(EVENT_CLICK, this.click);
+
+ if (!this.inline) {
+ $window.off(EVENT_RESIZE, this.onResize);
+ $document$1.off(EVENT_CLICK, this.onGlobalClick);
+ $document$1.off(EVENT_KEYUP, this.onGlobalKeyup);
+ }
+ },
+ toggle: function toggle() {
+ if (this.shown) {
+ this.hide();
+ } else {
+ this.show();
+ }
+ },
+
+
+ // Update the datepicker with the current input value
+ update: function update() {
+ var value = this.getValue();
+
+ if (value === this.oldValue) {
+ return;
+ }
+
+ this.setDate(value, true);
+ this.oldValue = value;
+ },
+
+
+ /**
+ * Pick the current date to the element
+ *
+ * @param {String} _view (private)
+ */
+ pick: function pick(_view) {
+ var $this = this.$element;
+ var date = this.date;
+
+
+ if (this.trigger(EVENT_PICK, {
+ view: _view || '',
+ date: date
+ }).isDefaultPrevented()) {
+ return;
+ }
+
+ date = this.formatDate(this.date);
+ this.setValue(date);
+
+ if (this.isInput) {
+ $this.trigger('input');
+ $this.trigger('change');
+ }
+ },
+
+
+ // Reset the datepicker
+ reset: function reset() {
+ this.setDate(this.initialDate, true);
+ this.setValue(this.initialValue);
+
+ if (this.shown) {
+ this.showView(this.options.startView);
+ }
+ },
+
+
+ /**
+ * Get the month name with given argument or the current date
+ *
+ * @param {Number} month (optional)
+ * @param {Boolean} short (optional)
+ * @return {String} (month name)
+ */
+ getMonthName: function getMonthName(month, short) {
+ var options = this.options;
+ var monthsShort = options.monthsShort;
+ var months = options.months;
+
+
+ if ($.isNumeric(month)) {
+ month = Number(month);
+ } else if (isUndefined(short)) {
+ short = month;
+ }
+
+ if (short === true) {
+ months = monthsShort;
+ }
+
+ return months[isNumber(month) ? month : this.date.getMonth()];
+ },
+
+
+ /**
+ * Get the day name with given argument or the current date
+ *
+ * @param {Number} day (optional)
+ * @param {Boolean} short (optional)
+ * @param {Boolean} min (optional)
+ * @return {String} (day name)
+ */
+ getDayName: function getDayName(day, short, min) {
+ var options = this.options;
+ var days = options.days;
+
+
+ if ($.isNumeric(day)) {
+ day = Number(day);
+ } else {
+ if (isUndefined(min)) {
+ min = short;
+ }
+
+ if (isUndefined(short)) {
+ short = day;
+ }
+ }
+
+ if (min) {
+ days = options.daysMin;
+ } else if (short) {
+ days = options.daysShort;
+ }
+
+ return days[isNumber(day) ? day : this.date.getDay()];
+ },
+
+
+ /**
+ * Get the current date
+ *
+ * @param {Boolean} formatted (optional)
+ * @return {Date|String} (date)
+ */
+ getDate: function getDate(formatted) {
+ var date = this.date;
+
+
+ return formatted ? this.formatDate(date) : new Date(date);
+ },
+
+
+ /**
+ * Set the current date with a new date
+ *
+ * @param {Date} date
+ * @param {Boolean} _updated (private)
+ */
+ setDate: function setDate(date, _updated) {
+ var filter = this.options.filter;
+
+
+ if (isDate(date) || isString(date)) {
+ date = this.parseDate(date);
+
+ if ($.isFunction(filter) && filter.call(this.$element, date) === false) {
+ return;
+ }
+
+ this.date = date;
+ this.viewDate = new Date(date);
+
+ if (!_updated) {
+ this.pick();
+ }
+
+ if (this.built) {
+ this.render();
+ }
+ }
+ },
+
+
+ /**
+ * Set the start view date with a new date
+ *
+ * @param {Date} date
+ */
+ setStartDate: function setStartDate(date) {
+ if (isDate(date) || isString(date)) {
+ this.startDate = this.parseDate(date);
+
+ if (this.built) {
+ this.render();
+ }
+ }
+ },
+
+
+ /**
+ * Set the end view date with a new date
+ *
+ * @param {Date} date
+ */
+ setEndDate: function setEndDate(date) {
+ if (isDate(date) || isString(date)) {
+ this.endDate = this.parseDate(date);
+
+ if (this.built) {
+ this.render();
+ }
+ }
+ },
+
+
+ /**
+ * Parse a date string with the set date format
+ *
+ * @param {String} date
+ * @return {Date} (parsed date)
+ */
+ parseDate: function parseDate(date) {
+ var format = this.format;
+
+ var parts = [];
+
+ if (isDate(date)) {
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
+ } else if (isString(date)) {
+ parts = date.match(REGEXP_DIGITS) || [];
+ }
+
+ date = new Date();
+
+ var length = format.parts.length;
+
+ var year = date.getFullYear();
+ var day = date.getDate();
+ var month = date.getMonth();
+
+ if (parts.length === length) {
+ $.each(parts, function (i, part) {
+ var value = parseInt(part, 10) || 1;
+
+ switch (format.parts[i]) {
+ case 'dd':
+ case 'd':
+ day = value;
+ break;
+
+ case 'mm':
+ case 'm':
+ month = value - 1;
+ break;
+
+ case 'yy':
+ year = 2000 + value;
+ break;
+
+ case 'yyyy':
+ year = value;
+ break;
+
+ default:
+ }
+ });
+ }
+
+ return new Date(year, month, day);
+ },
+
+
+ /**
+ * Format a date object to a string with the set date format
+ *
+ * @param {Date} date
+ * @return {String} (formatted date)
+ */
+ formatDate: function formatDate(date) {
+ var format = this.format;
+
+ var formatted = '';
+
+ if (isDate(date)) {
+ var year = date.getFullYear();
+ var values = {
+ d: date.getDate(),
+ m: date.getMonth() + 1,
+ yy: year.toString().substring(2),
+ yyyy: year
+ };
+
+ values.dd = (values.d < 10 ? '0' : '') + values.d;
+ values.mm = (values.m < 10 ? '0' : '') + values.m;
+ formatted = format.source;
+ $.each(format.parts, function (i, part) {
+ formatted = formatted.replace(part, values[part]);
+ });
+ }
+
+ return formatted;
+ },
+
+
+ // Destroy the datepicker and remove the instance from the target element
+ destroy: function destroy() {
+ this.unbind();
+ this.unbuild();
+ this.$element.removeData(NAMESPACE);
+ }
+};
+
+var handlers = {
+ click: function click(e) {
+ var $target = $(e.target);
+ var options = this.options,
+ viewDate = this.viewDate,
+ format = this.format;
+
+
+ e.stopPropagation();
+ e.preventDefault();
+
+ if ($target.hasClass('disabled')) {
+ return;
+ }
+
+ var view = $target.data('view');
+ var viewYear = viewDate.getFullYear();
+ var viewMonth = viewDate.getMonth();
+ var viewDay = viewDate.getDate();
+
+ switch (view) {
+ case 'years prev':
+ case 'years next':
+ {
+ viewYear = view === 'years prev' ? viewYear - 10 : viewYear + 10;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderYears();
+ break;
+ }
+
+ case 'year prev':
+ case 'year next':
+ viewYear = view === 'year prev' ? viewYear - 1 : viewYear + 1;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderMonths();
+ break;
+
+ case 'year current':
+ if (format.hasYear) {
+ this.showView(VIEWS.YEARS);
+ }
+
+ break;
+
+ case 'year picked':
+ if (format.hasMonth) {
+ this.showView(VIEWS.MONTHS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
+
+ this.pick('year');
+ break;
+
+ case 'year':
+ viewYear = parseInt($target.text(), 10);
+ this.date = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+
+ if (format.hasMonth) {
+ this.viewDate = new Date(this.date);
+ this.showView(VIEWS.MONTHS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
+
+ this.pick('year');
+ break;
+
+ case 'month prev':
+ case 'month next':
+ viewMonth = view === 'month prev' ? viewMonth - 1 : viewMonth + 1;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderDays();
+ break;
+
+ case 'month current':
+ if (format.hasMonth) {
+ this.showView(VIEWS.MONTHS);
+ }
+
+ break;
+
+ case 'month picked':
+ if (format.hasDay) {
+ this.showView(VIEWS.DAYS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
+
+ this.pick('month');
+ break;
+
+ case 'month':
+ viewMonth = $.inArray($target.text(), options.monthsShort);
+ this.date = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+
+ if (format.hasDay) {
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.showView(VIEWS.DAYS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
+
+ this.pick('month');
+ break;
+
+ case 'day prev':
+ case 'day next':
+ case 'day':
+ if (view === 'day prev') {
+ viewMonth -= 1;
+ } else if (view === 'day next') {
+ viewMonth += 1;
+ }
+
+ viewDay = parseInt($target.text(), 10);
+ this.date = new Date(viewYear, viewMonth, viewDay);
+ this.viewDate = new Date(viewYear, viewMonth, viewDay);
+ this.renderDays();
+
+ if (view === 'day') {
+ this.hideView();
+ }
+
+ this.pick('day');
+ break;
+
+ case 'day picked':
+ this.hideView();
+ this.pick('day');
+ break;
+
+ default:
+ }
+ },
+ globalClick: function globalClick(_ref) {
+ var target = _ref.target;
+ var element = this.element,
+ $trigger = this.$trigger;
+
+ var trigger = $trigger[0];
+ var hidden = true;
+
+ while (target !== document) {
+ if (target === trigger || target === element) {
+ hidden = false;
+ break;
+ }
+
+ target = target.parentNode;
+ }
+
+ if (hidden) {
+ this.hide();
+ }
+ },
+ keyup: function keyup() {
+ this.update();
+ },
+ globalKeyup: function globalKeyup(_ref2) {
+ var target = _ref2.target,
+ key = _ref2.key,
+ keyCode = _ref2.keyCode;
+
+ if (this.isInput && target !== this.element && this.shown && (key === 'Tab' || keyCode === 9)) {
+ this.hide();
+ }
+ }
+};
+
+var render = {
+ render: function render() {
+ this.renderYears();
+ this.renderMonths();
+ this.renderDays();
+ },
+ renderWeek: function renderWeek() {
+ var _this = this;
+
+ var items = [];
+ var _options = this.options,
+ weekStart = _options.weekStart,
+ daysMin = _options.daysMin;
+
+
+ weekStart = parseInt(weekStart, 10) % 7;
+ daysMin = daysMin.slice(weekStart).concat(daysMin.slice(0, weekStart));
+ $.each(daysMin, function (i, day) {
+ items.push(_this.createItem({
+ text: day
+ }));
+ });
+
+ this.$week.html(items.join(''));
+ },
+ renderYears: function renderYears() {
+ var options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate;
+ var disabledClass = options.disabledClass,
+ filter = options.filter,
+ yearSuffix = options.yearSuffix;
+
+ var viewYear = this.viewDate.getFullYear();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var year = this.date.getFullYear();
+ var start = -5;
+ var end = 6;
+ var items = [];
+ var prevDisabled = false;
+ var nextDisabled = false;
+ var i = void 0;
+
+ for (i = start; i <= end; i += 1) {
+ var date = new Date(viewYear + i, 1, 1);
+ var disabled = false;
+
+ if (startDate) {
+ disabled = date.getFullYear() < startDate.getFullYear();
+
+ if (i === start) {
+ prevDisabled = disabled;
+ }
+ }
+
+ if (!disabled && endDate) {
+ disabled = date.getFullYear() > endDate.getFullYear();
+
+ if (i === end) {
+ nextDisabled = disabled;
+ }
+ }
+
+ if (!disabled && filter) {
+ disabled = filter.call(this.$element, date) === false;
+ }
+
+ var picked = viewYear + i === year;
+ var view = picked ? 'year picked' : 'year';
+
+ items.push(this.createItem({
+ picked: picked,
+ disabled: disabled,
+ muted: i === start || i === end,
+ text: viewYear + i,
+ view: disabled ? 'year disabled' : view,
+ highlighted: date.getFullYear() === thisYear
+ }));
+ }
+
+ this.$yearsPrev.toggleClass(disabledClass, prevDisabled);
+ this.$yearsNext.toggleClass(disabledClass, nextDisabled);
+ this.$yearsCurrent.toggleClass(disabledClass, true).html(viewYear + start + yearSuffix + ' - ' + (viewYear + end) + yearSuffix);
+ this.$years.html(items.join(''));
+ },
+ renderMonths: function renderMonths() {
+ var options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate,
+ viewDate = this.viewDate;
+
+ var disabledClass = options.disabledClass || '';
+ var months = options.monthsShort;
+ var filter = $.isFunction(options.filter) && options.filter;
+ var viewYear = viewDate.getFullYear();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var thisMonth = now.getMonth();
+ var year = this.date.getFullYear();
+ var month = this.date.getMonth();
+ var items = [];
+ var prevDisabled = false;
+ var nextDisabled = false;
+ var i = void 0;
+
+ for (i = 0; i <= 11; i += 1) {
+ var date = new Date(viewYear, i, 1);
+ var disabled = false;
+
+ if (startDate) {
+ prevDisabled = date.getFullYear() === startDate.getFullYear();
+ disabled = prevDisabled && date.getMonth() < startDate.getMonth();
+ }
+
+ if (!disabled && endDate) {
+ nextDisabled = date.getFullYear() === endDate.getFullYear();
+ disabled = nextDisabled && date.getMonth() > endDate.getMonth();
+ }
+
+ if (!disabled && filter) {
+ disabled = filter.call(this.$element, date) === false;
+ }
+
+ 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,
+ index: i,
+ text: months[i],
+ view: disabled ? 'month disabled' : view
+ }));
+ }
+
+ this.$yearPrev.toggleClass(disabledClass, prevDisabled);
+ this.$yearNext.toggleClass(disabledClass, nextDisabled);
+ this.$yearCurrent.toggleClass(disabledClass, prevDisabled && nextDisabled).html(viewYear + options.yearSuffix || '');
+ this.$months.html(items.join(''));
+ },
+ renderDays: function renderDays() {
+ var $element = this.$element,
+ options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate,
+ viewDate = this.viewDate,
+ currentDate = this.date;
+ var disabledClass = options.disabledClass,
+ filter = options.filter,
+ monthsShort = options.monthsShort,
+ weekStart = options.weekStart,
+ yearSuffix = options.yearSuffix;
+
+ var viewYear = viewDate.getFullYear();
+ var viewMonth = viewDate.getMonth();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var thisMonth = now.getMonth();
+ var thisDay = now.getDate();
+ var year = currentDate.getFullYear();
+ var month = currentDate.getMonth();
+ var day = currentDate.getDate();
+ var length = void 0;
+ var i = void 0;
+ var n = void 0;
+
+ // Days of prev month
+ // -----------------------------------------------------------------------
+
+ var prevItems = [];
+ var prevViewYear = viewYear;
+ var prevViewMonth = viewMonth;
+ var prevDisabled = false;
+
+ if (viewMonth === 0) {
+ prevViewYear -= 1;
+ prevViewMonth = 11;
+ } else {
+ prevViewMonth -= 1;
+ }
+
+ // The length of the days of prev month
+ length = getDaysInMonth(prevViewYear, prevViewMonth);
+
+ // The first day of current month
+ var firstDay = new Date(viewYear, viewMonth, 1);
+
+ // The visible length of the days of prev month
+ // [0,1,2,3,4,5,6] - [0,1,2,3,4,5,6] => [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6]
+ n = firstDay.getDay() - parseInt(weekStart, 10) % 7;
+
+ // [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6] => [1,2,3,4,5,6,7]
+ if (n <= 0) {
+ n += 7;
+ }
+
+ if (startDate) {
+ prevDisabled = firstDay.getTime() <= startDate.getTime();
+ }
+
+ for (i = length - (n - 1); i <= length; i += 1) {
+ var prevViewDate = new Date(prevViewYear, prevViewMonth, i);
+ var disabled = false;
+
+ if (startDate) {
+ disabled = prevViewDate.getTime() < startDate.getTime();
+ }
+
+ if (!disabled && filter) {
+ disabled = filter.call($element, prevViewDate) === false;
+ }
+
+ prevItems.push(this.createItem({
+ disabled: disabled,
+ highlighted: prevViewYear === thisYear && prevViewMonth === thisMonth && prevViewDate.getDate() === thisDay,
+ muted: true,
+ picked: prevViewYear === year && prevViewMonth === month && i === day,
+ text: i,
+ view: 'day prev'
+ }));
+ }
+
+ // Days of next month
+ // -----------------------------------------------------------------------
+
+ var nextItems = [];
+ var nextViewYear = viewYear;
+ var nextViewMonth = viewMonth;
+ var nextDisabled = false;
+
+ if (viewMonth === 11) {
+ nextViewYear += 1;
+ nextViewMonth = 0;
+ } else {
+ nextViewMonth += 1;
+ }
+
+ // The length of the days of current month
+ length = getDaysInMonth(viewYear, viewMonth);
+
+ // The visible length of next month (42 means 6 rows and 7 columns)
+ n = 42 - (prevItems.length + length);
+
+ // The last day of current month
+ var lastDate = new Date(viewYear, viewMonth, length);
+
+ if (endDate) {
+ nextDisabled = lastDate.getTime() >= endDate.getTime();
+ }
+
+ for (i = 1; i <= n; i += 1) {
+ var date = new Date(nextViewYear, nextViewMonth, i);
+ var picked = nextViewYear === year && nextViewMonth === month && i === day;
+ var _disabled = false;
+
+ if (endDate) {
+ _disabled = date.getTime() > endDate.getTime();
+ }
+
+ if (!_disabled && filter) {
+ _disabled = filter.call($element, date) === false;
+ }
+
+ nextItems.push(this.createItem({
+ disabled: _disabled,
+ picked: picked,
+ highlighted: nextViewYear === thisYear && nextViewMonth === thisMonth && date.getDate() === thisDay,
+ muted: true,
+ text: i,
+ view: 'day next'
+ }));
+ }
+
+ // Days of current month
+ // -----------------------------------------------------------------------
+
+ var items = [];
+
+ for (i = 1; i <= length; i += 1) {
+ var _date = new Date(viewYear, viewMonth, i);
+ var _disabled2 = false;
+
+ if (startDate) {
+ _disabled2 = _date.getTime() < startDate.getTime();
+ }
+
+ if (!_disabled2 && endDate) {
+ _disabled2 = _date.getTime() > endDate.getTime();
+ }
+
+ if (!_disabled2 && filter) {
+ _disabled2 = filter.call($element, _date) === false;
+ }
+
+ var _picked = viewYear === year && viewMonth === month && i === day;
+ var view = _picked ? 'day picked' : 'day';
+
+ items.push(this.createItem({
+ disabled: _disabled2,
+ picked: _picked,
+ highlighted: viewYear === thisYear && viewMonth === thisMonth && _date.getDate() === thisDay,
+ text: i,
+ view: _disabled2 ? 'day disabled' : view
+ }));
+ }
+
+ // Render days picker
+ // -----------------------------------------------------------------------
+
+ this.$monthPrev.toggleClass(disabledClass, prevDisabled);
+ this.$monthNext.toggleClass(disabledClass, nextDisabled);
+ this.$monthCurrent.toggleClass(disabledClass, prevDisabled && nextDisabled).html(options.yearFirst ? viewYear + yearSuffix + ' ' + monthsShort[viewMonth] : monthsShort[viewMonth] + ' ' + viewYear + yearSuffix);
+ this.$days.html(prevItems.join('') + items.join('') + nextItems.join(''));
+ }
+};
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var _window = window;
+var document$1 = _window.document;
+
+var $document = $(document$1);
+
+// Classes
+var CLASS_TOP_LEFT = NAMESPACE + '-top-left';
+var CLASS_TOP_RIGHT = NAMESPACE + '-top-right';
+var CLASS_BOTTOM_LEFT = NAMESPACE + '-bottom-left';
+var CLASS_BOTTOM_RIGHT = NAMESPACE + '-bottom-right';
+var CLASS_PLACEMENTS = [CLASS_TOP_LEFT, CLASS_TOP_RIGHT, CLASS_BOTTOM_LEFT, CLASS_BOTTOM_RIGHT].join(' ');
+
+var Datepicker = function () {
+ function Datepicker(element) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ _classCallCheck(this, Datepicker);
+
+ this.$element = $(element);
+ this.element = element;
+ this.options = $.extend({}, DEFAULTS, LANGUAGES[options.language], options);
+ this.built = false;
+ this.shown = false;
+ this.isInput = false;
+ this.inline = false;
+ this.initialValue = '';
+ this.initialDate = null;
+ this.startDate = null;
+ this.endDate = null;
+ this.init();
+ }
+
+ _createClass(Datepicker, [{
+ key: 'init',
+ value: function init() {
+ var $this = this.$element,
+ options = this.options;
+ var startDate = options.startDate,
+ endDate = options.endDate,
+ date = options.date;
+
+
+ this.$trigger = $(options.trigger);
+ this.isInput = $this.is('input') || $this.is('textarea');
+ this.inline = options.inline && (options.container || !this.isInput);
+ this.format = parseFormat(options.format);
+
+ var initialValue = this.getValue();
+
+ this.initialValue = initialValue;
+ this.oldValue = initialValue;
+ date = this.parseDate(date || initialValue);
+
+ if (startDate) {
+ startDate = this.parseDate(startDate);
+
+ if (date.getTime() < startDate.getTime()) {
+ date = new Date(startDate);
+ }
+
+ this.startDate = startDate;
+ }
+
+ if (endDate) {
+ endDate = this.parseDate(endDate);
+
+ if (startDate && endDate.getTime() < startDate.getTime()) {
+ endDate = new Date(startDate);
+ }
+
+ if (date.getTime() > endDate.getTime()) {
+ date = new Date(endDate);
+ }
+
+ this.endDate = endDate;
+ }
+
+ this.date = date;
+ this.viewDate = new Date(date);
+ this.initialDate = new Date(this.date);
+ this.bind();
+
+ if (options.autoShow || this.inline) {
+ this.show();
+ }
+
+ if (options.autoPick) {
+ this.pick();
+ }
+ }
+ }, {
+ key: 'build',
+ value: function build() {
+ if (this.built) {
+ return;
+ }
+
+ this.built = true;
+
+ var $this = this.$element,
+ options = this.options;
+
+ var $picker = $(options.template);
+
+ this.$picker = $picker;
+ this.$week = $picker.find(selectorOf('week'));
+
+ // Years view
+ this.$yearsPicker = $picker.find(selectorOf('years picker'));
+ this.$yearsPrev = $picker.find(selectorOf('years prev'));
+ this.$yearsNext = $picker.find(selectorOf('years next'));
+ this.$yearsCurrent = $picker.find(selectorOf('years current'));
+ this.$years = $picker.find(selectorOf('years'));
+
+ // Months view
+ this.$monthsPicker = $picker.find(selectorOf('months picker'));
+ this.$yearPrev = $picker.find(selectorOf('year prev'));
+ this.$yearNext = $picker.find(selectorOf('year next'));
+ this.$yearCurrent = $picker.find(selectorOf('year current'));
+ this.$months = $picker.find(selectorOf('months'));
+
+ // Days view
+ this.$daysPicker = $picker.find(selectorOf('days picker'));
+ this.$monthPrev = $picker.find(selectorOf('month prev'));
+ this.$monthNext = $picker.find(selectorOf('month next'));
+ this.$monthCurrent = $picker.find(selectorOf('month current'));
+ this.$days = $picker.find(selectorOf('days'));
+
+ if (this.inline) {
+ $(options.container || $this).append($picker.addClass(NAMESPACE + '-inline'));
+ } else {
+ $(document$1.body).append($picker.addClass(NAMESPACE + '-dropdown'));
+ $picker.addClass(CLASS_HIDE);
+ }
+
+ this.renderWeek();
+ }
+ }, {
+ key: 'unbuild',
+ value: function unbuild() {
+ if (!this.built) {
+ return;
+ }
+
+ this.built = false;
+ this.$picker.remove();
+ }
+ }, {
+ key: 'bind',
+ value: function bind() {
+ var options = this.options,
+ $this = this.$element;
+
+
+ if ($.isFunction(options.show)) {
+ $this.on(EVENT_SHOW, options.show);
+ }
+
+ if ($.isFunction(options.hide)) {
+ $this.on(EVENT_HIDE, options.hide);
+ }
+
+ if ($.isFunction(options.pick)) {
+ $this.on(EVENT_PICK, options.pick);
+ }
+
+ if (this.isInput) {
+ $this.on(EVENT_KEYUP, $.proxy(this.keyup, this));
+ }
+
+ if (!this.inline) {
+ if (options.trigger) {
+ this.$trigger.on(EVENT_CLICK, $.proxy(this.toggle, this));
+ } else if (this.isInput) {
+ $this.on(EVENT_FOCUS, $.proxy(this.show, this));
+ } else {
+ $this.on(EVENT_CLICK, $.proxy(this.show, this));
+ }
+ }
+ }
+ }, {
+ key: 'unbind',
+ value: function unbind() {
+ var $this = this.$element,
+ options = this.options;
+
+
+ if ($.isFunction(options.show)) {
+ $this.off(EVENT_SHOW, options.show);
+ }
+
+ if ($.isFunction(options.hide)) {
+ $this.off(EVENT_HIDE, options.hide);
+ }
+
+ if ($.isFunction(options.pick)) {
+ $this.off(EVENT_PICK, options.pick);
+ }
+
+ if (this.isInput) {
+ $this.off(EVENT_KEYUP, this.keyup);
+ }
+
+ if (!this.inline) {
+ if (options.trigger) {
+ this.$trigger.off(EVENT_CLICK, this.toggle);
+ } else if (this.isInput) {
+ $this.off(EVENT_FOCUS, this.show);
+ } else {
+ $this.off(EVENT_CLICK, this.show);
+ }
+ }
+ }
+ }, {
+ key: 'showView',
+ value: function showView(view) {
+ var $yearsPicker = this.$yearsPicker,
+ $monthsPicker = this.$monthsPicker,
+ $daysPicker = this.$daysPicker,
+ format = this.format;
+
+
+ if (format.hasYear || format.hasMonth || format.hasDay) {
+ switch (Number(view)) {
+ case VIEWS.YEARS:
+ $monthsPicker.addClass(CLASS_HIDE);
+ $daysPicker.addClass(CLASS_HIDE);
+
+ if (format.hasYear) {
+ this.renderYears();
+ $yearsPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.DAYS);
+ }
+
+ break;
+
+ case VIEWS.MONTHS:
+ $yearsPicker.addClass(CLASS_HIDE);
+ $daysPicker.addClass(CLASS_HIDE);
+
+ if (format.hasMonth) {
+ this.renderMonths();
+ $monthsPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.YEARS);
+ }
+
+ break;
+
+ // case VIEWS.DAYS:
+ default:
+ $yearsPicker.addClass(CLASS_HIDE);
+ $monthsPicker.addClass(CLASS_HIDE);
+
+ if (format.hasDay) {
+ this.renderDays();
+ $daysPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.MONTHS);
+ }
+ }
+ }
+ }
+ }, {
+ key: 'hideView',
+ value: function hideView() {
+ if (!this.inline && this.options.autoHide) {
+ this.hide();
+ }
+ }
+ }, {
+ key: 'place',
+ value: function place() {
+ if (this.inline) {
+ return;
+ }
+
+ var $this = this.$element,
+ options = this.options,
+ $picker = this.$picker;
+
+ var containerWidth = $document.outerWidth();
+ var containerHeight = $document.outerHeight();
+ var elementWidth = $this.outerWidth();
+ var elementHeight = $this.outerHeight();
+ var width = $picker.width();
+ var height = $picker.height();
+
+ var _$this$offset = $this.offset(),
+ left = _$this$offset.left,
+ top = _$this$offset.top;
+
+ var offset = parseFloat(options.offset);
+ var placement = CLASS_TOP_LEFT;
+
+ if (isNaN(offset)) {
+ offset = 10;
+ }
+
+ if (top > height && top + elementHeight + height > containerHeight) {
+ top -= height + offset;
+ placement = CLASS_BOTTOM_LEFT;
+ } else {
+ top += elementHeight + offset;
+ }
+
+ if (left + width > containerWidth) {
+ left += elementWidth - width;
+ placement = placement.replace('left', 'right');
+ }
+
+ $picker.removeClass(CLASS_PLACEMENTS).addClass(placement).css({
+ top: top,
+ left: left,
+ zIndex: parseInt(options.zIndex, 10)
+ });
+ }
+
+ // A shortcut for triggering custom events
+
+ }, {
+ key: 'trigger',
+ value: function trigger(type, data) {
+ var e = $.Event(type, data);
+
+ this.$element.trigger(e);
+
+ return e;
+ }
+ }, {
+ key: 'createItem',
+ value: function createItem(data) {
+ var options = this.options;
+ var itemTag = options.itemTag;
+
+ var item = {
+ text: '',
+ view: '',
+ muted: false,
+ picked: false,
+ disabled: false,
+ highlighted: false
+ };
+ var classes = [];
+
+ $.extend(item, data);
+
+ if (item.muted) {
+ classes.push(options.mutedClass);
+ }
+
+ if (item.highlighted) {
+ classes.push(options.highlightedClass);
+ }
+
+ if (item.picked) {
+ classes.push(options.pickedClass);
+ }
+
+ if (item.disabled) {
+ classes.push(options.disabledClass);
+ }
+
+ return '<' + itemTag + ' class="' + classes.join(' ') + '" data-view="' + item.view + '">' + item.text + '' + itemTag + '>';
+ }
+ }, {
+ key: 'getValue',
+ value: function getValue() {
+ var $this = this.$element;
+
+ return this.isInput ? $this.val() : $this.text();
+ }
+ }, {
+ key: 'setValue',
+ value: function setValue() {
+ var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
+
+ var $this = this.$element;
+
+ if (this.isInput) {
+ $this.val(value);
+ } else {
+ $this.text(value);
+ }
+ }
+ }], [{
+ key: 'setDefaults',
+ value: function setDefaults() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ $.extend(DEFAULTS, LANGUAGES[options.language], options);
+ }
+ }]);
+
+ return Datepicker;
+}();
+
+$.extend(Datepicker.prototype, render, handlers, methods);
+
+var AnotherDatepicker = $.fn.datepicker;
+
+$.fn.datepicker = function jQueryDatepicker(option) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ var result = void 0;
+
+ this.each(function each() {
+ var $this = $(this);
+ var data = $this.data('datepicker');
+
+ if (!data) {
+ if (/destroy/.test(option)) {
+ return;
+ }
+
+ var options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
+
+ data = new Datepicker(this, options);
+ $this.data('datepicker', data);
+ }
+
+ if (typeof option === 'string') {
+ var fn = data[option];
+
+ if ($.isFunction(fn)) {
+ result = fn.apply(data, args);
+ }
+ }
+ });
+
+ return typeof result !== 'undefined' ? result : this;
+};
+
+$.fn.datepicker.Constructor = Datepicker;
+$.fn.datepicker.languages = LANGUAGES;
+$.fn.datepicker.setDefaults = Datepicker.setDefaults;
+$.fn.datepicker.noConflict = function noConflict() {
+ $.fn.datepicker = AnotherDatepicker;
+ return this;
+};
diff --git a/dist/datepicker.js b/dist/datepicker.js
index 66a74d3..2b6560f 100644
--- a/dist/datepicker.js
+++ b/dist/datepicker.js
@@ -1,1567 +1,1517 @@
/*!
- * Datepicker v0.5.5
+ * Datepicker v0.6.0
* https://github.com/fengyuanchen/datepicker
*
* Copyright (c) 2014-2017 Fengyuan Chen
* Released under the MIT license
*
- * Date: 2017-09-10T09:16:17.133Z
+ * Date: 2017-09-24T11:42:13.421Z
*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
+ typeof define === 'function' && define.amd ? define(['jquery'], factory) :
+ (factory(global.jQuery));
+}(this, (function ($) { 'use strict';
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as anonymous module.
- define('datepicker', ['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node / CommonJS
- factory(require('jquery'));
- } else {
- // Browser globals.
- factory(jQuery);
+$ = $ && $.hasOwnProperty('default') ? $['default'] : $;
+
+var DEFAULTS = {
+ // Show the datepicker automatically when initialized
+ autoShow: false,
+
+ // Hide the datepicker automatically when picked
+ autoHide: false,
+
+ // Pick the initial date automatically when initialized
+ autoPick: false,
+
+ // Enable inline mode
+ inline: false,
+
+ // A element (or selector) for putting the datepicker
+ container: null,
+
+ // A element (or selector) for triggering the datepicker
+ trigger: null,
+
+ // The ISO language code (built-in: en-US)
+ language: '',
+
+ // The date string format
+ format: 'mm/dd/yyyy',
+
+ // The initial date
+ date: null,
+
+ // The start view date
+ startDate: null,
+
+ // The end view date
+ endDate: null,
+
+ // The start view when initialized
+ startView: 0, // 0 for days, 1 for months, 2 for years
+
+ // The start day of the week
+ // 0 for Sunday, 1 for Monday, 2 for Tuesday, 3 for Wednesday,
+ // 4 for Thursday, 5 for Friday, 6 for Saturday
+ weekStart: 0,
+
+ // Show year before month on the datepicker header
+ yearFirst: false,
+
+ // A string suffix to the year number.
+ yearSuffix: '',
+
+ // Days' name of the week.
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+
+ // Shorter days' name
+ daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+
+ // Shortest days' name
+ daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
+
+ // Months' name
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+
+ // Shorter months' name
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+
+ // A element tag for each item of years, months and days
+ itemTag: 'li',
+
+ // A class (CSS) for muted date item
+ mutedClass: 'muted',
+
+ // A class (CSS) for picked date item
+ pickedClass: 'picked',
+
+ // A class (CSS) for disabled date item
+ disabledClass: 'disabled',
+
+ // A class (CSS) for highlight date item
+ highlightedClass: 'highlighted',
+
+ // The template of the datepicker
+ template: '',
+
+ // The offset top or bottom of the datepicker from the element
+ offset: 10,
+
+ // The `z-index` of the datepicker
+ zIndex: 1000,
+
+ // Filter each date item (return `false` to disable a date item)
+ filter: null,
+
+ // Event shortcuts
+ show: null,
+ hide: null,
+ pick: null
+};
+
+var NAMESPACE = 'datepicker';
+var EVENT_CLICK = 'click.' + NAMESPACE;
+var EVENT_FOCUS = 'focus.' + NAMESPACE;
+var EVENT_HIDE = 'hide.' + NAMESPACE;
+var EVENT_KEYUP = 'keyup.' + NAMESPACE;
+var EVENT_PICK = 'pick.' + NAMESPACE;
+var EVENT_RESIZE = 'resize.' + NAMESPACE;
+var EVENT_SHOW = 'show.' + NAMESPACE;
+var CLASS_HIDE = NAMESPACE + '-hide';
+var LANGUAGES = {};
+var VIEWS = {
+ DAYS: 0,
+ MONTHS: 1,
+ YEARS: 2
+};
+
+var toString = Object.prototype.toString;
+
+
+function typeOf(obj) {
+ return toString.call(obj).slice(8, -1).toLowerCase();
+}
+
+function isString(value) {
+ return typeof value === 'string';
+}
+
+var isNaN = Number.isNaN || window.isNaN;
+
+function isNumber(value) {
+ return typeof value === 'number' && !isNaN(value);
+}
+
+function isUndefined(value) {
+ return typeof value === 'undefined';
+}
+
+function isDate(value) {
+ return typeOf(value) === 'date';
+}
+
+function proxy(fn, context) {
+ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
}
-})(function ($) {
-
- 'use strict';
-
- var $window = $(window);
- var document = window.document;
- var $document = $(document);
- var Number = window.Number;
- var NAMESPACE = 'datepicker';
-
- // Events
- var EVENT_CLICK = 'click.' + NAMESPACE;
- var EVENT_KEYUP = 'keyup.' + NAMESPACE;
- var EVENT_FOCUS = 'focus.' + NAMESPACE;
- var EVENT_RESIZE = 'resize.' + NAMESPACE;
- var EVENT_SHOW = 'show.' + NAMESPACE;
- var EVENT_HIDE = 'hide.' + NAMESPACE;
- var EVENT_PICK = 'pick.' + NAMESPACE;
-
- // RegExps
- var REGEXP_FORMAT = /(y|m|d)+/g;
- var REGEXP_DIGITS = /\d+/g;
- var REGEXP_YEAR = /^\d{2,4}$/;
-
- // Classes
- var CLASS_INLINE = NAMESPACE + '-inline';
- var CLASS_DROPDOWN = NAMESPACE + '-dropdown';
- var CLASS_TOP_LEFT = NAMESPACE + '-top-left';
- var CLASS_TOP_RIGHT = NAMESPACE + '-top-right';
- var CLASS_BOTTOM_LEFT = NAMESPACE + '-bottom-left';
- var CLASS_BOTTOM_RIGHT = NAMESPACE + '-bottom-right';
- var CLASS_PLACEMENTS = [
- CLASS_TOP_LEFT,
- CLASS_TOP_RIGHT,
- CLASS_BOTTOM_LEFT,
- CLASS_BOTTOM_RIGHT
- ].join(' ');
- var CLASS_HIDE = NAMESPACE + '-hide';
-
- // Views
- var VIEWS = {
- DAYS: 0,
- MONTHS: 1,
- YEARS: 2
+
+ return function () {
+ for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args2[_key2] = arguments[_key2];
+ }
+
+ return fn.apply(context, args.concat(args2));
};
+}
- // Maths
- var min = Math.min;
+function selectorOf(view) {
+ return '[data-view="' + view + '"]';
+}
- // Utilities
- var toString = Object.prototype.toString;
+function isLeapYear(year) {
+ return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
+}
- function typeOf(obj) {
- return toString.call(obj).slice(8, -1).toLowerCase();
- }
+function getDaysInMonth(year, month) {
+ return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
+}
- function isString(str) {
- return typeof str === 'string';
- }
+function getMinDay(year, month, day) {
+ return Math.min(day, getDaysInMonth(year, month));
+}
- function isNumber(num) {
- return typeof num === 'number' && !isNaN(num);
- }
+var formatParts = /(y|m|d)+/g;
- function isUndefined(obj) {
- return typeof obj === 'undefined';
- }
+function parseFormat(format) {
+ var source = String(format).toLowerCase();
+ var parts = source.match(formatParts);
- function isDate(date) {
- return typeOf(date) === 'date';
+ if (!parts || parts.length === 0) {
+ throw new Error('Invalid date format.');
}
- function toArray(obj, offset) {
- var args = [];
+ format = {
+ source: source,
+ parts: parts
+ };
- if (Array.from) {
- return Array.from(obj).slice(offset || 0);
- }
+ $.each(parts, function (i, part) {
+ switch (part) {
+ case 'dd':
+ case 'd':
+ format.hasDay = true;
+ break;
- // This is necessary for IE8
- if (isNumber(offset)) {
- args.push(offset);
- }
+ case 'mm':
+ case 'm':
+ format.hasMonth = true;
+ break;
- return args.slice.apply(obj, args);
- }
+ case 'yyyy':
+ case 'yy':
+ format.hasYear = true;
+ break;
- // Custom proxy to avoid jQuery's guid
- function proxy(fn, context) {
- var args = toArray(arguments, 2);
+ default:
+ }
+ });
- return function () {
- return fn.apply(context, args.concat(toArray(arguments)));
- };
- }
+ return format;
+}
- function isLeapYear(year) {
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
- }
+var _window$1 = window;
+var document$2 = _window$1.document;
- function getDaysInMonth(year, month) {
- return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
- }
+var $window = $(window);
+var $document$1 = $(document$2);
+var REGEXP_DIGITS = /\d+/g;
- function parseFormat(format) {
- var source = String(format).toLowerCase();
- var parts = source.match(REGEXP_FORMAT);
- var length;
- var i;
+var methods = {
+ // Show the datepicker
+ show: function show() {
+ if (!this.built) {
+ this.build();
+ }
- if (!parts || parts.length === 0) {
- throw new Error('Invalid date format.');
+ if (this.shown) {
+ return;
}
- format = {
- source: source,
- parts: parts
- };
+ if (this.trigger(EVENT_SHOW).isDefaultPrevented()) {
+ return;
+ }
- length = parts.length;
+ this.shown = true;
+ this.$picker.removeClass(CLASS_HIDE).on(EVENT_CLICK, $.proxy(this.click, this));
+ this.showView(this.options.startView);
- for (i = 0; i < length; i++) {
- switch (parts[i]) {
- case 'dd':
- case 'd':
- format.hasDay = true;
- break;
+ if (!this.inline) {
+ $window.on(EVENT_RESIZE, this.onResize = proxy(this.place, this));
+ $document$1.on(EVENT_CLICK, this.onGlobalClick = proxy(this.globalClick, this));
+ $document$1.on(EVENT_KEYUP, this.onGlobalKeyup = proxy(this.globalKeyup, this));
+ this.place();
+ }
+ },
- case 'mm':
- case 'm':
- format.hasMonth = true;
- break;
- case 'yyyy':
- case 'yy':
- format.hasYear = true;
- break;
+ // Hide the datepicker
+ hide: function hide() {
+ if (!this.shown) {
+ return;
+ }
- // No default
- }
+ if (this.trigger(EVENT_HIDE).isDefaultPrevented()) {
+ return;
}
- return format;
- }
+ this.shown = false;
+ this.$picker.addClass(CLASS_HIDE).off(EVENT_CLICK, this.click);
+
+ if (!this.inline) {
+ $window.off(EVENT_RESIZE, this.onResize);
+ $document$1.off(EVENT_CLICK, this.onGlobalClick);
+ $document$1.off(EVENT_KEYUP, this.onGlobalKeyup);
+ }
+ },
+ toggle: function toggle() {
+ if (this.shown) {
+ this.hide();
+ } else {
+ this.show();
+ }
+ },
+
- function Datepicker(element, options) {
- options = $.isPlainObject(options) ? options : {};
+ // Update the datepicker with the current input value
+ update: function update() {
+ var value = this.getValue();
- if (options.language) {
- // Priority: Datepicker.DEFAULTS < Datepicker.LANGUAGES < options
- options = $.extend({}, Datepicker.LANGUAGES[options.language], options);
+ if (value === this.oldValue) {
+ return;
}
- this.$element = $(element);
- this.options = $.extend({}, Datepicker.DEFAULTS, options);
- this.isBuilt = false;
- this.isShown = false;
- this.isInput = false;
- this.isInline = false;
- this.initialValue = '';
- this.initialDate = null;
- this.startDate = null;
- this.endDate = null;
- this.init();
- }
+ this.setDate(value, true);
+ this.oldValue = value;
+ },
- Datepicker.prototype = {
- constructor: Datepicker,
- init: function () {
- var options = this.options;
- var $this = this.$element;
- var startDate = options.startDate;
- var endDate = options.endDate;
- var date = options.date;
+ /**
+ * Pick the current date to the element
+ *
+ * @param {String} _view (private)
+ */
+ pick: function pick(_view) {
+ var $this = this.$element;
+ var date = this.date;
- this.$trigger = $(options.trigger);
- this.isInput = $this.is('input') || $this.is('textarea');
- this.isInline = options.inline && (options.container || !this.isInput);
- this.format = parseFormat(options.format);
- this.oldValue = this.initialValue = this.getValue();
- date = this.parseDate(date || this.initialValue);
- if (startDate) {
- startDate = this.parseDate(startDate);
+ if (this.trigger(EVENT_PICK, {
+ view: _view || '',
+ date: date
+ }).isDefaultPrevented()) {
+ return;
+ }
- if (date.getTime() < startDate.getTime()) {
- date = new Date(startDate);
- }
+ date = this.formatDate(this.date);
+ this.setValue(date);
- this.startDate = startDate;
- }
+ if (this.isInput) {
+ $this.trigger('input');
+ $this.trigger('change');
+ }
+ },
- if (endDate) {
- endDate = this.parseDate(endDate);
- if (startDate && endDate.getTime() < startDate.getTime()) {
- endDate = new Date(startDate);
- }
+ // Reset the datepicker
+ reset: function reset() {
+ this.setDate(this.initialDate, true);
+ this.setValue(this.initialValue);
- if (date.getTime() > endDate.getTime()) {
- date = new Date(endDate);
- }
+ if (this.shown) {
+ this.showView(this.options.startView);
+ }
+ },
+
+
+ /**
+ * Get the month name with given argument or the current date
+ *
+ * @param {Number} month (optional)
+ * @param {Boolean} short (optional)
+ * @return {String} (month name)
+ */
+ getMonthName: function getMonthName(month, short) {
+ var options = this.options;
+ var monthsShort = options.monthsShort;
+ var months = options.months;
+
+
+ if ($.isNumeric(month)) {
+ month = Number(month);
+ } else if (isUndefined(short)) {
+ short = month;
+ }
- this.endDate = endDate;
- }
+ if (short === true) {
+ months = monthsShort;
+ }
- this.date = date;
- this.viewDate = new Date(date);
- this.initialDate = new Date(this.date);
+ return months[isNumber(month) ? month : this.date.getMonth()];
+ },
- this.bind();
- if (options.autoShow || this.isInline) {
- this.show();
+ /**
+ * Get the day name with given argument or the current date
+ *
+ * @param {Number} day (optional)
+ * @param {Boolean} short (optional)
+ * @param {Boolean} min (optional)
+ * @return {String} (day name)
+ */
+ getDayName: function getDayName(day, short, min) {
+ var options = this.options;
+ var days = options.days;
+
+
+ if ($.isNumeric(day)) {
+ day = Number(day);
+ } else {
+ if (isUndefined(min)) {
+ min = short;
}
- if (options.autoPick) {
- this.pick();
+ if (isUndefined(short)) {
+ short = day;
}
- },
+ }
- build: function () {
- var options = this.options;
- var $this = this.$element;
- var $picker;
+ if (min) {
+ days = options.daysMin;
+ } else if (short) {
+ days = options.daysShort;
+ }
- if (this.isBuilt) {
- return;
- }
+ return days[isNumber(day) ? day : this.date.getDay()];
+ },
- this.isBuilt = true;
- this.$picker = $picker = $(options.template);
- this.$week = $picker.find('[data-view="week"]');
+ /**
+ * Get the current date
+ *
+ * @param {Boolean} formatted (optional)
+ * @return {Date|String} (date)
+ */
+ getDate: function getDate(formatted) {
+ var date = this.date;
- // Years view
- this.$yearsPicker = $picker.find('[data-view="years picker"]');
- this.$yearsPrev = $picker.find('[data-view="years prev"]');
- this.$yearsNext = $picker.find('[data-view="years next"]');
- this.$yearsCurrent = $picker.find('[data-view="years current"]');
- this.$years = $picker.find('[data-view="years"]');
- // Months view
- this.$monthsPicker = $picker.find('[data-view="months picker"]');
- this.$yearPrev = $picker.find('[data-view="year prev"]');
- this.$yearNext = $picker.find('[data-view="year next"]');
- this.$yearCurrent = $picker.find('[data-view="year current"]');
- this.$months = $picker.find('[data-view="months"]');
+ return formatted ? this.formatDate(date) : new Date(date);
+ },
- // Days view
- this.$daysPicker = $picker.find('[data-view="days picker"]');
- this.$monthPrev = $picker.find('[data-view="month prev"]');
- this.$monthNext = $picker.find('[data-view="month next"]');
- this.$monthCurrent = $picker.find('[data-view="month current"]');
- this.$days = $picker.find('[data-view="days"]');
-
- if (this.isInline) {
- $(options.container || $this).append($picker.addClass(CLASS_INLINE));
- } else {
- $(document.body).append($picker.addClass(CLASS_DROPDOWN));
- $picker.addClass(CLASS_HIDE);
- }
- this.fillWeek();
- },
+ /**
+ * Set the current date with a new date
+ *
+ * @param {Date} date
+ * @param {Boolean} _updated (private)
+ */
+ setDate: function setDate(date, _updated) {
+ var filter = this.options.filter;
+
- unbuild: function () {
- if (!this.isBuilt) {
+ if (isDate(date) || isString(date)) {
+ date = this.parseDate(date);
+
+ if ($.isFunction(filter) && filter.call(this.$element, date) === false) {
return;
}
- this.isBuilt = false;
- this.$picker.remove();
- },
-
- bind: function () {
- var options = this.options;
- var $this = this.$element;
+ this.date = date;
+ this.viewDate = new Date(date);
- if ($.isFunction(options.show)) {
- $this.on(EVENT_SHOW, options.show);
+ if (!_updated) {
+ this.pick();
}
- if ($.isFunction(options.hide)) {
- $this.on(EVENT_HIDE, options.hide);
+ if (this.built) {
+ this.render();
}
+ }
+ },
- if ($.isFunction(options.pick)) {
- $this.on(EVENT_PICK, options.pick);
- }
- if (this.isInput) {
- $this.on(EVENT_KEYUP, $.proxy(this.keyup, this));
- }
+ /**
+ * Set the start view date with a new date
+ *
+ * @param {Date} date
+ */
+ setStartDate: function setStartDate(date) {
+ if (isDate(date) || isString(date)) {
+ this.startDate = this.parseDate(date);
- if (!this.isInline) {
- if (options.trigger) {
- this.$trigger.on(EVENT_CLICK, $.proxy(this.toggle, this));
- } else if (this.isInput) {
- $this.on(EVENT_FOCUS, $.proxy(this.show, this));
- } else {
- $this.on(EVENT_CLICK, $.proxy(this.show, this));
- }
+ if (this.built) {
+ this.render();
}
- },
+ }
+ },
- unbind: function () {
- var options = this.options;
- var $this = this.$element;
- if ($.isFunction(options.show)) {
- $this.off(EVENT_SHOW, options.show);
- }
+ /**
+ * Set the end view date with a new date
+ *
+ * @param {Date} date
+ */
+ setEndDate: function setEndDate(date) {
+ if (isDate(date) || isString(date)) {
+ this.endDate = this.parseDate(date);
- if ($.isFunction(options.hide)) {
- $this.off(EVENT_HIDE, options.hide);
+ if (this.built) {
+ this.render();
}
+ }
+ },
- if ($.isFunction(options.pick)) {
- $this.off(EVENT_PICK, options.pick);
- }
- if (this.isInput) {
- $this.off(EVENT_KEYUP, this.keyup);
- }
+ /**
+ * Parse a date string with the set date format
+ *
+ * @param {String} date
+ * @return {Date} (parsed date)
+ */
+ parseDate: function parseDate(date) {
+ var format = this.format;
- if (!this.isInline) {
- if (options.trigger) {
- this.$trigger.off(EVENT_CLICK, this.toggle);
- } else if (this.isInput) {
- $this.off(EVENT_FOCUS, this.show);
- } else {
- $this.off(EVENT_CLICK, this.show);
- }
- }
- },
+ var parts = [];
- showView: function (view) {
- var $yearsPicker = this.$yearsPicker;
- var $monthsPicker = this.$monthsPicker;
- var $daysPicker = this.$daysPicker;
- var format = this.format;
+ if (isDate(date)) {
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
+ } else if (isString(date)) {
+ parts = date.match(REGEXP_DIGITS) || [];
+ }
- if (format.hasYear || format.hasMonth || format.hasDay) {
- switch (Number(view)) {
- case VIEWS.YEARS:
- case 'years':
- $monthsPicker.addClass(CLASS_HIDE);
- $daysPicker.addClass(CLASS_HIDE);
+ date = new Date();
- if (format.hasYear) {
- this.fillYears();
- $yearsPicker.removeClass(CLASS_HIDE);
- this.place();
- } else {
- this.showView(VIEWS.DAYS);
- }
+ var length = format.parts.length;
+
+ var year = date.getFullYear();
+ var day = date.getDate();
+ var month = date.getMonth();
+ if (parts.length === length) {
+ $.each(parts, function (i, part) {
+ var value = parseInt(part, 10) || 1;
+
+ switch (format.parts[i]) {
+ case 'dd':
+ case 'd':
+ day = value;
break;
- case VIEWS.MONTHS:
- case 'months':
- $yearsPicker.addClass(CLASS_HIDE);
- $daysPicker.addClass(CLASS_HIDE);
+ case 'mm':
+ case 'm':
+ month = value - 1;
+ break;
- if (format.hasMonth) {
- this.fillMonths();
- $monthsPicker.removeClass(CLASS_HIDE);
- this.place();
- } else {
- this.showView(VIEWS.YEARS);
- }
+ case 'yy':
+ year = 2000 + value;
+ break;
+ case 'yyyy':
+ year = value;
break;
- // case VIEWS.DAYS:
- // case 'days':
default:
- $yearsPicker.addClass(CLASS_HIDE);
- $monthsPicker.addClass(CLASS_HIDE);
-
- if (format.hasDay) {
- this.fillDays();
- $daysPicker.removeClass(CLASS_HIDE);
- this.place();
- } else {
- this.showView(VIEWS.MONTHS);
- }
}
- }
- },
+ });
+ }
- hideView: function () {
- if (!this.isInline && this.options.autoHide) {
- this.hide();
- }
- },
+ return new Date(year, month, day);
+ },
- place: function () {
- if (this.isInline) {
- return;
- }
- var options = this.options;
- var $this = this.$element;
- var $picker = this.$picker;
- var containerWidth = $document.outerWidth();
- var containerHeight = $document.outerHeight();
- var elementWidth = $this.outerWidth();
- var elementHeight = $this.outerHeight();
- var width = $picker.width();
- var height = $picker.height();
- var offsets = $this.offset();
- var left = offsets.left;
- var top = offsets.top;
- var offset = parseFloat(options.offset) || 10;
- var placement = CLASS_TOP_LEFT;
+ /**
+ * Format a date object to a string with the set date format
+ *
+ * @param {Date} date
+ * @return {String} (formatted date)
+ */
+ formatDate: function formatDate(date) {
+ var format = this.format;
- if (top > height && top + elementHeight + height > containerHeight) {
- top -= height + offset;
- placement = CLASS_BOTTOM_LEFT;
- } else {
- top += elementHeight + offset;
- }
-
- if (left + width > containerWidth) {
- left = left + elementWidth - width;
- placement = placement.replace('left', 'right');
- }
+ var formatted = '';
- $picker.removeClass(CLASS_PLACEMENTS).addClass(placement).css({
- top: top,
- left: left,
- zIndex: parseInt(options.zIndex, 10)
+ if (isDate(date)) {
+ var year = date.getFullYear();
+ var values = {
+ d: date.getDate(),
+ m: date.getMonth() + 1,
+ yy: year.toString().substring(2),
+ yyyy: year
+ };
+
+ values.dd = (values.d < 10 ? '0' : '') + values.d;
+ values.mm = (values.m < 10 ? '0' : '') + values.m;
+ formatted = format.source;
+ $.each(format.parts, function (i, part) {
+ formatted = formatted.replace(part, values[part]);
});
- },
+ }
- // A shortcut for triggering custom events
- trigger: function (type, data) {
- var e = $.Event(type, data);
+ return formatted;
+ },
- this.$element.trigger(e);
- return e;
- },
+ // Destroy the datepicker and remove the instance from the target element
+ destroy: function destroy() {
+ this.unbind();
+ this.unbuild();
+ this.$element.removeData(NAMESPACE);
+ }
+};
- createItem: function (data) {
- var options = this.options;
- var itemTag = options.itemTag;
- var defaults = {
- text: '',
- view: '',
- muted: false,
- picked: false,
- disabled: false,
- highlighted: false
- };
- var classes = [];
+var handlers = {
+ click: function click(e) {
+ var $target = $(e.target);
+ var options = this.options,
+ viewDate = this.viewDate,
+ format = this.format;
- $.extend(defaults, data);
- if (defaults.muted) {
- classes.push(options.mutedClass);
- }
+ e.stopPropagation();
+ e.preventDefault();
- if (defaults.highlighted) {
- classes.push(options.highlightedClass);
- }
+ if ($target.hasClass('disabled')) {
+ return;
+ }
- if (defaults.picked) {
- classes.push(options.pickedClass);
- }
+ var view = $target.data('view');
+ var viewYear = viewDate.getFullYear();
+ var viewMonth = viewDate.getMonth();
+ var viewDay = viewDate.getDate();
- if (defaults.disabled) {
- classes.push(options.disabledClass);
- }
+ switch (view) {
+ case 'years prev':
+ case 'years next':
+ {
+ viewYear = view === 'years prev' ? viewYear - 10 : viewYear + 10;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderYears();
+ break;
+ }
- return (
- '<' + itemTag + ' class="' + classes.join(' ') + '"' +
- (defaults.view ? ' data-view="' + defaults.view + '"' : '') +
- '>' +
- defaults.text +
- '' + itemTag + '>'
- );
- },
-
- fillAll: function () {
- this.fillYears();
- this.fillMonths();
- this.fillDays();
- },
-
- fillWeek: function () {
- var options = this.options;
- var weekStart = parseInt(options.weekStart, 10) % 7;
- var days = options.daysMin;
- var list = '';
- var i;
+ case 'year prev':
+ case 'year next':
+ viewYear = view === 'year prev' ? viewYear - 1 : viewYear + 1;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderMonths();
+ break;
- days = $.merge(days.slice(weekStart), days.slice(0, weekStart));
+ case 'year current':
+ if (format.hasYear) {
+ this.showView(VIEWS.YEARS);
+ }
- for (i = 0; i <= 6; i++) {
- list += this.createItem({
- text: days[i]
- });
- }
+ break;
+
+ case 'year picked':
+ if (format.hasMonth) {
+ this.showView(VIEWS.MONTHS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
- this.$week.html(list);
- },
+ this.pick('year');
+ break;
- fillYears: function () {
- var options = this.options;
- var disabledClass = options.disabledClass || '';
- var suffix = options.yearSuffix || '';
- var filter = $.isFunction(options.filter) && options.filter;
- var startDate = this.startDate;
- var endDate = this.endDate;
- var viewDate = this.viewDate;
- var viewYear = viewDate.getFullYear();
- var now = new Date();
- var thisYear = now.getFullYear();
- var date = this.date;
- var year = date.getFullYear();
- var isPrevDisabled = false;
- var isNextDisabled = false;
- var isDisabled = false;
- var isPicked = false;
- var isMuted = false;
- var list = '';
- var start = -5;
- var end = 6;
- var i;
-
- for (i = start; i <= end; i++) {
- date = new Date(viewYear + i, 1, 1);
- isMuted = i === start || i === end;
- isPicked = (viewYear + i) === year;
- isDisabled = false;
-
- if (startDate) {
- isDisabled = date.getFullYear() < startDate.getFullYear();
-
- if (i === start) {
- isPrevDisabled = isDisabled;
- }
+ case 'year':
+ viewYear = parseInt($target.text(), 10);
+ this.date = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+
+ if (format.hasMonth) {
+ this.viewDate = new Date(this.date);
+ this.showView(VIEWS.MONTHS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
}
- if (!isDisabled && endDate) {
- isDisabled = date.getFullYear() > endDate.getFullYear();
+ this.pick('year');
+ break;
- if (i === end) {
- isNextDisabled = isDisabled;
- }
+ case 'month prev':
+ case 'month next':
+ viewMonth = view === 'month prev' ? viewMonth - 1 : viewMonth + 1;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderDays();
+ break;
+
+ case 'month current':
+ if (format.hasMonth) {
+ this.showView(VIEWS.MONTHS);
}
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
+ break;
+
+ case 'month picked':
+ if (format.hasDay) {
+ this.showView(VIEWS.DAYS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
}
- list += this.createItem({
- text: viewYear + i,
- view: isDisabled ? 'year disabled' : isPicked ? 'year picked' : 'year',
- muted: isMuted,
- picked: isPicked,
- disabled: isDisabled,
- highlighted: date.getFullYear() === thisYear
- });
- }
+ this.pick('month');
+ break;
- this.$yearsPrev.toggleClass(disabledClass, isPrevDisabled);
- this.$yearsNext.toggleClass(disabledClass, isNextDisabled);
- this.$yearsCurrent.
- toggleClass(disabledClass, true).
- html((viewYear + start) + suffix + ' - ' + (viewYear + end) + suffix);
- this.$years.html(list);
- },
+ case 'month':
+ viewMonth = $.inArray($target.text(), options.monthsShort);
+ this.date = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
- fillMonths: function () {
- var options = this.options;
- var disabledClass = options.disabledClass || '';
- var months = options.monthsShort;
- var filter = $.isFunction(options.filter) && options.filter;
- var startDate = this.startDate;
- var endDate = this.endDate;
- var viewDate = this.viewDate;
- var viewYear = viewDate.getFullYear();
- var now = new Date();
- var thisYear = now.getFullYear();
- var thisMonth = now.getMonth();
- var date = this.date;
- var year = date.getFullYear();
- var month = date.getMonth();
- var isPrevDisabled = false;
- var isNextDisabled = false;
- var isDisabled = false;
- var isPicked = false;
- var list = '';
- var i;
-
- for (i = 0; i <= 11; i++) {
- date = new Date(viewYear, i, 1);
- isPicked = viewYear === year && i === month;
- isDisabled = false;
-
- if (startDate) {
- isPrevDisabled = date.getFullYear() === startDate.getFullYear();
- isDisabled = isPrevDisabled && date.getMonth() < startDate.getMonth();
+ if (format.hasDay) {
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.showView(VIEWS.DAYS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
}
- if (!isDisabled && endDate) {
- isNextDisabled = date.getFullYear() === endDate.getFullYear();
- isDisabled = isNextDisabled && date.getMonth() > endDate.getMonth();
- console.log(isNextDisabled, date, endDate)
- }
+ this.pick('month');
+ break;
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
+ case 'day prev':
+ case 'day next':
+ case 'day':
+ if (view === 'day prev') {
+ viewMonth -= 1;
+ } else if (view === 'day next') {
+ viewMonth += 1;
}
- list += this.createItem({
- index: i,
- text: months[i],
- view: isDisabled ? 'month disabled' : isPicked ? 'month picked' : 'month',
- picked: isPicked,
- disabled: isDisabled,
- highlighted: viewYear === thisYear && date.getMonth() === thisMonth
- });
- }
+ viewDay = parseInt($target.text(), 10);
+ this.date = new Date(viewYear, viewMonth, viewDay);
+ this.viewDate = new Date(viewYear, viewMonth, viewDay);
+ this.renderDays();
- this.$yearPrev.toggleClass(disabledClass, isPrevDisabled);
- this.$yearNext.toggleClass(disabledClass, isNextDisabled);
- this.$yearCurrent.
- toggleClass(disabledClass, isPrevDisabled && isNextDisabled).
- html(viewYear + options.yearSuffix || '');
- this.$months.html(list);
- },
+ if (view === 'day') {
+ this.hideView();
+ }
- fillDays: function () {
- var options = this.options;
- var disabledClass = options.disabledClass || '';
- var suffix = options.yearSuffix || '';
- var months = options.monthsShort;
- var weekStart = parseInt(options.weekStart, 10) % 7;
- var filter = $.isFunction(options.filter) && options.filter;
- var startDate = this.startDate;
- var endDate = this.endDate;
- var viewDate = this.viewDate;
- var viewYear = viewDate.getFullYear();
- var viewMonth = viewDate.getMonth();
- var prevViewYear = viewYear;
- var prevViewMonth = viewMonth;
- var nextViewYear = viewYear;
- var now = new Date();
- var thisYear = now.getFullYear();
- var thisMonth = now.getMonth();
- var today = now.getDate();
- var nextViewMonth = viewMonth;
- var date = this.date;
- var year = date.getFullYear();
- var month = date.getMonth();
- var day = date.getDate();
- var isPrevDisabled = false;
- var isNextDisabled = false;
- var isDisabled = false;
- var isPicked = false;
- var prevItems = [];
- var nextItems = [];
- var items = [];
- var total = 42; // 6 rows and 7 columns on the days picker
- var length;
- var i;
- var n;
-
- // Days of previous month
- // -----------------------------------------------------------------------
-
- if (viewMonth === 0) {
- prevViewYear -= 1;
- prevViewMonth = 11;
- } else {
- prevViewMonth -= 1;
- }
+ this.pick('day');
+ break;
- // The length of the days of previous month
- length = getDaysInMonth(prevViewYear, prevViewMonth);
+ case 'day picked':
+ this.hideView();
+ this.pick('day');
+ break;
- // The first day of current month
- date = new Date(viewYear, viewMonth, 1);
+ default:
+ }
+ },
+ globalClick: function globalClick(_ref) {
+ var target = _ref.target;
+ var element = this.element,
+ $trigger = this.$trigger;
- // The visible length of the days of previous month
- // [0,1,2,3,4,5,6] - [0,1,2,3,4,5,6] => [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6]
- n = date.getDay() - weekStart;
+ var trigger = $trigger[0];
+ var hidden = true;
- // [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6] => [1,2,3,4,5,6,7]
- if (n <= 0) {
- n += 7;
+ while (target !== document) {
+ if (target === trigger || target === element) {
+ hidden = false;
+ break;
}
+ target = target.parentNode;
+ }
+
+ if (hidden) {
+ this.hide();
+ }
+ },
+ keyup: function keyup() {
+ this.update();
+ },
+ globalKeyup: function globalKeyup(_ref2) {
+ var target = _ref2.target,
+ key = _ref2.key,
+ keyCode = _ref2.keyCode;
+
+ if (this.isInput && target !== this.element && this.shown && (key === 'Tab' || keyCode === 9)) {
+ this.hide();
+ }
+ }
+};
+
+var render = {
+ render: function render() {
+ this.renderYears();
+ this.renderMonths();
+ this.renderDays();
+ },
+ renderWeek: function renderWeek() {
+ var _this = this;
+
+ var items = [];
+ var _options = this.options,
+ weekStart = _options.weekStart,
+ daysMin = _options.daysMin;
+
+
+ weekStart = parseInt(weekStart, 10) % 7;
+ daysMin = daysMin.slice(weekStart).concat(daysMin.slice(0, weekStart));
+ $.each(daysMin, function (i, day) {
+ items.push(_this.createItem({
+ text: day
+ }));
+ });
+
+ this.$week.html(items.join(''));
+ },
+ renderYears: function renderYears() {
+ var options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate;
+ var disabledClass = options.disabledClass,
+ filter = options.filter,
+ yearSuffix = options.yearSuffix;
+
+ var viewYear = this.viewDate.getFullYear();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var year = this.date.getFullYear();
+ var start = -5;
+ var end = 6;
+ var items = [];
+ var prevDisabled = false;
+ var nextDisabled = false;
+ var i = void 0;
+
+ for (i = start; i <= end; i += 1) {
+ var date = new Date(viewYear + i, 1, 1);
+ var disabled = false;
+
if (startDate) {
- isPrevDisabled = date.getTime() <= startDate.getTime();
+ disabled = date.getFullYear() < startDate.getFullYear();
+
+ if (i === start) {
+ prevDisabled = disabled;
+ }
}
- for (i = length - (n - 1); i <= length; i++) {
- date = new Date(prevViewYear, prevViewMonth, i);
- isPicked = prevViewYear === year && prevViewMonth === month && i === day;
- isDisabled = false;
+ if (!disabled && endDate) {
+ disabled = date.getFullYear() > endDate.getFullYear();
- if (startDate) {
- isDisabled = date.getTime() < startDate.getTime();
+ if (i === end) {
+ nextDisabled = disabled;
}
+ }
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
- }
+ if (!disabled && filter) {
+ disabled = filter.call(this.$element, date) === false;
+ }
+
+ var picked = viewYear + i === year;
+ var view = picked ? 'year picked' : 'year';
+
+ items.push(this.createItem({
+ picked: picked,
+ disabled: disabled,
+ muted: i === start || i === end,
+ text: viewYear + i,
+ view: disabled ? 'year disabled' : view,
+ highlighted: date.getFullYear() === thisYear
+ }));
+ }
- prevItems.push(this.createItem({
- text: i,
- view: 'day prev',
- muted: true,
- picked: isPicked,
- disabled: isDisabled,
- highlighted: prevViewYear === thisYear && prevViewMonth === thisMonth && date.getDate() === today
- }));
+ this.$yearsPrev.toggleClass(disabledClass, prevDisabled);
+ this.$yearsNext.toggleClass(disabledClass, nextDisabled);
+ this.$yearsCurrent.toggleClass(disabledClass, true).html(viewYear + start + yearSuffix + ' - ' + (viewYear + end) + yearSuffix);
+ this.$years.html(items.join(''));
+ },
+ renderMonths: function renderMonths() {
+ var options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate,
+ viewDate = this.viewDate;
+
+ var disabledClass = options.disabledClass || '';
+ var months = options.monthsShort;
+ var filter = $.isFunction(options.filter) && options.filter;
+ var viewYear = viewDate.getFullYear();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var thisMonth = now.getMonth();
+ var year = this.date.getFullYear();
+ var month = this.date.getMonth();
+ var items = [];
+ var prevDisabled = false;
+ var nextDisabled = false;
+ var i = void 0;
+
+ for (i = 0; i <= 11; i += 1) {
+ var date = new Date(viewYear, i, 1);
+ var disabled = false;
+
+ if (startDate) {
+ prevDisabled = date.getFullYear() === startDate.getFullYear();
+ disabled = prevDisabled && date.getMonth() < startDate.getMonth();
}
- // Days of next month
- // -----------------------------------------------------------------------
+ if (!disabled && endDate) {
+ nextDisabled = date.getFullYear() === endDate.getFullYear();
+ disabled = nextDisabled && date.getMonth() > endDate.getMonth();
+ }
- if (viewMonth === 11) {
- nextViewYear += 1;
- nextViewMonth = 0;
- } else {
- nextViewMonth += 1;
+ if (!disabled && filter) {
+ disabled = filter.call(this.$element, date) === false;
}
- // The length of the days of current month
- length = getDaysInMonth(viewYear, viewMonth);
+ var picked = viewYear === year && i === month;
+ var view = picked ? 'month picked' : 'month';
- // The visible length of next month
- n = total - (prevItems.length + length);
+ items.push(this.createItem({
+ disabled: disabled,
+ picked: picked,
+ highlighted: viewYear === thisYear && date.getMonth() === thisMonth,
+ index: i,
+ text: months[i],
+ view: disabled ? 'month disabled' : view
+ }));
+ }
- // The last day of current month
- date = new Date(viewYear, viewMonth, length);
+ this.$yearPrev.toggleClass(disabledClass, prevDisabled);
+ this.$yearNext.toggleClass(disabledClass, nextDisabled);
+ this.$yearCurrent.toggleClass(disabledClass, prevDisabled && nextDisabled).html(viewYear + options.yearSuffix || '');
+ this.$months.html(items.join(''));
+ },
+ renderDays: function renderDays() {
+ var $element = this.$element,
+ options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate,
+ viewDate = this.viewDate,
+ currentDate = this.date;
+ var disabledClass = options.disabledClass,
+ filter = options.filter,
+ monthsShort = options.monthsShort,
+ weekStart = options.weekStart,
+ yearSuffix = options.yearSuffix;
+
+ var viewYear = viewDate.getFullYear();
+ var viewMonth = viewDate.getMonth();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var thisMonth = now.getMonth();
+ var thisDay = now.getDate();
+ var year = currentDate.getFullYear();
+ var month = currentDate.getMonth();
+ var day = currentDate.getDate();
+ var length = void 0;
+ var i = void 0;
+ var n = void 0;
+
+ // Days of prev month
+ // -----------------------------------------------------------------------
+
+ var prevItems = [];
+ var prevViewYear = viewYear;
+ var prevViewMonth = viewMonth;
+ var prevDisabled = false;
+
+ if (viewMonth === 0) {
+ prevViewYear -= 1;
+ prevViewMonth = 11;
+ } else {
+ prevViewMonth -= 1;
+ }
- if (endDate) {
- isNextDisabled = date.getTime() >= endDate.getTime();
+ // The length of the days of prev month
+ length = getDaysInMonth(prevViewYear, prevViewMonth);
+
+ // The first day of current month
+ var firstDay = new Date(viewYear, viewMonth, 1);
+
+ // The visible length of the days of prev month
+ // [0,1,2,3,4,5,6] - [0,1,2,3,4,5,6] => [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6]
+ n = firstDay.getDay() - parseInt(weekStart, 10) % 7;
+
+ // [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6] => [1,2,3,4,5,6,7]
+ if (n <= 0) {
+ n += 7;
+ }
+
+ if (startDate) {
+ prevDisabled = firstDay.getTime() <= startDate.getTime();
+ }
+
+ for (i = length - (n - 1); i <= length; i += 1) {
+ var prevViewDate = new Date(prevViewYear, prevViewMonth, i);
+ var disabled = false;
+
+ if (startDate) {
+ disabled = prevViewDate.getTime() < startDate.getTime();
+ }
+
+ if (!disabled && filter) {
+ disabled = filter.call($element, prevViewDate) === false;
}
- for (i = 1; i <= n; i++) {
- date = new Date(nextViewYear, nextViewMonth, i);
- isPicked = nextViewYear === year && nextViewMonth === month && i === day;
- isDisabled = false;
+ prevItems.push(this.createItem({
+ disabled: disabled,
+ highlighted: prevViewYear === thisYear && prevViewMonth === thisMonth && prevViewDate.getDate() === thisDay,
+ muted: true,
+ picked: prevViewYear === year && prevViewMonth === month && i === day,
+ text: i,
+ view: 'day prev'
+ }));
+ }
+
+ // Days of next month
+ // -----------------------------------------------------------------------
+
+ var nextItems = [];
+ var nextViewYear = viewYear;
+ var nextViewMonth = viewMonth;
+ var nextDisabled = false;
+
+ if (viewMonth === 11) {
+ nextViewYear += 1;
+ nextViewMonth = 0;
+ } else {
+ nextViewMonth += 1;
+ }
+
+ // The length of the days of current month
+ length = getDaysInMonth(viewYear, viewMonth);
+
+ // The visible length of next month (42 means 6 rows and 7 columns)
+ n = 42 - (prevItems.length + length);
- if (endDate) {
- isDisabled = date.getTime() > endDate.getTime();
- }
+ // The last day of current month
+ var lastDate = new Date(viewYear, viewMonth, length);
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
- }
+ if (endDate) {
+ nextDisabled = lastDate.getTime() >= endDate.getTime();
+ }
+
+ for (i = 1; i <= n; i += 1) {
+ var date = new Date(nextViewYear, nextViewMonth, i);
+ var picked = nextViewYear === year && nextViewMonth === month && i === day;
+ var _disabled = false;
- nextItems.push(this.createItem({
- text: i,
- view: 'day next',
- muted: true,
- picked: isPicked,
- disabled: isDisabled,
- highlighted: nextViewYear === thisYear && nextViewMonth === thisMonth && date.getDate() === today
- }));
+ if (endDate) {
+ _disabled = date.getTime() > endDate.getTime();
}
- // Days of current month
- // -----------------------------------------------------------------------
+ if (!_disabled && filter) {
+ _disabled = filter.call($element, date) === false;
+ }
- for (i = 1; i <= length; i++) {
- date = new Date(viewYear, viewMonth, i);
- isPicked = viewYear === year && viewMonth === month && i === day;
- isDisabled = false;
+ nextItems.push(this.createItem({
+ disabled: _disabled,
+ picked: picked,
+ highlighted: nextViewYear === thisYear && nextViewMonth === thisMonth && date.getDate() === thisDay,
+ muted: true,
+ text: i,
+ view: 'day next'
+ }));
+ }
- if (startDate) {
- isDisabled = date.getTime() < startDate.getTime();
- }
+ // Days of current month
+ // -----------------------------------------------------------------------
- if (!isDisabled && endDate) {
- isDisabled = date.getTime() > endDate.getTime();
- }
+ var items = [];
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
- }
+ for (i = 1; i <= length; i += 1) {
+ var _date = new Date(viewYear, viewMonth, i);
+ var _disabled2 = false;
- items.push(this.createItem({
- text: i,
- view: isDisabled ? 'day disabled' : isPicked ? 'day picked' : 'day',
- picked: isPicked,
- disabled: isDisabled,
- highlighted: viewYear === thisYear && viewMonth === thisMonth && date.getDate() === today
- }));
+ if (startDate) {
+ _disabled2 = _date.getTime() < startDate.getTime();
}
- // Render days picker
- // -----------------------------------------------------------------------
-
- this.$monthPrev.toggleClass(disabledClass, isPrevDisabled);
- this.$monthNext.toggleClass(disabledClass, isNextDisabled);
- this.$monthCurrent.
- toggleClass(disabledClass, isPrevDisabled && isNextDisabled).
- html(
- options.yearFirst ?
- viewYear + suffix + ' ' + months[viewMonth] :
- months[viewMonth] + ' ' + viewYear + suffix
- );
- this.$days.html(prevItems.join('') + items.join(' ') + nextItems.join(''));
- },
-
- click: function (e) {
- var $target = $(e.target);
- var options = this.options;
- var viewDate = this.viewDate;
- var viewYear;
- var viewMonth;
- var viewDay;
- var isYear;
- var year;
- var view;
-
- e.stopPropagation();
- e.preventDefault();
-
- if ($target.hasClass('disabled')) {
- return;
+ if (!_disabled2 && endDate) {
+ _disabled2 = _date.getTime() > endDate.getTime();
}
- viewYear = viewDate.getFullYear();
- viewMonth = viewDate.getMonth();
- viewDay = viewDate.getDate();
- view = $target.data('view');
+ if (!_disabled2 && filter) {
+ _disabled2 = filter.call($element, _date) === false;
+ }
- switch (view) {
- case 'years prev':
- case 'years next':
- viewYear = view === 'years prev' ? viewYear - 10 : viewYear + 10;
- year = $target.text();
- isYear = REGEXP_YEAR.test(year);
+ var _picked = viewYear === year && viewMonth === month && i === day;
+ var view = _picked ? 'day picked' : 'day';
- if (isYear) {
- viewYear = parseInt(year, 10);
- this.date = new Date(viewYear, viewMonth, min(viewDay, 28));
- }
+ items.push(this.createItem({
+ disabled: _disabled2,
+ picked: _picked,
+ highlighted: viewYear === thisYear && viewMonth === thisMonth && _date.getDate() === thisDay,
+ text: i,
+ view: _disabled2 ? 'day disabled' : view
+ }));
+ }
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.fillYears();
+ // Render days picker
+ // -----------------------------------------------------------------------
- if (isYear) {
- this.showView(VIEWS.MONTHS);
- this.pick('year');
- }
+ this.$monthPrev.toggleClass(disabledClass, prevDisabled);
+ this.$monthNext.toggleClass(disabledClass, nextDisabled);
+ this.$monthCurrent.toggleClass(disabledClass, prevDisabled && nextDisabled).html(options.yearFirst ? viewYear + yearSuffix + ' ' + monthsShort[viewMonth] : monthsShort[viewMonth] + ' ' + viewYear + yearSuffix);
+ this.$days.html(prevItems.join('') + items.join('') + nextItems.join(''));
+ }
+};
- break;
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
- case 'year prev':
- case 'year next':
- viewYear = view === 'year prev' ? viewYear - 1 : viewYear + 1;
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.fillMonths();
- break;
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- case 'year current':
- if (this.format.hasYear) {
- this.showView(VIEWS.YEARS);
- }
+var _window = window;
+var document$1 = _window.document;
- break;
+var $document = $(document$1);
- case 'year picked':
- if (this.format.hasMonth) {
- this.showView(VIEWS.MONTHS);
- } else {
- $target.addClass(options.pickedClass)
- .siblings()
- .removeClass(options.pickedClass);
- this.hideView();
- }
-
- this.pick('year');
- break;
+// Classes
+var CLASS_TOP_LEFT = NAMESPACE + '-top-left';
+var CLASS_TOP_RIGHT = NAMESPACE + '-top-right';
+var CLASS_BOTTOM_LEFT = NAMESPACE + '-bottom-left';
+var CLASS_BOTTOM_RIGHT = NAMESPACE + '-bottom-right';
+var CLASS_PLACEMENTS = [CLASS_TOP_LEFT, CLASS_TOP_RIGHT, CLASS_BOTTOM_LEFT, CLASS_BOTTOM_RIGHT].join(' ');
- case 'year':
- viewYear = parseInt($target.text(), 10);
- this.date = new Date(viewYear, viewMonth, min(viewDay, 28));
-
- if (this.format.hasMonth) {
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.showView(VIEWS.MONTHS);
- } else {
- $target.addClass(options.pickedClass)
- .siblings()
- .removeClass(options.pickedClass);
- this.hideView();
- }
-
- this.pick('year');
- break;
+var Datepicker = function () {
+ function Datepicker(element) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- case 'month prev':
- case 'month next':
- viewMonth = view === 'month prev' ? viewMonth - 1 : view === 'month next' ? viewMonth + 1 : viewMonth;
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.fillDays();
- break;
+ _classCallCheck(this, Datepicker);
- case 'month current':
- if (this.format.hasMonth) {
- this.showView(VIEWS.MONTHS);
- }
+ this.$element = $(element);
+ this.element = element;
+ this.options = $.extend({}, DEFAULTS, LANGUAGES[options.language], options);
+ this.built = false;
+ this.shown = false;
+ this.isInput = false;
+ this.inline = false;
+ this.initialValue = '';
+ this.initialDate = null;
+ this.startDate = null;
+ this.endDate = null;
+ this.init();
+ }
- break;
+ _createClass(Datepicker, [{
+ key: 'init',
+ value: function init() {
+ var $this = this.$element,
+ options = this.options;
+ var startDate = options.startDate,
+ endDate = options.endDate,
+ date = options.date;
- case 'month picked':
- if (this.format.hasDay) {
- this.showView(VIEWS.DAYS);
- } else {
- $target.addClass(options.pickedClass)
- .siblings()
- .removeClass(options.pickedClass);
- this.hideView();
- }
-
- this.pick('month');
- break;
- case 'month':
- viewMonth = $.inArray($target.text(), options.monthsShort);
- this.date = new Date(viewYear, viewMonth, min(viewDay, 28));
-
- if (this.format.hasDay) {
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.showView(VIEWS.DAYS);
- } else {
- $target.addClass(options.pickedClass)
- .siblings()
- .removeClass(options.pickedClass);
- this.hideView();
- }
-
- this.pick('month');
- break;
+ this.$trigger = $(options.trigger);
+ this.isInput = $this.is('input') || $this.is('textarea');
+ this.inline = options.inline && (options.container || !this.isInput);
+ this.format = parseFormat(options.format);
- case 'day prev':
- case 'day next':
- case 'day':
- viewMonth = view === 'day prev' ? viewMonth - 1 : view === 'day next' ? viewMonth + 1 : viewMonth;
- viewDay = parseInt($target.text(), 10);
- this.date = new Date(viewYear, viewMonth, viewDay);
- this.viewDate = new Date(viewYear, viewMonth, viewDay);
- this.fillDays();
+ var initialValue = this.getValue();
- if (view === 'day') {
- this.hideView();
- }
+ this.initialValue = initialValue;
+ this.oldValue = initialValue;
+ date = this.parseDate(date || initialValue);
- this.pick('day');
- break;
+ if (startDate) {
+ startDate = this.parseDate(startDate);
- case 'day picked':
- this.hideView();
- this.pick('day');
- break;
+ if (date.getTime() < startDate.getTime()) {
+ date = new Date(startDate);
+ }
- // No default
+ this.startDate = startDate;
}
- },
- clickDoc: function (e) {
- var target = e.target;
- var element = this.$element[0];
- var trigger = this.$trigger[0];
- var ignored;
+ if (endDate) {
+ endDate = this.parseDate(endDate);
- while (target !== document) {
- if (target === trigger || target === element) {
- ignored = true;
- break;
+ if (startDate && endDate.getTime() < startDate.getTime()) {
+ endDate = new Date(startDate);
}
- target = target.parentNode;
- }
+ if (date.getTime() > endDate.getTime()) {
+ date = new Date(endDate);
+ }
- if (!ignored) {
- this.hide();
+ this.endDate = endDate;
}
- },
- keyup: function () {
- this.update();
- },
+ this.date = date;
+ this.viewDate = new Date(date);
+ this.initialDate = new Date(this.date);
+ this.bind();
- keyupDoc: function (e) {
- if (this.isInput && e.target !== this.$element[0] &&
- this.isShown && (e.key === 'Tab' || e.keyCode === 9)) {
- this.hide();
+ if (options.autoShow || this.inline) {
+ this.show();
}
- },
-
- getValue: function () {
- var $this = this.$element;
- var val = '';
- if (this.isInput) {
- val = $this.val();
- } else if (this.isInline) {
- if (this.options.container) {
- val = $this.text();
- }
- } else {
- val = $this.text();
+ if (options.autoPick) {
+ this.pick();
+ }
+ }
+ }, {
+ key: 'build',
+ value: function build() {
+ if (this.built) {
+ return;
}
- return val;
- },
+ this.built = true;
- setValue: function (val) {
- var $this = this.$element;
+ var $this = this.$element,
+ options = this.options;
- val = isString(val) ? val : '';
+ var $picker = $(options.template);
- if (this.isInput) {
- $this.val(val);
- } else if (this.isInline) {
- if (this.options.container) {
- $this.text(val);
- }
- } else {
- $this.text(val);
- }
- },
+ this.$picker = $picker;
+ this.$week = $picker.find(selectorOf('week'));
+ // Years view
+ this.$yearsPicker = $picker.find(selectorOf('years picker'));
+ this.$yearsPrev = $picker.find(selectorOf('years prev'));
+ this.$yearsNext = $picker.find(selectorOf('years next'));
+ this.$yearsCurrent = $picker.find(selectorOf('years current'));
+ this.$years = $picker.find(selectorOf('years'));
- // Methods
- // -------------------------------------------------------------------------
+ // Months view
+ this.$monthsPicker = $picker.find(selectorOf('months picker'));
+ this.$yearPrev = $picker.find(selectorOf('year prev'));
+ this.$yearNext = $picker.find(selectorOf('year next'));
+ this.$yearCurrent = $picker.find(selectorOf('year current'));
+ this.$months = $picker.find(selectorOf('months'));
- // Show the datepicker
- show: function () {
- if (!this.isBuilt) {
- this.build();
+ // Days view
+ this.$daysPicker = $picker.find(selectorOf('days picker'));
+ this.$monthPrev = $picker.find(selectorOf('month prev'));
+ this.$monthNext = $picker.find(selectorOf('month next'));
+ this.$monthCurrent = $picker.find(selectorOf('month current'));
+ this.$days = $picker.find(selectorOf('days'));
+
+ if (this.inline) {
+ $(options.container || $this).append($picker.addClass(NAMESPACE + '-inline'));
+ } else {
+ $(document$1.body).append($picker.addClass(NAMESPACE + '-dropdown'));
+ $picker.addClass(CLASS_HIDE);
}
- if (this.isShown) {
+ this.renderWeek();
+ }
+ }, {
+ key: 'unbuild',
+ value: function unbuild() {
+ if (!this.built) {
return;
}
- if (this.trigger(EVENT_SHOW).isDefaultPrevented()) {
- return;
- }
+ this.built = false;
+ this.$picker.remove();
+ }
+ }, {
+ key: 'bind',
+ value: function bind() {
+ var options = this.options,
+ $this = this.$element;
- this.isShown = true;
- this.$picker.removeClass(CLASS_HIDE).on(EVENT_CLICK, $.proxy(this.click, this));
- this.showView(this.options.startView);
- if (!this.isInline) {
- $window.on(EVENT_RESIZE, (this._place = proxy(this.place, this)));
- $document.on(EVENT_CLICK, (this._clickDoc = proxy(this.clickDoc, this)));
- $document.on(EVENT_KEYUP, (this._keyupDoc = proxy(this.keyupDoc, this)));
- this.place();
+ if ($.isFunction(options.show)) {
+ $this.on(EVENT_SHOW, options.show);
}
- },
- // Hide the datepicker
- hide: function () {
- if (!this.isShown) {
- return;
+ if ($.isFunction(options.hide)) {
+ $this.on(EVENT_HIDE, options.hide);
}
- if (this.trigger(EVENT_HIDE).isDefaultPrevented()) {
- return;
+ if ($.isFunction(options.pick)) {
+ $this.on(EVENT_PICK, options.pick);
}
- this.isShown = false;
- this.$picker.addClass(CLASS_HIDE).off(EVENT_CLICK, this.click);
-
- if (!this.isInline) {
- $window.off(EVENT_RESIZE, this._place);
- $document.off(EVENT_CLICK, this._clickDoc);
- $document.off(EVENT_KEYUP, this._keyupDoc);
+ if (this.isInput) {
+ $this.on(EVENT_KEYUP, $.proxy(this.keyup, this));
}
- },
- toggle: function () {
- if (this.isShown) {
- this.hide();
- } else {
- this.show();
+ if (!this.inline) {
+ if (options.trigger) {
+ this.$trigger.on(EVENT_CLICK, $.proxy(this.toggle, this));
+ } else if (this.isInput) {
+ $this.on(EVENT_FOCUS, $.proxy(this.show, this));
+ } else {
+ $this.on(EVENT_CLICK, $.proxy(this.show, this));
+ }
}
- },
+ }
+ }, {
+ key: 'unbind',
+ value: function unbind() {
+ var $this = this.$element,
+ options = this.options;
- // Update the datepicker with the current input value
- update: function () {
- var value = this.getValue();
- if (value === this.oldValue) {
- return;
+ if ($.isFunction(options.show)) {
+ $this.off(EVENT_SHOW, options.show);
}
- this.setDate(value, true);
- this.oldValue = value;
- },
-
- /**
- * Pick the current date to the element
- *
- * @param {String} _view (private)
- */
- pick: function (_view) {
- var $this = this.$element;
- var date = this.date;
-
- if (this.trigger(EVENT_PICK, {
- view: _view || '',
- date: date
- }).isDefaultPrevented()) {
- return;
+ if ($.isFunction(options.hide)) {
+ $this.off(EVENT_HIDE, options.hide);
}
- this.setValue(date = this.formatDate(this.date));
+ if ($.isFunction(options.pick)) {
+ $this.off(EVENT_PICK, options.pick);
+ }
if (this.isInput) {
- $this.trigger('change');
+ $this.off(EVENT_KEYUP, this.keyup);
}
- },
- // Reset the datepicker
- reset: function () {
- this.setDate(this.initialDate, true);
- this.setValue(this.initialValue);
-
- if (this.isShown) {
- this.showView(this.options.startView);
+ if (!this.inline) {
+ if (options.trigger) {
+ this.$trigger.off(EVENT_CLICK, this.toggle);
+ } else if (this.isInput) {
+ $this.off(EVENT_FOCUS, this.show);
+ } else {
+ $this.off(EVENT_CLICK, this.show);
+ }
}
- },
-
- /**
- * Get the month name with given argument or the current date
- *
- * @param {Number} month (optional)
- * @param {Boolean} short (optional)
- * @return {String} (month name)
- */
- getMonthName: function (month, short) {
- var options = this.options;
- var months = options.months;
+ }
+ }, {
+ key: 'showView',
+ value: function showView(view) {
+ var $yearsPicker = this.$yearsPicker,
+ $monthsPicker = this.$monthsPicker,
+ $daysPicker = this.$daysPicker,
+ format = this.format;
- if ($.isNumeric(month)) {
- month = Number(month);
- } else if (isUndefined(short)) {
- short = month;
- }
- if (short === true) {
- months = options.monthsShort;
- }
+ if (format.hasYear || format.hasMonth || format.hasDay) {
+ switch (Number(view)) {
+ case VIEWS.YEARS:
+ $monthsPicker.addClass(CLASS_HIDE);
+ $daysPicker.addClass(CLASS_HIDE);
- return months[isNumber(month) ? month : this.date.getMonth()];
- },
-
- /**
- * Get the day name with given argument or the current date
- *
- * @param {Number} day (optional)
- * @param {Boolean} short (optional)
- * @param {Boolean} min (optional)
- * @return {String} (day name)
- */
- getDayName: function (day, short, min) {
- var options = this.options;
- var days = options.days;
+ if (format.hasYear) {
+ this.renderYears();
+ $yearsPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.DAYS);
+ }
- if ($.isNumeric(day)) {
- day = Number(day);
- } else {
- if (isUndefined(min)) {
- min = short;
- }
+ break;
- if (isUndefined(short)) {
- short = day;
- }
- }
+ case VIEWS.MONTHS:
+ $yearsPicker.addClass(CLASS_HIDE);
+ $daysPicker.addClass(CLASS_HIDE);
- days = min === true ? options.daysMin : short === true ? options.daysShort : days;
-
- return days[isNumber(day) ? day : this.date.getDay()];
- },
-
- /**
- * Get the current date
- *
- * @param {Boolean} formatted (optional)
- * @return {Date|String} (date)
- */
- getDate: function (formatted) {
- var date = this.date;
-
- return formatted ? this.formatDate(date) : new Date(date);
- },
-
- /**
- * Set the current date with a new date
- *
- * @param {Date} date
- * @param {Boolean} _isUpdated (private)
- */
- setDate: function (date, _isUpdated) {
- var filter = this.options.filter;
-
- if (isDate(date) || isString(date)) {
- date = this.parseDate(date);
-
- if ($.isFunction(filter) && filter.call(this.$element, date) === false) {
- return;
- }
+ if (format.hasMonth) {
+ this.renderMonths();
+ $monthsPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.YEARS);
+ }
- this.date = date;
- this.viewDate = new Date(date);
+ break;
- if (!_isUpdated) {
- this.pick();
- }
+ // case VIEWS.DAYS:
+ default:
+ $yearsPicker.addClass(CLASS_HIDE);
+ $monthsPicker.addClass(CLASS_HIDE);
- if (this.isBuilt) {
- this.fillAll();
- }
- }
- },
-
- /**
- * Set the start view date with a new date
- *
- * @param {Date} date
- */
- setStartDate: function (date) {
- if (isDate(date) || isString(date)) {
- this.startDate = this.parseDate(date);
-
- if (this.isBuilt) {
- this.fillAll();
- }
- }
- },
-
- /**
- * Set the end view date with a new date
- *
- * @param {Date} date
- */
- setEndDate: function (date) {
- if (isDate(date) || isString(date)) {
- this.endDate = this.parseDate(date);
-
- if (this.isBuilt) {
- this.fillAll();
+ if (format.hasDay) {
+ this.renderDays();
+ $daysPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.MONTHS);
+ }
}
}
- },
-
- /**
- * Parse a date string with the set date format
- *
- * @param {String} date
- * @return {Date} (parsed date)
- */
- parseDate: function (date) {
- var format = this.format;
- var parts = [];
- var length;
- var year;
- var day;
- var month;
- var val;
- var i;
-
- if (isDate(date)) {
- return new Date(date.getFullYear(), date.getMonth(), date.getDate());
- } else if (isString(date)) {
- parts = date.match(REGEXP_DIGITS) || [];
- }
-
- date = new Date();
- year = date.getFullYear();
- day = date.getDate();
- month = date.getMonth();
- length = format.parts.length;
-
- if (parts.length === length) {
- for (i = 0; i < length; i++) {
- val = parseInt(parts[i], 10) || 1;
-
- switch (format.parts[i]) {
- case 'dd':
- case 'd':
- day = val;
- break;
-
- case 'mm':
- case 'm':
- month = val - 1;
- break;
-
- case 'yy':
- year = 2000 + val;
- break;
-
- case 'yyyy':
- year = val;
- break;
-
- // No default
- }
- }
+ }
+ }, {
+ key: 'hideView',
+ value: function hideView() {
+ if (!this.inline && this.options.autoHide) {
+ this.hide();
}
-
- return new Date(year, month, day);
- },
-
- /**
- * Format a date object to a string with the set date format
- *
- * @param {Date} date
- * @return {String} (formatted date)
- */
- formatDate: function (date) {
- var format = this.format;
- var formatted = '';
- var length;
- var year;
- var part;
- var val;
- var i;
-
- if (isDate(date)) {
- formatted = format.source;
- year = date.getFullYear();
- val = {
- d: date.getDate(),
- m: date.getMonth() + 1,
- yy: year.toString().substring(2),
- yyyy: year
- };
-
- val.dd = (val.d < 10 ? '0' : '') + val.d;
- val.mm = (val.m < 10 ? '0' : '') + val.m;
- length = format.parts.length;
-
- for (i = 0; i < length; i++) {
- part = format.parts[i];
- formatted = formatted.replace(part, val[part]);
- }
+ }
+ }, {
+ key: 'place',
+ value: function place() {
+ if (this.inline) {
+ return;
}
- return formatted;
- },
+ var $this = this.$element,
+ options = this.options,
+ $picker = this.$picker;
- // Destroy the datepicker and remove the instance from the target element
- destroy: function () {
- this.unbind();
- this.unbuild();
- this.$element.removeData(NAMESPACE);
- }
- };
-
- Datepicker.LANGUAGES = {};
+ var containerWidth = $document.outerWidth();
+ var containerHeight = $document.outerHeight();
+ var elementWidth = $this.outerWidth();
+ var elementHeight = $this.outerHeight();
+ var width = $picker.width();
+ var height = $picker.height();
- Datepicker.DEFAULTS = {
- // Show the datepicker automatically when initialized
- autoShow: false,
+ var _$this$offset = $this.offset(),
+ left = _$this$offset.left,
+ top = _$this$offset.top;
- // Hide the datepicker automatically when picked
- autoHide: false,
+ var offset = parseFloat(options.offset);
+ var placement = CLASS_TOP_LEFT;
- // Pick the initial date automatically when initialized
- autoPick: false,
+ if (isNaN(offset)) {
+ offset = 10;
+ }
- // Enable inline mode
- inline: false,
+ if (top > height && top + elementHeight + height > containerHeight) {
+ top -= height + offset;
+ placement = CLASS_BOTTOM_LEFT;
+ } else {
+ top += elementHeight + offset;
+ }
- // A element (or selector) for putting the datepicker
- container: null,
+ if (left + width > containerWidth) {
+ left += elementWidth - width;
+ placement = placement.replace('left', 'right');
+ }
- // A element (or selector) for triggering the datepicker
- trigger: null,
+ $picker.removeClass(CLASS_PLACEMENTS).addClass(placement).css({
+ top: top,
+ left: left,
+ zIndex: parseInt(options.zIndex, 10)
+ });
+ }
- // The ISO language code (built-in: en-US)
- language: '',
+ // A shortcut for triggering custom events
- // The date string format
- format: 'mm/dd/yyyy',
+ }, {
+ key: 'trigger',
+ value: function trigger(type, data) {
+ var e = $.Event(type, data);
- // The initial date
- date: null,
+ this.$element.trigger(e);
- // The start view date
- startDate: null,
+ return e;
+ }
+ }, {
+ key: 'createItem',
+ value: function createItem(data) {
+ var options = this.options;
+ var itemTag = options.itemTag;
- // The end view date
- endDate: null,
+ var item = {
+ text: '',
+ view: '',
+ muted: false,
+ picked: false,
+ disabled: false,
+ highlighted: false
+ };
+ var classes = [];
- // The start view when initialized
- startView: 0, // 0 for days, 1 for months, 2 for years
+ $.extend(item, data);
- // The start day of the week
- weekStart: 0, // 0 for Sunday, 1 for Monday, 2 for Tuesday, 3 for Wednesday, 4 for Thursday, 5 for Friday, 6 for Saturday
+ if (item.muted) {
+ classes.push(options.mutedClass);
+ }
- // Show year before month on the datepicker header
- yearFirst: false,
+ if (item.highlighted) {
+ classes.push(options.highlightedClass);
+ }
- // A string suffix to the year number.
- yearSuffix: '',
+ if (item.picked) {
+ classes.push(options.pickedClass);
+ }
- // Days' name of the week.
- days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+ if (item.disabled) {
+ classes.push(options.disabledClass);
+ }
- // Shorter days' name
- daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ return '<' + itemTag + ' class="' + classes.join(' ') + '" data-view="' + item.view + '">' + item.text + '' + itemTag + '>';
+ }
+ }, {
+ key: 'getValue',
+ value: function getValue() {
+ var $this = this.$element;
- // Shortest days' name
- daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
+ return this.isInput ? $this.val() : $this.text();
+ }
+ }, {
+ key: 'setValue',
+ value: function setValue() {
+ var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
- // Months' name
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ var $this = this.$element;
- // Shorter months' name
- monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ if (this.isInput) {
+ $this.val(value);
+ } else {
+ $this.text(value);
+ }
+ }
+ }], [{
+ key: 'setDefaults',
+ value: function setDefaults() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- // A element tag for each item of years, months and days
- itemTag: 'li',
+ $.extend(DEFAULTS, LANGUAGES[options.language], options);
+ }
+ }]);
- // A class (CSS) for muted date item
- mutedClass: 'muted',
+ return Datepicker;
+}();
- // A class (CSS) for picked date item
- pickedClass: 'picked',
+$.extend(Datepicker.prototype, render, handlers, methods);
- // A class (CSS) for disabled date item
- disabledClass: 'disabled',
+var AnotherDatepicker = $.fn.datepicker;
- // A class (CSS) for highlight date item
- highlightedClass: 'highlighted',
+$.fn.datepicker = function jQueryDatepicker(option) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
- // The template of the datepicker
- template: (
- '' +
- '
' +
- '
' +
- '- ‹
' +
- '' +
- '- ›
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '- ‹
' +
- '' +
- '- ›
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '- ‹
' +
- '' +
- '- ›
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
'
- ),
+ var result = void 0;
- // The offset top or bottom of the datepicker from the element
- offset: 10,
+ this.each(function each() {
+ var $this = $(this);
+ var data = $this.data('datepicker');
- // The `z-index` of the datepicker
- zIndex: 1000,
-
- // Filter each date item (return `false` to disable a date item)
- filter: null,
-
- // Event shortcuts
- show: null,
- hide: null,
- pick: null
- };
+ if (!data) {
+ if (/destroy/.test(option)) {
+ return;
+ }
- Datepicker.setDefaults = function (options) {
- options = $.isPlainObject(options) ? options : {};
+ var options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
- if (options.language) {
- options = $.extend({}, Datepicker.LANGUAGES[options.language], options);
+ data = new Datepicker(this, options);
+ $this.data('datepicker', data);
}
- $.extend(Datepicker.DEFAULTS, options);
- };
-
- // Save the other datepicker
- Datepicker.other = $.fn.datepicker;
-
- // Register as jQuery plugin
- $.fn.datepicker = function (option) {
- var args = toArray(arguments, 1);
- var result;
-
- this.each(function () {
- var $this = $(this);
- var data = $this.data(NAMESPACE);
- var options;
- var fn;
-
- if (!data) {
- if (/destroy/.test(option)) {
- return;
- }
-
- options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
- $this.data(NAMESPACE, (data = new Datepicker(this, options)));
- }
+ if (typeof option === 'string') {
+ var fn = data[option];
- if (isString(option) && $.isFunction(fn = data[option])) {
+ if ($.isFunction(fn)) {
result = fn.apply(data, args);
}
- });
-
- return isUndefined(result) ? this : result;
- };
+ }
+ });
- $.fn.datepicker.Constructor = Datepicker;
- $.fn.datepicker.languages = Datepicker.LANGUAGES;
- $.fn.datepicker.setDefaults = Datepicker.setDefaults;
+ return typeof result !== 'undefined' ? result : this;
+};
- // No conflict
- $.fn.datepicker.noConflict = function () {
- $.fn.datepicker = Datepicker.other;
- return this;
- };
+$.fn.datepicker.Constructor = Datepicker;
+$.fn.datepicker.languages = LANGUAGES;
+$.fn.datepicker.setDefaults = Datepicker.setDefaults;
+$.fn.datepicker.noConflict = function noConflict() {
+ $.fn.datepicker = AnotherDatepicker;
+ return this;
+};
-});
+})));
diff --git a/dist/datepicker.min.css b/dist/datepicker.min.css
index 209b438..1d1e0b8 100644
--- a/dist/datepicker.min.css
+++ b/dist/datepicker.min.css
@@ -1,9 +1,10 @@
/*!
- * Datepicker v0.5.3
+ * Datepicker v0.6.0
* https://github.com/fengyuanchen/datepicker
- *
+ *
* Copyright (c) 2014-2017 Fengyuan Chen
* Released under the MIT license
- *
- * Date: 2017-06-15T11:00:53.699Z
- */.datepicker-container{font-size:12px;line-height:30px;position:fixed;z-index:-1;top:0;left:0;width:210px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;direction:ltr!important;-ms-touch-action:none;touch-action:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.datepicker-container:after,.datepicker-container:before{position:absolute;display:block;width:0;height:0;content:' ';border:5px solid transparent}.datepicker-dropdown{position:absolute;z-index:1;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;border:1px solid #ccc;-webkit-box-shadow:0 3px 6px #ccc;box-shadow:0 3px 6px #ccc}.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{top:-5px;left:10px;border-top:0}.datepicker-top-left:before,.datepicker-top-right:before{border-bottom-color:#39f}.datepicker-top-left:after,.datepicker-top-right:after{top:-4px;border-bottom-color:#fff}.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{bottom:-5px;left:10px;border-bottom:0}.datepicker-bottom-left:before,.datepicker-bottom-right:before{border-top-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-right:after{bottom:-4px;border-top-color:#fff}.datepicker-bottom-right:after,.datepicker-bottom-right:before,.datepicker-top-right:after,.datepicker-top-right:before{right:10px;left:auto}.datepicker-panel>ul:after,.datepicker-panel>ul:before{display:table;content:' '}.datepicker-panel>ul:after{clear:both}.datepicker-panel>ul{width:102%;margin:0;padding:0}.datepicker-panel>ul>li{float:left;width:30px;height:30px;margin:0;padding:0;list-style:none;cursor:pointer;text-align:center;background-color:#fff}.datepicker-panel>ul>li.highlighted,.datepicker-panel>ul>li:hover{background-color:#e6f2ff}.datepicker-panel>ul>li.muted,.datepicker-panel>ul>li.muted:hover{color:#999}.datepicker-panel>ul>li.highlighted:hover{background-color:#cce6ff}.datepicker-panel>ul>li.picked,.datepicker-panel>ul>li.picked:hover{color:#39f}.datepicker-panel>ul>li.disabled,.datepicker-panel>ul>li.disabled:hover{cursor:default;color:#ccc;background-color:#fff}.datepicker-panel>ul>li.disabled.highlighted,.datepicker-panel>ul>li.disabled:hover.highlighted{background-color:#e6f2ff}.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='month current'],.datepicker-panel>ul>li[data-view='years current'],.datepicker-panel>ul>li[data-view='year current']{width:150px}.datepicker-panel>ul[data-view=years]>li,.datepicker-panel>ul[data-view=months]>li{line-height:52.5px;width:52.5px;height:52.5px}.datepicker-panel>ul[data-view=week]>li,.datepicker-panel>ul[data-view=week]>li:hover{cursor:default;background-color:#fff}.datepicker-hide{display:none}
\ No newline at end of file
+ *
+ * Date: 2017-09-24T11:42:09.338Z
+ */.datepicker-container{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;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.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;box-shadow:0 3px 6px #ccc;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:lighten(#39f 35%)}.datepicker-panel>ul>li.muted,.datepicker-panel>ul>li.muted:hover{color:#999}.datepicker-panel>ul>li.highlighted{background-color:lighten(#39f 35%)}.datepicker-panel>ul>li.highlighted:hover{background-color:lighten(#39f 30%)}.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:lighten(#39f 35%)}.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}
+/*# sourceMappingURL=datepicker.min.css.map */
\ No newline at end of file
diff --git a/dist/datepicker.min.js b/dist/datepicker.min.js
index 96485ed..3d750f4 100644
--- a/dist/datepicker.min.js
+++ b/dist/datepicker.min.js
@@ -1 +1,10 @@
-!function(t){"function"==typeof define&&define.amd?define("datepicker",["jquery"],t):t("object"==typeof exports?require("jquery"):jQuery)}(function(t){"use strict";function e(t){return S.call(t).slice(8,-1).toLowerCase()}function i(t){return"string"==typeof t}function s(t){return"number"==typeof t&&!isNaN(t)}function a(t){return void 0===t}function n(t){return"date"===e(t)}function h(t,e){var i=[];return Array.from?Array.from(t).slice(e||0):(s(e)&&i.push(e),i.slice.apply(t,i))}function r(t,e){var i=h(arguments,2);return function(){return t.apply(e,i.concat(h(arguments)))}}function l(t){return t%4==0&&t%100!=0||t%400==0}function o(t,e){return[31,l(t)?29:28,31,30,31,30,31,31,30,31,30,31][e]}function d(t){var e,i,s=String(t).toLowerCase(),a=s.match(m);if(!a||0===a.length)throw new Error("Invalid date format.");for(t={source:s,parts:a},e=a.length,i=0;ia.getTime()&&(n=new Date(a)),this.endDate=a),this.date=n,this.viewDate=new Date(n),this.initialDate=new Date(this.date),this.bind(),(e.autoShow||this.isInline)&&this.show(),e.autoPick&&this.pick()},build:function(){var e,i=this.options,s=this.$element;this.isBuilt||(this.isBuilt=!0,this.$picker=e=t(i.template),this.$week=e.find('[data-view="week"]'),this.$yearsPicker=e.find('[data-view="years picker"]'),this.$yearsPrev=e.find('[data-view="years prev"]'),this.$yearsNext=e.find('[data-view="years next"]'),this.$yearsCurrent=e.find('[data-view="years current"]'),this.$years=e.find('[data-view="years"]'),this.$monthsPicker=e.find('[data-view="months picker"]'),this.$yearPrev=e.find('[data-view="year prev"]'),this.$yearNext=e.find('[data-view="year next"]'),this.$yearCurrent=e.find('[data-view="year current"]'),this.$months=e.find('[data-view="months"]'),this.$daysPicker=e.find('[data-view="days picker"]'),this.$monthPrev=e.find('[data-view="month prev"]'),this.$monthNext=e.find('[data-view="month next"]'),this.$monthCurrent=e.find('[data-view="month current"]'),this.$days=e.find('[data-view="days"]'),this.isInline?t(i.container||s).append(e.addClass("datepicker-inline")):(t(p.body).append(e.addClass("datepicker-dropdown")),e.addClass(b)),this.fillWeek())},unbuild:function(){this.isBuilt&&(this.isBuilt=!1,this.$picker.remove())},bind:function(){var e=this.options,i=this.$element;t.isFunction(e.show)&&i.on("show.datepicker",e.show),t.isFunction(e.hide)&&i.on("hide.datepicker",e.hide),t.isFunction(e.pick)&&i.on("pick.datepicker",e.pick),this.isInput&&i.on("keyup.datepicker",t.proxy(this.keyup,this)),this.isInline||(e.trigger?this.$trigger.on(y,t.proxy(this.toggle,this)):this.isInput?i.on("focus.datepicker",t.proxy(this.show,this)):i.on(y,t.proxy(this.show,this)))},unbind:function(){var e=this.options,i=this.$element;t.isFunction(e.show)&&i.off("show.datepicker",e.show),t.isFunction(e.hide)&&i.off("hide.datepicker",e.hide),t.isFunction(e.pick)&&i.off("pick.datepicker",e.pick),this.isInput&&i.off("keyup.datepicker",this.keyup),this.isInline||(e.trigger?this.$trigger.off(y,this.toggle):this.isInput?i.off("focus.datepicker",this.show):i.off(y,this.show))},showView:function(t){var e=this.$yearsPicker,i=this.$monthsPicker,s=this.$daysPicker,a=this.format;if(a.hasYear||a.hasMonth||a.hasDay)switch(g(t)){case C.YEARS:case"years":i.addClass(b),s.addClass(b),a.hasYear?(this.fillYears(),e.removeClass(b),this.place()):this.showView(C.DAYS);break;case C.MONTHS:case"months":e.addClass(b),s.addClass(b),a.hasMonth?(this.fillMonths(),i.removeClass(b),this.place()):this.showView(C.YEARS);break;default:e.addClass(b),i.addClass(b),a.hasDay?(this.fillDays(),s.removeClass(b),this.place()):this.showView(C.MONTHS)}},hideView:function(){!this.isInline&&this.options.autoHide&&this.hide()},place:function(){if(!this.isInline){var t=this.options,e=this.$element,i=this.$picker,s=f.outerWidth(),a=f.outerHeight(),n=e.outerWidth(),h=e.outerHeight(),r=i.width(),l=i.height(),o=e.offset(),d=o.left,c=o.top,u=parseFloat(t.offset)||10,p="datepicker-top-left";c>l&&c+h+l>a?(c-=l+u,p="datepicker-bottom-left"):c+=h+u,d+r>s&&(d=d+n-r,p=p.replace("left","right")),i.removeClass(D).addClass(p).css({top:c,left:d,zIndex:parseInt(t.zIndex,10)})}},trigger:function(e,i){var s=t.Event(e,i);return this.$element.trigger(s),s},createItem:function(e){var i=this.options,s=i.itemTag,a={text:"",view:"",muted:!1,picked:!1,disabled:!1,highlighted:!1},n=[];return t.extend(a,e),a.muted&&n.push(i.mutedClass),a.highlighted&&n.push(i.highlightedClass),a.picked&&n.push(i.pickedClass),a.disabled&&n.push(i.disabledClass),"<"+s+' class="'+n.join(" ")+'"'+(a.view?' data-view="'+a.view+'"':"")+">"+a.text+""+s+">"},fillAll:function(){this.fillYears(),this.fillMonths(),this.fillDays()},fillWeek:function(){var e,i=this.options,s=parseInt(i.weekStart,10)%7,a=i.daysMin,n="";for(a=t.merge(a.slice(s),a.slice(0,s)),e=0;e<=6;e++)n+=this.createItem({text:a[e]});this.$week.html(n)},fillYears:function(){var e,i=this.options,s=i.disabledClass||"",a=i.yearSuffix||"",n=t.isFunction(i.filter)&&i.filter,h=this.startDate,r=this.endDate,l=this.viewDate.getFullYear(),o=(new Date).getFullYear(),d=this.date,c=d.getFullYear(),u=!1,p=!1,f=!1,g=!1,w=!1,y="";for(e=-5;e<=6;e++)d=new Date(l+e,1,1),w=-5===e||6===e,g=l+e===c,f=!1,h&&(f=d.getFullYear()r.getFullYear(),6===e&&(p=f)),!f&&n&&(f=!1===n.call(this.$element,d)),y+=this.createItem({text:l+e,view:f?"year disabled":g?"year picked":"year",muted:w,picked:g,disabled:f,highlighted:d.getFullYear()===o});this.$yearsPrev.toggleClass(s,u),this.$yearsNext.toggleClass(s,p),this.$yearsCurrent.toggleClass(s,!0).html(l+-5+a+" - "+(l+6)+a),this.$years.html(y)},fillMonths:function(){var e,i=this.options,s=i.disabledClass||"",a=i.monthsShort,n=t.isFunction(i.filter)&&i.filter,h=this.startDate,r=this.endDate,l=this.viewDate.getFullYear(),o=new Date,d=o.getFullYear(),c=o.getMonth(),u=this.date,p=u.getFullYear(),f=u.getMonth(),g=!1,w=!1,y=!1,m=!1,k="";for(e=0;e<=11;e++)u=new Date(l,e,1),m=l===p&&e===f,y=!1,h&&(y=(g=u.getFullYear()===h.getFullYear())&&u.getMonth()r.getMonth(),console.log(w,u,r)),!y&&n&&(y=!1===n.call(this.$element,u)),k+=this.createItem({index:e,text:a[e],view:y?"month disabled":m?"month picked":"month",picked:m,disabled:y,highlighted:l===d&&u.getMonth()===c});this.$yearPrev.toggleClass(s,g),this.$yearNext.toggleClass(s,w),this.$yearCurrent.toggleClass(s,g&&w).html(l+i.yearSuffix||""),this.$months.html(k)},fillDays:function(){var e,i,s,a=this.options,n=a.disabledClass||"",h=a.yearSuffix||"",r=a.monthsShort,l=parseInt(a.weekStart,10)%7,d=t.isFunction(a.filter)&&a.filter,c=this.startDate,u=this.endDate,p=this.viewDate,f=p.getFullYear(),g=p.getMonth(),w=f,y=g,m=f,k=new Date,v=k.getFullYear(),D=k.getMonth(),b=k.getDate(),C=g,$=this.date,S=$.getFullYear(),x=$.getMonth(),F=$.getDate(),M=!1,I=!1,Y=!1,T=!1,V=[],A=[],N=[];for(0===g?(w-=1,y=11):y-=1,e=o(w,y),(s=($=new Date(f,g,1)).getDay()-l)<=0&&(s+=7),c&&(M=$.getTime()<=c.getTime()),i=e-(s-1);i<=e;i++)$=new Date(w,y,i),T=w===S&&y===x&&i===F,Y=!1,c&&(Y=$.getTime()=u.getTime()),i=1;i<=s;i++)$=new Date(m,C,i),T=m===S&&C===x&&i===F,Y=!1,u&&(Y=$.getTime()>u.getTime()),!Y&&d&&(Y=!1===d.call(this.$element,$)),A.push(this.createItem({text:i,view:"day next",muted:!0,picked:T,disabled:Y,highlighted:m===v&&C===D&&$.getDate()===b}));for(i=1;i<=e;i++)$=new Date(f,g,i),T=f===S&&g===x&&i===F,Y=!1,c&&(Y=$.getTime()u.getTime()),!Y&&d&&(Y=!1===d.call(this.$element,$)),N.push(this.createItem({text:i,view:Y?"day disabled":T?"day picked":"day",picked:T,disabled:Y,highlighted:f===v&&g===D&&$.getDate()===b}));this.$monthPrev.toggleClass(n,M),this.$monthNext.toggleClass(n,I),this.$monthCurrent.toggleClass(n,M&&I).html(a.yearFirst?f+h+" "+r[g]:r[g]+" "+f+h),this.$days.html(V.join("")+N.join(" ")+A.join(""))},click:function(e){var i,s,a,n,h,r,l=t(e.target),o=this.options,d=this.viewDate;if(e.stopPropagation(),e.preventDefault(),!l.hasClass("disabled"))switch(i=d.getFullYear(),s=d.getMonth(),a=d.getDate(),r=l.data("view")){case"years prev":case"years next":i="years prev"===r?i-10:i+10,h=l.text(),(n=v.test(h))&&(i=parseInt(h,10),this.date=new Date(i,s,$(a,28))),this.viewDate=new Date(i,s,$(a,28)),this.fillYears(),n&&(this.showView(C.MONTHS),this.pick("year"));break;case"year prev":case"year next":i="year prev"===r?i-1:i+1,this.viewDate=new Date(i,s,$(a,28)),this.fillMonths();break;case"year current":this.format.hasYear&&this.showView(C.YEARS);break;case"year picked":this.format.hasMonth?this.showView(C.MONTHS):(l.addClass(o.pickedClass).siblings().removeClass(o.pickedClass),this.hideView()),this.pick("year");break;case"year":i=parseInt(l.text(),10),this.date=new Date(i,s,$(a,28)),this.format.hasMonth?(this.viewDate=new Date(i,s,$(a,28)),this.showView(C.MONTHS)):(l.addClass(o.pickedClass).siblings().removeClass(o.pickedClass),this.hideView()),this.pick("year");break;case"month prev":case"month next":s="month prev"===r?s-1:"month next"===r?s+1:s,this.viewDate=new Date(i,s,$(a,28)),this.fillDays();break;case"month current":this.format.hasMonth&&this.showView(C.MONTHS);break;case"month picked":this.format.hasDay?this.showView(C.DAYS):(l.addClass(o.pickedClass).siblings().removeClass(o.pickedClass),this.hideView()),this.pick("month");break;case"month":s=t.inArray(l.text(),o.monthsShort),this.date=new Date(i,s,$(a,28)),this.format.hasDay?(this.viewDate=new Date(i,s,$(a,28)),this.showView(C.DAYS)):(l.addClass(o.pickedClass).siblings().removeClass(o.pickedClass),this.hideView()),this.pick("month");break;case"day prev":case"day next":case"day":s="day prev"===r?s-1:"day next"===r?s+1:s,a=parseInt(l.text(),10),this.date=new Date(i,s,a),this.viewDate=new Date(i,s,a),this.fillDays(),"day"===r&&this.hideView(),this.pick("day");break;case"day picked":this.hideView(),this.pick("day")}},clickDoc:function(t){for(var e,i=t.target,s=this.$element[0],a=this.$trigger[0];i!==p;){if(i===a||i===s){e=!0;break}i=i.parentNode}e||this.hide()},keyup:function(){this.update()},keyupDoc:function(t){this.isInput&&t.target!==this.$element[0]&&this.isShown&&("Tab"===t.key||9===t.keyCode)&&this.hide()},getValue:function(){var t=this.$element,e="";return this.isInput?e=t.val():this.isInline?this.options.container&&(e=t.text()):e=t.text(),e},setValue:function(t){var e=this.$element;t=i(t)?t:"",this.isInput?e.val(t):this.isInline?this.options.container&&e.text(t):e.text(t)},show:function(){this.isBuilt||this.build(),this.isShown||this.trigger("show.datepicker").isDefaultPrevented()||(this.isShown=!0,this.$picker.removeClass(b).on(y,t.proxy(this.click,this)),this.showView(this.options.startView),this.isInline||(u.on("resize.datepicker",this._place=r(this.place,this)),f.on(y,this._clickDoc=r(this.clickDoc,this)),f.on("keyup.datepicker",this._keyupDoc=r(this.keyupDoc,this)),this.place()))},hide:function(){this.isShown&&(this.trigger("hide.datepicker").isDefaultPrevented()||(this.isShown=!1,this.$picker.addClass(b).off(y,this.click),this.isInline||(u.off("resize.datepicker",this._place),f.off(y,this._clickDoc),f.off("keyup.datepicker",this._keyupDoc))))},toggle:function(){this.isShown?this.hide():this.show()},update:function(){var t=this.getValue();t!==this.oldValue&&(this.setDate(t,!0),this.oldValue=t)},pick:function(t){var e=this.$element,i=this.date;this.trigger("pick.datepicker",{view:t||"",date:i}).isDefaultPrevented()||(this.setValue(i=this.formatDate(this.date)),this.isInput&&e.trigger("change"))},reset:function(){this.setDate(this.initialDate,!0),this.setValue(this.initialValue),this.isShown&&this.showView(this.options.startView)},getMonthName:function(e,i){var n=this.options,h=n.months;return t.isNumeric(e)?e=g(e):a(i)&&(i=e),!0===i&&(h=n.monthsShort),h[s(e)?e:this.date.getMonth()]},getDayName:function(e,i,n){var h=this.options,r=h.days;return t.isNumeric(e)?e=g(e):(a(n)&&(n=i),a(i)&&(i=e)),(r=!0===n?h.daysMin:!0===i?h.daysShort:r)[s(e)?e:this.date.getDay()]},getDate:function(t){var e=this.date;return t?this.formatDate(e):new Date(e)},setDate:function(e,s){var a=this.options.filter;if(n(e)||i(e)){if(e=this.parseDate(e),t.isFunction(a)&&!1===a.call(this.$element,e))return;this.date=e,this.viewDate=new Date(e),s||this.pick(),this.isBuilt&&this.fillAll()}},setStartDate:function(t){(n(t)||i(t))&&(this.startDate=this.parseDate(t),this.isBuilt&&this.fillAll())},setEndDate:function(t){(n(t)||i(t))&&(this.endDate=this.parseDate(t),this.isBuilt&&this.fillAll())},parseDate:function(t){var e,s,a,h,r,l,o=this.format,d=[];if(n(t))return new Date(t.getFullYear(),t.getMonth(),t.getDate());if(i(t)&&(d=t.match(k)||[]),t=new Date,s=t.getFullYear(),a=t.getDate(),h=t.getMonth(),e=o.parts.length,d.length===e)for(l=0;l',offset:10,zIndex:1e3,filter:null,show:null,hide:null,pick:null},c.setDefaults=function(e){(e=t.isPlainObject(e)?e:{}).language&&(e=t.extend({},c.LANGUAGES[e.language],e)),t.extend(c.DEFAULTS,e)},c.other=t.fn.datepicker,t.fn.datepicker=function(e){var s,n=h(arguments,1);return this.each(function(){var a,h,r=t(this),l=r.data(w);if(!l){if(/destroy/.test(e))return;a=t.extend({},r.data(),t.isPlainObject(e)&&e),r.data(w,l=new c(this,a))}i(e)&&t.isFunction(h=l[e])&&(s=h.apply(l,n))}),a(s)?this:s},t.fn.datepicker.Constructor=c,t.fn.datepicker.languages=c.LANGUAGES,t.fn.datepicker.setDefaults=c.setDefaults,t.fn.datepicker.noConflict=function(){return t.fn.datepicker=c.other,this}});
\ No newline at end of file
+/*!
+ * Datepicker v0.6.0
+ * https://github.com/fengyuanchen/datepicker
+ *
+ * Copyright (c) 2014-2017 Fengyuan Chen
+ * Released under the MIT license
+ *
+ * Date: 2017-09-24T11:42:13.421Z
+ */
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],t):t(e.jQuery)}(this,function(e){"use strict";function t(e){return k.call(e).slice(8,-1).toLowerCase()}function i(e){return"string"==typeof e}function a(e){return"number"==typeof e&&!w(e)}function s(e){return void 0===e}function n(e){return"date"===t(e)}function r(e,t){for(var i=arguments.length,a=Array(i>2?i-2:0),s=2;s',offset:10,zIndex:1e3,filter:null,show:null,hide:null,pick:null},f="datepicker",g="click.datepicker",y="datepicker-hide",v={},m={DAYS:0,MONTHS:1,YEARS:2},k=Object.prototype.toString,w=Number.isNaN||window.isNaN,D=/(y|m|d)+/g,b=window.document,C=e(window),$=e(b),x=/\d+/g,M={show:function(){this.built||this.build(),this.shown||this.trigger("show.datepicker").isDefaultPrevented()||(this.shown=!0,this.$picker.removeClass(y).on(g,e.proxy(this.click,this)),this.showView(this.options.startView),this.inline||(C.on("resize.datepicker",this.onResize=r(this.place,this)),$.on(g,this.onGlobalClick=r(this.globalClick,this)),$.on("keyup.datepicker",this.onGlobalKeyup=r(this.globalKeyup,this)),this.place()))},hide:function(){this.shown&&(this.trigger("hide.datepicker").isDefaultPrevented()||(this.shown=!1,this.$picker.addClass(y).off(g,this.click),this.inline||(C.off("resize.datepicker",this.onResize),$.off(g,this.onGlobalClick),$.off("keyup.datepicker",this.onGlobalKeyup))))},toggle:function(){this.shown?this.hide():this.show()},update:function(){var e=this.getValue();e!==this.oldValue&&(this.setDate(e,!0),this.oldValue=e)},pick:function(e){var t=this.$element,i=this.date;this.trigger("pick.datepicker",{view:e||"",date:i}).isDefaultPrevented()||(i=this.formatDate(this.date),this.setValue(i),this.isInput&&(t.trigger("input"),t.trigger("change")))},reset:function(){this.setDate(this.initialDate,!0),this.setValue(this.initialValue),this.shown&&this.showView(this.options.startView)},getMonthName:function(t,i){var n=this.options,r=n.monthsShort,h=n.months;return e.isNumeric(t)?t=Number(t):s(i)&&(i=t),!0===i&&(h=r),h[a(t)?t:this.date.getMonth()]},getDayName:function(t,i,n){var r=this.options,h=r.days;return e.isNumeric(t)?t=Number(t):(s(n)&&(n=i),s(i)&&(i=t)),n?h=r.daysMin:i&&(h=r.daysShort),h[a(t)?t:this.date.getDay()]},getDate:function(e){var t=this.date;return e?this.formatDate(t):new Date(t)},setDate:function(t,a){var s=this.options.filter;if(n(t)||i(t)){if(t=this.parseDate(t),e.isFunction(s)&&!1===s.call(this.$element,t))return;this.date=t,this.viewDate=new Date(t),a||this.pick(),this.built&&this.render()}},setStartDate:function(e){(n(e)||i(e))&&(this.startDate=this.parseDate(e),this.built&&this.render())},setEndDate:function(e){(n(e)||i(e))&&(this.endDate=this.parseDate(e),this.built&&this.render())},parseDate:function(t){var a=this.format,s=[];if(n(t))return new Date(t.getFullYear(),t.getMonth(),t.getDate());i(t)&&(s=t.match(x)||[]),t=new Date;var r=a.parts.length,h=t.getFullYear(),o=t.getDate(),l=t.getMonth();return s.length===r&&e.each(s,function(e,t){var i=parseInt(t,10)||1;switch(a.parts[e]){case"dd":case"d":o=i;break;case"mm":case"m":l=i-1;break;case"yy":h=2e3+i;break;case"yyyy":h=i}}),new Date(h,l,o)},formatDate:function(t){var i=this.format,a="";if(n(t)){var s=t.getFullYear(),r={d:t.getDate(),m:t.getMonth()+1,yy:s.toString().substring(2),yyyy:s};r.dd=(r.d<10?"0":"")+r.d,r.mm=(r.m<10?"0":"")+r.m,a=i.source,e.each(i.parts,function(e,t){a=a.replace(t,r[t])})}return a},destroy:function(){this.unbind(),this.unbuild(),this.$element.removeData(f)}},S={click:function(t){var i=e(t.target),a=this.options,s=this.viewDate,n=this.format;if(t.stopPropagation(),t.preventDefault(),!i.hasClass("disabled")){var r=i.data("view"),h=s.getFullYear(),o=s.getMonth(),l=s.getDate();switch(r){case"years prev":case"years next":h="years prev"===r?h-10:h+10,this.viewDate=new Date(h,o,d(h,o,l)),this.renderYears();break;case"year prev":case"year next":h="year prev"===r?h-1:h+1,this.viewDate=new Date(h,o,d(h,o,l)),this.renderMonths();break;case"year current":n.hasYear&&this.showView(m.YEARS);break;case"year picked":n.hasMonth?this.showView(m.MONTHS):(i.addClass(a.pickedClass).siblings().removeClass(a.pickedClass),this.hideView()),this.pick("year");break;case"year":h=parseInt(i.text(),10),this.date=new Date(h,o,d(h,o,l)),n.hasMonth?(this.viewDate=new Date(this.date),this.showView(m.MONTHS)):(i.addClass(a.pickedClass).siblings().removeClass(a.pickedClass),this.hideView()),this.pick("year");break;case"month prev":case"month next":o="month prev"===r?o-1:o+1,this.viewDate=new Date(h,o,d(h,o,l)),this.renderDays();break;case"month current":n.hasMonth&&this.showView(m.MONTHS);break;case"month picked":n.hasDay?this.showView(m.DAYS):(i.addClass(a.pickedClass).siblings().removeClass(a.pickedClass),this.hideView()),this.pick("month");break;case"month":o=e.inArray(i.text(),a.monthsShort),this.date=new Date(h,o,d(h,o,l)),n.hasDay?(this.viewDate=new Date(h,o,d(h,o,l)),this.showView(m.DAYS)):(i.addClass(a.pickedClass).siblings().removeClass(a.pickedClass),this.hideView()),this.pick("month");break;case"day prev":case"day next":case"day":"day prev"===r?o-=1:"day next"===r&&(o+=1),l=parseInt(i.text(),10),this.date=new Date(h,o,l),this.viewDate=new Date(h,o,l),this.renderDays(),"day"===r&&this.hideView(),this.pick("day");break;case"day picked":this.hideView(),this.pick("day")}}},globalClick:function(e){for(var t=e.target,i=this.element,a=this.$trigger[0],s=!0;t!==document;){if(t===a||t===i){s=!1;break}t=t.parentNode}s&&this.hide()},keyup:function(){this.update()},globalKeyup:function(e){var t=e.target,i=e.key,a=e.keyCode;this.isInput&&t!==this.element&&this.shown&&("Tab"===i||9===a)&&this.hide()}},F={render:function(){this.renderYears(),this.renderMonths(),this.renderDays()},renderWeek:function(){var t=this,i=[],a=this.options,s=a.weekStart,n=a.daysMin;s=parseInt(s,10)%7,n=n.slice(s).concat(n.slice(0,s)),e.each(n,function(e,a){i.push(t.createItem({text:a}))}),this.$week.html(i.join(""))},renderYears:function(){var e=this.options,t=this.startDate,i=this.endDate,a=e.disabledClass,s=e.filter,n=e.yearSuffix,r=this.viewDate.getFullYear(),h=(new Date).getFullYear(),o=this.date.getFullYear(),l=[],d=!1,u=!1,c=void 0;for(c=-5;c<=6;c+=1){var p=new Date(r+c,1,1),f=!1;t&&(f=p.getFullYear()i.getFullYear(),6===c&&(u=f)),!f&&s&&(f=!1===s.call(this.$element,p));var g=r+c===o,y=g?"year picked":"year";l.push(this.createItem({picked:g,disabled:f,muted:-5===c||6===c,text:r+c,view:f?"year disabled":y,highlighted:p.getFullYear()===h}))}this.$yearsPrev.toggleClass(a,d),this.$yearsNext.toggleClass(a,u),this.$yearsCurrent.toggleClass(a,!0).html(r+-5+n+" - "+(r+6)+n),this.$years.html(l.join(""))},renderMonths:function(){var t=this.options,i=this.startDate,a=this.endDate,s=this.viewDate,n=t.disabledClass||"",r=t.monthsShort,h=e.isFunction(t.filter)&&t.filter,o=s.getFullYear(),l=new Date,d=l.getFullYear(),u=l.getMonth(),c=this.date.getFullYear(),p=this.date.getMonth(),f=[],g=!1,y=!1,v=void 0;for(v=0;v<=11;v+=1){var m=new Date(o,v,1),k=!1;i&&(k=(g=m.getFullYear()===i.getFullYear())&&m.getMonth()a.getMonth()),!k&&h&&(k=!1===h.call(this.$element,m));var w=o===c&&v===p,D=w?"month picked":"month";f.push(this.createItem({disabled:k,picked:w,highlighted:o===d&&m.getMonth()===u,index:v,text:r[v],view:k?"month disabled":D}))}this.$yearPrev.toggleClass(n,g),this.$yearNext.toggleClass(n,y),this.$yearCurrent.toggleClass(n,g&&y).html(o+t.yearSuffix||""),this.$months.html(f.join(""))},renderDays:function(){var e=this.$element,t=this.options,i=this.startDate,a=this.endDate,s=this.viewDate,n=this.date,r=t.disabledClass,h=t.filter,o=t.monthsShort,d=t.weekStart,u=t.yearSuffix,c=s.getFullYear(),p=s.getMonth(),f=new Date,g=f.getFullYear(),y=f.getMonth(),v=f.getDate(),m=n.getFullYear(),k=n.getMonth(),w=n.getDate(),D=void 0,b=void 0,C=void 0,$=[],x=c,M=p,S=!1;0===p?(x-=1,M=11):M-=1,D=l(x,M);var F=new Date(c,p,1);for((C=F.getDay()-parseInt(d,10)%7)<=0&&(C+=7),i&&(S=F.getTime()<=i.getTime()),b=D-(C-1);b<=D;b+=1){var Y=new Date(x,M,b),T=!1;i&&(T=Y.getTime()=a.getTime()),b=1;b<=C;b+=1){var j=new Date(I,N,b),O=I===m&&N===k&&b===w,H=!1;a&&(H=j.getTime()>a.getTime()),!H&&h&&(H=!1===h.call(e,j)),V.push(this.createItem({disabled:H,picked:O,highlighted:I===g&&N===y&&j.getDate()===v,muted:!0,text:b,view:"day next"}))}var q=[];for(b=1;b<=D;b+=1){var E=new Date(c,p,b),z=!1;i&&(z=E.getTime()a.getTime()),!z&&h&&(z=!1===h.call(e,E));var W=c===m&&p===k&&b===w,J=W?"day picked":"day";q.push(this.createItem({disabled:z,picked:W,highlighted:c===g&&p===y&&E.getDate()===v,text:b,view:z?"day disabled":J}))}this.$monthPrev.toggleClass(r,S),this.$monthNext.toggleClass(r,P),this.$monthCurrent.toggleClass(r,S&&P).html(t.yearFirst?c+u+" "+o[p]:o[p]+" "+c+u),this.$days.html($.join("")+q.join("")+V.join(""))}},Y=function(){function e(e,t){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};c(this,t),this.$element=e(i),this.element=i,this.options=e.extend({},p,v[a.language],a),this.built=!1,this.shown=!1,this.isInput=!1,this.inline=!1,this.initialValue="",this.initialDate=null,this.startDate=null,this.endDate=null,this.init()}return Y(t,[{key:"init",value:function(){var t=this.$element,i=this.options,a=i.startDate,s=i.endDate,n=i.date;this.$trigger=e(i.trigger),this.isInput=t.is("input")||t.is("textarea"),this.inline=i.inline&&(i.container||!this.isInput),this.format=u(i.format);var r=this.getValue();this.initialValue=r,this.oldValue=r,n=this.parseDate(n||r),a&&(a=this.parseDate(a),n.getTime()s.getTime()&&(n=new Date(s)),this.endDate=s),this.date=n,this.viewDate=new Date(n),this.initialDate=new Date(this.date),this.bind(),(i.autoShow||this.inline)&&this.show(),i.autoPick&&this.pick()}},{key:"build",value:function(){if(!this.built){this.built=!0;var t=this.$element,i=this.options,a=e(i.template);this.$picker=a,this.$week=a.find(h("week")),this.$yearsPicker=a.find(h("years picker")),this.$yearsPrev=a.find(h("years prev")),this.$yearsNext=a.find(h("years next")),this.$yearsCurrent=a.find(h("years current")),this.$years=a.find(h("years")),this.$monthsPicker=a.find(h("months picker")),this.$yearPrev=a.find(h("year prev")),this.$yearNext=a.find(h("year next")),this.$yearCurrent=a.find(h("year current")),this.$months=a.find(h("months")),this.$daysPicker=a.find(h("days picker")),this.$monthPrev=a.find(h("month prev")),this.$monthNext=a.find(h("month next")),this.$monthCurrent=a.find(h("month current")),this.$days=a.find(h("days")),this.inline?e(i.container||t).append(a.addClass("datepicker-inline")):(e(T.body).append(a.addClass("datepicker-dropdown")),a.addClass(y)),this.renderWeek()}}},{key:"unbuild",value:function(){this.built&&(this.built=!1,this.$picker.remove())}},{key:"bind",value:function(){var t=this.options,i=this.$element;e.isFunction(t.show)&&i.on("show.datepicker",t.show),e.isFunction(t.hide)&&i.on("hide.datepicker",t.hide),e.isFunction(t.pick)&&i.on("pick.datepicker",t.pick),this.isInput&&i.on("keyup.datepicker",e.proxy(this.keyup,this)),this.inline||(t.trigger?this.$trigger.on(g,e.proxy(this.toggle,this)):this.isInput?i.on("focus.datepicker",e.proxy(this.show,this)):i.on(g,e.proxy(this.show,this)))}},{key:"unbind",value:function(){var t=this.$element,i=this.options;e.isFunction(i.show)&&t.off("show.datepicker",i.show),e.isFunction(i.hide)&&t.off("hide.datepicker",i.hide),e.isFunction(i.pick)&&t.off("pick.datepicker",i.pick),this.isInput&&t.off("keyup.datepicker",this.keyup),this.inline||(i.trigger?this.$trigger.off(g,this.toggle):this.isInput?t.off("focus.datepicker",this.show):t.off(g,this.show))}},{key:"showView",value:function(e){var t=this.$yearsPicker,i=this.$monthsPicker,a=this.$daysPicker,s=this.format;if(s.hasYear||s.hasMonth||s.hasDay)switch(Number(e)){case m.YEARS:i.addClass(y),a.addClass(y),s.hasYear?(this.renderYears(),t.removeClass(y),this.place()):this.showView(m.DAYS);break;case m.MONTHS:t.addClass(y),a.addClass(y),s.hasMonth?(this.renderMonths(),i.removeClass(y),this.place()):this.showView(m.YEARS);break;default:t.addClass(y),i.addClass(y),s.hasDay?(this.renderDays(),a.removeClass(y),this.place()):this.showView(m.MONTHS)}}},{key:"hideView",value:function(){!this.inline&&this.options.autoHide&&this.hide()}},{key:"place",value:function(){if(!this.inline){var e=this.$element,t=this.options,i=this.$picker,a=V.outerWidth(),s=V.outerHeight(),n=e.outerWidth(),r=e.outerHeight(),h=i.width(),o=i.height(),l=e.offset(),d=l.left,u=l.top,c=parseFloat(t.offset),p="datepicker-top-left";w(c)&&(c=10),u>o&&u+r+o>s?(u-=o+c,p="datepicker-bottom-left"):u+=r+c,d+h>a&&(d+=n-h,p=p.replace("left","right")),i.removeClass(I).addClass(p).css({top:u,left:d,zIndex:parseInt(t.zIndex,10)})}}},{key:"trigger",value:function(t,i){var a=e.Event(t,i);return this.$element.trigger(a),a}},{key:"createItem",value:function(t){var i=this.options,a=i.itemTag,s={text:"",view:"",muted:!1,picked:!1,disabled:!1,highlighted:!1},n=[];return e.extend(s,t),s.muted&&n.push(i.mutedClass),s.highlighted&&n.push(i.highlightedClass),s.picked&&n.push(i.pickedClass),s.disabled&&n.push(i.disabledClass),"<"+a+' class="'+n.join(" ")+'" data-view="'+s.view+'">'+s.text+""+a+">"}},{key:"getValue",value:function(){var e=this.$element;return this.isInput?e.val():e.text()}},{key:"setValue",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this.$element;this.isInput?t.val(e):t.text(e)}}],[{key:"setDefaults",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e.extend(p,v[t.language],t)}}]),t}();e.extend(N.prototype,F,S,M);var P=e.fn.datepicker;e.fn.datepicker=function(t){for(var i=arguments.length,a=Array(i>1?i-1:0),s=1;s ul:before,
-.datepicker-panel > ul:after {
- display: table;
-
- content: ' ';
+.datepicker-panel > ul {
+ margin: 0;
+ padding: 0;
+ width: 102%;
}
-.datepicker-panel > ul:after {
- clear: both;
+.datepicker-panel > ul::before,
+.datepicker-panel > ul::after {
+ content: " ";
+ display: table;
}
-.datepicker-panel > ul {
- width: 102%;
- margin: 0;
- padding: 0;
+.datepicker-panel > ul::after {
+ clear: both;
}
.datepicker-panel > ul > li {
+ background-color: #fff;
+ cursor: pointer;
float: left;
-
- width: 30px;
height: 30px;
+ list-style: none;
margin: 0;
padding: 0;
-
- list-style: none;
-
- cursor: pointer;
text-align: center;
-
- background-color: #fff;
+ width: 30px;
}
.datepicker-panel > ul > li:hover {
- background-color: #e6f2ff;
+ background-color: lighten(#39f 35%);
}
.datepicker-panel > ul > li.muted,
@@ -168,11 +147,11 @@
}
.datepicker-panel > ul > li.highlighted {
- background-color: #e6f2ff;
+ background-color: lighten(#39f 35%);
}
.datepicker-panel > ul > li.highlighted:hover {
- background-color: #cce6ff;
+ background-color: lighten(#39f 30%);
}
.datepicker-panel > ul > li.picked,
@@ -182,46 +161,43 @@
.datepicker-panel > ul > li.disabled,
.datepicker-panel > ul > li.disabled:hover {
- cursor: default;
-
- color: #ccc;
background-color: #fff;
+ color: #ccc;
+ cursor: default;
}
.datepicker-panel > ul > li.disabled.highlighted,
.datepicker-panel > ul > li.disabled:hover.highlighted {
- background-color: #e6f2ff;
+ background-color: lighten(#39f 35%);
}
-.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'] {
+.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='years current'],
-.datepicker-panel > ul > li[data-view='year current'],
-.datepicker-panel > ul > li[data-view='month current'] {
+.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 {
+.datepicker-panel > ul[data-view="years"] > li,
+.datepicker-panel > ul[data-view="months"] > li {
+ height: 52.5px;
line-height: 52.5px;
-
width: 52.5px;
- height: 52.5px;
}
-.datepicker-panel > ul[data-view='week'] > li,
-.datepicker-panel > ul[data-view='week'] > li:hover {
- cursor: default;
-
+.datepicker-panel > ul[data-view="week"] > li,
+.datepicker-panel > ul[data-view="week"] > li:hover {
background-color: #fff;
+ cursor: default;
}
.datepicker-hide {
diff --git a/docs/js/datepicker.js b/docs/js/datepicker.js
index 66a74d3..2b6560f 100644
--- a/docs/js/datepicker.js
+++ b/docs/js/datepicker.js
@@ -1,1567 +1,1517 @@
/*!
- * Datepicker v0.5.5
+ * Datepicker v0.6.0
* https://github.com/fengyuanchen/datepicker
*
* Copyright (c) 2014-2017 Fengyuan Chen
* Released under the MIT license
*
- * Date: 2017-09-10T09:16:17.133Z
+ * Date: 2017-09-24T11:42:13.421Z
*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
+ typeof define === 'function' && define.amd ? define(['jquery'], factory) :
+ (factory(global.jQuery));
+}(this, (function ($) { 'use strict';
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as anonymous module.
- define('datepicker', ['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node / CommonJS
- factory(require('jquery'));
- } else {
- // Browser globals.
- factory(jQuery);
+$ = $ && $.hasOwnProperty('default') ? $['default'] : $;
+
+var DEFAULTS = {
+ // Show the datepicker automatically when initialized
+ autoShow: false,
+
+ // Hide the datepicker automatically when picked
+ autoHide: false,
+
+ // Pick the initial date automatically when initialized
+ autoPick: false,
+
+ // Enable inline mode
+ inline: false,
+
+ // A element (or selector) for putting the datepicker
+ container: null,
+
+ // A element (or selector) for triggering the datepicker
+ trigger: null,
+
+ // The ISO language code (built-in: en-US)
+ language: '',
+
+ // The date string format
+ format: 'mm/dd/yyyy',
+
+ // The initial date
+ date: null,
+
+ // The start view date
+ startDate: null,
+
+ // The end view date
+ endDate: null,
+
+ // The start view when initialized
+ startView: 0, // 0 for days, 1 for months, 2 for years
+
+ // The start day of the week
+ // 0 for Sunday, 1 for Monday, 2 for Tuesday, 3 for Wednesday,
+ // 4 for Thursday, 5 for Friday, 6 for Saturday
+ weekStart: 0,
+
+ // Show year before month on the datepicker header
+ yearFirst: false,
+
+ // A string suffix to the year number.
+ yearSuffix: '',
+
+ // Days' name of the week.
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+
+ // Shorter days' name
+ daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+
+ // Shortest days' name
+ daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
+
+ // Months' name
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+
+ // Shorter months' name
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+
+ // A element tag for each item of years, months and days
+ itemTag: 'li',
+
+ // A class (CSS) for muted date item
+ mutedClass: 'muted',
+
+ // A class (CSS) for picked date item
+ pickedClass: 'picked',
+
+ // A class (CSS) for disabled date item
+ disabledClass: 'disabled',
+
+ // A class (CSS) for highlight date item
+ highlightedClass: 'highlighted',
+
+ // The template of the datepicker
+ template: '',
+
+ // The offset top or bottom of the datepicker from the element
+ offset: 10,
+
+ // The `z-index` of the datepicker
+ zIndex: 1000,
+
+ // Filter each date item (return `false` to disable a date item)
+ filter: null,
+
+ // Event shortcuts
+ show: null,
+ hide: null,
+ pick: null
+};
+
+var NAMESPACE = 'datepicker';
+var EVENT_CLICK = 'click.' + NAMESPACE;
+var EVENT_FOCUS = 'focus.' + NAMESPACE;
+var EVENT_HIDE = 'hide.' + NAMESPACE;
+var EVENT_KEYUP = 'keyup.' + NAMESPACE;
+var EVENT_PICK = 'pick.' + NAMESPACE;
+var EVENT_RESIZE = 'resize.' + NAMESPACE;
+var EVENT_SHOW = 'show.' + NAMESPACE;
+var CLASS_HIDE = NAMESPACE + '-hide';
+var LANGUAGES = {};
+var VIEWS = {
+ DAYS: 0,
+ MONTHS: 1,
+ YEARS: 2
+};
+
+var toString = Object.prototype.toString;
+
+
+function typeOf(obj) {
+ return toString.call(obj).slice(8, -1).toLowerCase();
+}
+
+function isString(value) {
+ return typeof value === 'string';
+}
+
+var isNaN = Number.isNaN || window.isNaN;
+
+function isNumber(value) {
+ return typeof value === 'number' && !isNaN(value);
+}
+
+function isUndefined(value) {
+ return typeof value === 'undefined';
+}
+
+function isDate(value) {
+ return typeOf(value) === 'date';
+}
+
+function proxy(fn, context) {
+ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
}
-})(function ($) {
-
- 'use strict';
-
- var $window = $(window);
- var document = window.document;
- var $document = $(document);
- var Number = window.Number;
- var NAMESPACE = 'datepicker';
-
- // Events
- var EVENT_CLICK = 'click.' + NAMESPACE;
- var EVENT_KEYUP = 'keyup.' + NAMESPACE;
- var EVENT_FOCUS = 'focus.' + NAMESPACE;
- var EVENT_RESIZE = 'resize.' + NAMESPACE;
- var EVENT_SHOW = 'show.' + NAMESPACE;
- var EVENT_HIDE = 'hide.' + NAMESPACE;
- var EVENT_PICK = 'pick.' + NAMESPACE;
-
- // RegExps
- var REGEXP_FORMAT = /(y|m|d)+/g;
- var REGEXP_DIGITS = /\d+/g;
- var REGEXP_YEAR = /^\d{2,4}$/;
-
- // Classes
- var CLASS_INLINE = NAMESPACE + '-inline';
- var CLASS_DROPDOWN = NAMESPACE + '-dropdown';
- var CLASS_TOP_LEFT = NAMESPACE + '-top-left';
- var CLASS_TOP_RIGHT = NAMESPACE + '-top-right';
- var CLASS_BOTTOM_LEFT = NAMESPACE + '-bottom-left';
- var CLASS_BOTTOM_RIGHT = NAMESPACE + '-bottom-right';
- var CLASS_PLACEMENTS = [
- CLASS_TOP_LEFT,
- CLASS_TOP_RIGHT,
- CLASS_BOTTOM_LEFT,
- CLASS_BOTTOM_RIGHT
- ].join(' ');
- var CLASS_HIDE = NAMESPACE + '-hide';
-
- // Views
- var VIEWS = {
- DAYS: 0,
- MONTHS: 1,
- YEARS: 2
+
+ return function () {
+ for (var _len2 = arguments.length, args2 = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+ args2[_key2] = arguments[_key2];
+ }
+
+ return fn.apply(context, args.concat(args2));
};
+}
- // Maths
- var min = Math.min;
+function selectorOf(view) {
+ return '[data-view="' + view + '"]';
+}
- // Utilities
- var toString = Object.prototype.toString;
+function isLeapYear(year) {
+ return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
+}
- function typeOf(obj) {
- return toString.call(obj).slice(8, -1).toLowerCase();
- }
+function getDaysInMonth(year, month) {
+ return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
+}
- function isString(str) {
- return typeof str === 'string';
- }
+function getMinDay(year, month, day) {
+ return Math.min(day, getDaysInMonth(year, month));
+}
- function isNumber(num) {
- return typeof num === 'number' && !isNaN(num);
- }
+var formatParts = /(y|m|d)+/g;
- function isUndefined(obj) {
- return typeof obj === 'undefined';
- }
+function parseFormat(format) {
+ var source = String(format).toLowerCase();
+ var parts = source.match(formatParts);
- function isDate(date) {
- return typeOf(date) === 'date';
+ if (!parts || parts.length === 0) {
+ throw new Error('Invalid date format.');
}
- function toArray(obj, offset) {
- var args = [];
+ format = {
+ source: source,
+ parts: parts
+ };
- if (Array.from) {
- return Array.from(obj).slice(offset || 0);
- }
+ $.each(parts, function (i, part) {
+ switch (part) {
+ case 'dd':
+ case 'd':
+ format.hasDay = true;
+ break;
- // This is necessary for IE8
- if (isNumber(offset)) {
- args.push(offset);
- }
+ case 'mm':
+ case 'm':
+ format.hasMonth = true;
+ break;
- return args.slice.apply(obj, args);
- }
+ case 'yyyy':
+ case 'yy':
+ format.hasYear = true;
+ break;
- // Custom proxy to avoid jQuery's guid
- function proxy(fn, context) {
- var args = toArray(arguments, 2);
+ default:
+ }
+ });
- return function () {
- return fn.apply(context, args.concat(toArray(arguments)));
- };
- }
+ return format;
+}
- function isLeapYear(year) {
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
- }
+var _window$1 = window;
+var document$2 = _window$1.document;
- function getDaysInMonth(year, month) {
- return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
- }
+var $window = $(window);
+var $document$1 = $(document$2);
+var REGEXP_DIGITS = /\d+/g;
- function parseFormat(format) {
- var source = String(format).toLowerCase();
- var parts = source.match(REGEXP_FORMAT);
- var length;
- var i;
+var methods = {
+ // Show the datepicker
+ show: function show() {
+ if (!this.built) {
+ this.build();
+ }
- if (!parts || parts.length === 0) {
- throw new Error('Invalid date format.');
+ if (this.shown) {
+ return;
}
- format = {
- source: source,
- parts: parts
- };
+ if (this.trigger(EVENT_SHOW).isDefaultPrevented()) {
+ return;
+ }
- length = parts.length;
+ this.shown = true;
+ this.$picker.removeClass(CLASS_HIDE).on(EVENT_CLICK, $.proxy(this.click, this));
+ this.showView(this.options.startView);
- for (i = 0; i < length; i++) {
- switch (parts[i]) {
- case 'dd':
- case 'd':
- format.hasDay = true;
- break;
+ if (!this.inline) {
+ $window.on(EVENT_RESIZE, this.onResize = proxy(this.place, this));
+ $document$1.on(EVENT_CLICK, this.onGlobalClick = proxy(this.globalClick, this));
+ $document$1.on(EVENT_KEYUP, this.onGlobalKeyup = proxy(this.globalKeyup, this));
+ this.place();
+ }
+ },
- case 'mm':
- case 'm':
- format.hasMonth = true;
- break;
- case 'yyyy':
- case 'yy':
- format.hasYear = true;
- break;
+ // Hide the datepicker
+ hide: function hide() {
+ if (!this.shown) {
+ return;
+ }
- // No default
- }
+ if (this.trigger(EVENT_HIDE).isDefaultPrevented()) {
+ return;
}
- return format;
- }
+ this.shown = false;
+ this.$picker.addClass(CLASS_HIDE).off(EVENT_CLICK, this.click);
+
+ if (!this.inline) {
+ $window.off(EVENT_RESIZE, this.onResize);
+ $document$1.off(EVENT_CLICK, this.onGlobalClick);
+ $document$1.off(EVENT_KEYUP, this.onGlobalKeyup);
+ }
+ },
+ toggle: function toggle() {
+ if (this.shown) {
+ this.hide();
+ } else {
+ this.show();
+ }
+ },
+
- function Datepicker(element, options) {
- options = $.isPlainObject(options) ? options : {};
+ // Update the datepicker with the current input value
+ update: function update() {
+ var value = this.getValue();
- if (options.language) {
- // Priority: Datepicker.DEFAULTS < Datepicker.LANGUAGES < options
- options = $.extend({}, Datepicker.LANGUAGES[options.language], options);
+ if (value === this.oldValue) {
+ return;
}
- this.$element = $(element);
- this.options = $.extend({}, Datepicker.DEFAULTS, options);
- this.isBuilt = false;
- this.isShown = false;
- this.isInput = false;
- this.isInline = false;
- this.initialValue = '';
- this.initialDate = null;
- this.startDate = null;
- this.endDate = null;
- this.init();
- }
+ this.setDate(value, true);
+ this.oldValue = value;
+ },
- Datepicker.prototype = {
- constructor: Datepicker,
- init: function () {
- var options = this.options;
- var $this = this.$element;
- var startDate = options.startDate;
- var endDate = options.endDate;
- var date = options.date;
+ /**
+ * Pick the current date to the element
+ *
+ * @param {String} _view (private)
+ */
+ pick: function pick(_view) {
+ var $this = this.$element;
+ var date = this.date;
- this.$trigger = $(options.trigger);
- this.isInput = $this.is('input') || $this.is('textarea');
- this.isInline = options.inline && (options.container || !this.isInput);
- this.format = parseFormat(options.format);
- this.oldValue = this.initialValue = this.getValue();
- date = this.parseDate(date || this.initialValue);
- if (startDate) {
- startDate = this.parseDate(startDate);
+ if (this.trigger(EVENT_PICK, {
+ view: _view || '',
+ date: date
+ }).isDefaultPrevented()) {
+ return;
+ }
- if (date.getTime() < startDate.getTime()) {
- date = new Date(startDate);
- }
+ date = this.formatDate(this.date);
+ this.setValue(date);
- this.startDate = startDate;
- }
+ if (this.isInput) {
+ $this.trigger('input');
+ $this.trigger('change');
+ }
+ },
- if (endDate) {
- endDate = this.parseDate(endDate);
- if (startDate && endDate.getTime() < startDate.getTime()) {
- endDate = new Date(startDate);
- }
+ // Reset the datepicker
+ reset: function reset() {
+ this.setDate(this.initialDate, true);
+ this.setValue(this.initialValue);
- if (date.getTime() > endDate.getTime()) {
- date = new Date(endDate);
- }
+ if (this.shown) {
+ this.showView(this.options.startView);
+ }
+ },
+
+
+ /**
+ * Get the month name with given argument or the current date
+ *
+ * @param {Number} month (optional)
+ * @param {Boolean} short (optional)
+ * @return {String} (month name)
+ */
+ getMonthName: function getMonthName(month, short) {
+ var options = this.options;
+ var monthsShort = options.monthsShort;
+ var months = options.months;
+
+
+ if ($.isNumeric(month)) {
+ month = Number(month);
+ } else if (isUndefined(short)) {
+ short = month;
+ }
- this.endDate = endDate;
- }
+ if (short === true) {
+ months = monthsShort;
+ }
- this.date = date;
- this.viewDate = new Date(date);
- this.initialDate = new Date(this.date);
+ return months[isNumber(month) ? month : this.date.getMonth()];
+ },
- this.bind();
- if (options.autoShow || this.isInline) {
- this.show();
+ /**
+ * Get the day name with given argument or the current date
+ *
+ * @param {Number} day (optional)
+ * @param {Boolean} short (optional)
+ * @param {Boolean} min (optional)
+ * @return {String} (day name)
+ */
+ getDayName: function getDayName(day, short, min) {
+ var options = this.options;
+ var days = options.days;
+
+
+ if ($.isNumeric(day)) {
+ day = Number(day);
+ } else {
+ if (isUndefined(min)) {
+ min = short;
}
- if (options.autoPick) {
- this.pick();
+ if (isUndefined(short)) {
+ short = day;
}
- },
+ }
- build: function () {
- var options = this.options;
- var $this = this.$element;
- var $picker;
+ if (min) {
+ days = options.daysMin;
+ } else if (short) {
+ days = options.daysShort;
+ }
- if (this.isBuilt) {
- return;
- }
+ return days[isNumber(day) ? day : this.date.getDay()];
+ },
- this.isBuilt = true;
- this.$picker = $picker = $(options.template);
- this.$week = $picker.find('[data-view="week"]');
+ /**
+ * Get the current date
+ *
+ * @param {Boolean} formatted (optional)
+ * @return {Date|String} (date)
+ */
+ getDate: function getDate(formatted) {
+ var date = this.date;
- // Years view
- this.$yearsPicker = $picker.find('[data-view="years picker"]');
- this.$yearsPrev = $picker.find('[data-view="years prev"]');
- this.$yearsNext = $picker.find('[data-view="years next"]');
- this.$yearsCurrent = $picker.find('[data-view="years current"]');
- this.$years = $picker.find('[data-view="years"]');
- // Months view
- this.$monthsPicker = $picker.find('[data-view="months picker"]');
- this.$yearPrev = $picker.find('[data-view="year prev"]');
- this.$yearNext = $picker.find('[data-view="year next"]');
- this.$yearCurrent = $picker.find('[data-view="year current"]');
- this.$months = $picker.find('[data-view="months"]');
+ return formatted ? this.formatDate(date) : new Date(date);
+ },
- // Days view
- this.$daysPicker = $picker.find('[data-view="days picker"]');
- this.$monthPrev = $picker.find('[data-view="month prev"]');
- this.$monthNext = $picker.find('[data-view="month next"]');
- this.$monthCurrent = $picker.find('[data-view="month current"]');
- this.$days = $picker.find('[data-view="days"]');
-
- if (this.isInline) {
- $(options.container || $this).append($picker.addClass(CLASS_INLINE));
- } else {
- $(document.body).append($picker.addClass(CLASS_DROPDOWN));
- $picker.addClass(CLASS_HIDE);
- }
- this.fillWeek();
- },
+ /**
+ * Set the current date with a new date
+ *
+ * @param {Date} date
+ * @param {Boolean} _updated (private)
+ */
+ setDate: function setDate(date, _updated) {
+ var filter = this.options.filter;
+
- unbuild: function () {
- if (!this.isBuilt) {
+ if (isDate(date) || isString(date)) {
+ date = this.parseDate(date);
+
+ if ($.isFunction(filter) && filter.call(this.$element, date) === false) {
return;
}
- this.isBuilt = false;
- this.$picker.remove();
- },
-
- bind: function () {
- var options = this.options;
- var $this = this.$element;
+ this.date = date;
+ this.viewDate = new Date(date);
- if ($.isFunction(options.show)) {
- $this.on(EVENT_SHOW, options.show);
+ if (!_updated) {
+ this.pick();
}
- if ($.isFunction(options.hide)) {
- $this.on(EVENT_HIDE, options.hide);
+ if (this.built) {
+ this.render();
}
+ }
+ },
- if ($.isFunction(options.pick)) {
- $this.on(EVENT_PICK, options.pick);
- }
- if (this.isInput) {
- $this.on(EVENT_KEYUP, $.proxy(this.keyup, this));
- }
+ /**
+ * Set the start view date with a new date
+ *
+ * @param {Date} date
+ */
+ setStartDate: function setStartDate(date) {
+ if (isDate(date) || isString(date)) {
+ this.startDate = this.parseDate(date);
- if (!this.isInline) {
- if (options.trigger) {
- this.$trigger.on(EVENT_CLICK, $.proxy(this.toggle, this));
- } else if (this.isInput) {
- $this.on(EVENT_FOCUS, $.proxy(this.show, this));
- } else {
- $this.on(EVENT_CLICK, $.proxy(this.show, this));
- }
+ if (this.built) {
+ this.render();
}
- },
+ }
+ },
- unbind: function () {
- var options = this.options;
- var $this = this.$element;
- if ($.isFunction(options.show)) {
- $this.off(EVENT_SHOW, options.show);
- }
+ /**
+ * Set the end view date with a new date
+ *
+ * @param {Date} date
+ */
+ setEndDate: function setEndDate(date) {
+ if (isDate(date) || isString(date)) {
+ this.endDate = this.parseDate(date);
- if ($.isFunction(options.hide)) {
- $this.off(EVENT_HIDE, options.hide);
+ if (this.built) {
+ this.render();
}
+ }
+ },
- if ($.isFunction(options.pick)) {
- $this.off(EVENT_PICK, options.pick);
- }
- if (this.isInput) {
- $this.off(EVENT_KEYUP, this.keyup);
- }
+ /**
+ * Parse a date string with the set date format
+ *
+ * @param {String} date
+ * @return {Date} (parsed date)
+ */
+ parseDate: function parseDate(date) {
+ var format = this.format;
- if (!this.isInline) {
- if (options.trigger) {
- this.$trigger.off(EVENT_CLICK, this.toggle);
- } else if (this.isInput) {
- $this.off(EVENT_FOCUS, this.show);
- } else {
- $this.off(EVENT_CLICK, this.show);
- }
- }
- },
+ var parts = [];
- showView: function (view) {
- var $yearsPicker = this.$yearsPicker;
- var $monthsPicker = this.$monthsPicker;
- var $daysPicker = this.$daysPicker;
- var format = this.format;
+ if (isDate(date)) {
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
+ } else if (isString(date)) {
+ parts = date.match(REGEXP_DIGITS) || [];
+ }
- if (format.hasYear || format.hasMonth || format.hasDay) {
- switch (Number(view)) {
- case VIEWS.YEARS:
- case 'years':
- $monthsPicker.addClass(CLASS_HIDE);
- $daysPicker.addClass(CLASS_HIDE);
+ date = new Date();
- if (format.hasYear) {
- this.fillYears();
- $yearsPicker.removeClass(CLASS_HIDE);
- this.place();
- } else {
- this.showView(VIEWS.DAYS);
- }
+ var length = format.parts.length;
+
+ var year = date.getFullYear();
+ var day = date.getDate();
+ var month = date.getMonth();
+ if (parts.length === length) {
+ $.each(parts, function (i, part) {
+ var value = parseInt(part, 10) || 1;
+
+ switch (format.parts[i]) {
+ case 'dd':
+ case 'd':
+ day = value;
break;
- case VIEWS.MONTHS:
- case 'months':
- $yearsPicker.addClass(CLASS_HIDE);
- $daysPicker.addClass(CLASS_HIDE);
+ case 'mm':
+ case 'm':
+ month = value - 1;
+ break;
- if (format.hasMonth) {
- this.fillMonths();
- $monthsPicker.removeClass(CLASS_HIDE);
- this.place();
- } else {
- this.showView(VIEWS.YEARS);
- }
+ case 'yy':
+ year = 2000 + value;
+ break;
+ case 'yyyy':
+ year = value;
break;
- // case VIEWS.DAYS:
- // case 'days':
default:
- $yearsPicker.addClass(CLASS_HIDE);
- $monthsPicker.addClass(CLASS_HIDE);
-
- if (format.hasDay) {
- this.fillDays();
- $daysPicker.removeClass(CLASS_HIDE);
- this.place();
- } else {
- this.showView(VIEWS.MONTHS);
- }
}
- }
- },
+ });
+ }
- hideView: function () {
- if (!this.isInline && this.options.autoHide) {
- this.hide();
- }
- },
+ return new Date(year, month, day);
+ },
- place: function () {
- if (this.isInline) {
- return;
- }
- var options = this.options;
- var $this = this.$element;
- var $picker = this.$picker;
- var containerWidth = $document.outerWidth();
- var containerHeight = $document.outerHeight();
- var elementWidth = $this.outerWidth();
- var elementHeight = $this.outerHeight();
- var width = $picker.width();
- var height = $picker.height();
- var offsets = $this.offset();
- var left = offsets.left;
- var top = offsets.top;
- var offset = parseFloat(options.offset) || 10;
- var placement = CLASS_TOP_LEFT;
+ /**
+ * Format a date object to a string with the set date format
+ *
+ * @param {Date} date
+ * @return {String} (formatted date)
+ */
+ formatDate: function formatDate(date) {
+ var format = this.format;
- if (top > height && top + elementHeight + height > containerHeight) {
- top -= height + offset;
- placement = CLASS_BOTTOM_LEFT;
- } else {
- top += elementHeight + offset;
- }
-
- if (left + width > containerWidth) {
- left = left + elementWidth - width;
- placement = placement.replace('left', 'right');
- }
+ var formatted = '';
- $picker.removeClass(CLASS_PLACEMENTS).addClass(placement).css({
- top: top,
- left: left,
- zIndex: parseInt(options.zIndex, 10)
+ if (isDate(date)) {
+ var year = date.getFullYear();
+ var values = {
+ d: date.getDate(),
+ m: date.getMonth() + 1,
+ yy: year.toString().substring(2),
+ yyyy: year
+ };
+
+ values.dd = (values.d < 10 ? '0' : '') + values.d;
+ values.mm = (values.m < 10 ? '0' : '') + values.m;
+ formatted = format.source;
+ $.each(format.parts, function (i, part) {
+ formatted = formatted.replace(part, values[part]);
});
- },
+ }
- // A shortcut for triggering custom events
- trigger: function (type, data) {
- var e = $.Event(type, data);
+ return formatted;
+ },
- this.$element.trigger(e);
- return e;
- },
+ // Destroy the datepicker and remove the instance from the target element
+ destroy: function destroy() {
+ this.unbind();
+ this.unbuild();
+ this.$element.removeData(NAMESPACE);
+ }
+};
- createItem: function (data) {
- var options = this.options;
- var itemTag = options.itemTag;
- var defaults = {
- text: '',
- view: '',
- muted: false,
- picked: false,
- disabled: false,
- highlighted: false
- };
- var classes = [];
+var handlers = {
+ click: function click(e) {
+ var $target = $(e.target);
+ var options = this.options,
+ viewDate = this.viewDate,
+ format = this.format;
- $.extend(defaults, data);
- if (defaults.muted) {
- classes.push(options.mutedClass);
- }
+ e.stopPropagation();
+ e.preventDefault();
- if (defaults.highlighted) {
- classes.push(options.highlightedClass);
- }
+ if ($target.hasClass('disabled')) {
+ return;
+ }
- if (defaults.picked) {
- classes.push(options.pickedClass);
- }
+ var view = $target.data('view');
+ var viewYear = viewDate.getFullYear();
+ var viewMonth = viewDate.getMonth();
+ var viewDay = viewDate.getDate();
- if (defaults.disabled) {
- classes.push(options.disabledClass);
- }
+ switch (view) {
+ case 'years prev':
+ case 'years next':
+ {
+ viewYear = view === 'years prev' ? viewYear - 10 : viewYear + 10;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderYears();
+ break;
+ }
- return (
- '<' + itemTag + ' class="' + classes.join(' ') + '"' +
- (defaults.view ? ' data-view="' + defaults.view + '"' : '') +
- '>' +
- defaults.text +
- '' + itemTag + '>'
- );
- },
-
- fillAll: function () {
- this.fillYears();
- this.fillMonths();
- this.fillDays();
- },
-
- fillWeek: function () {
- var options = this.options;
- var weekStart = parseInt(options.weekStart, 10) % 7;
- var days = options.daysMin;
- var list = '';
- var i;
+ case 'year prev':
+ case 'year next':
+ viewYear = view === 'year prev' ? viewYear - 1 : viewYear + 1;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderMonths();
+ break;
- days = $.merge(days.slice(weekStart), days.slice(0, weekStart));
+ case 'year current':
+ if (format.hasYear) {
+ this.showView(VIEWS.YEARS);
+ }
- for (i = 0; i <= 6; i++) {
- list += this.createItem({
- text: days[i]
- });
- }
+ break;
+
+ case 'year picked':
+ if (format.hasMonth) {
+ this.showView(VIEWS.MONTHS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
+ }
- this.$week.html(list);
- },
+ this.pick('year');
+ break;
- fillYears: function () {
- var options = this.options;
- var disabledClass = options.disabledClass || '';
- var suffix = options.yearSuffix || '';
- var filter = $.isFunction(options.filter) && options.filter;
- var startDate = this.startDate;
- var endDate = this.endDate;
- var viewDate = this.viewDate;
- var viewYear = viewDate.getFullYear();
- var now = new Date();
- var thisYear = now.getFullYear();
- var date = this.date;
- var year = date.getFullYear();
- var isPrevDisabled = false;
- var isNextDisabled = false;
- var isDisabled = false;
- var isPicked = false;
- var isMuted = false;
- var list = '';
- var start = -5;
- var end = 6;
- var i;
-
- for (i = start; i <= end; i++) {
- date = new Date(viewYear + i, 1, 1);
- isMuted = i === start || i === end;
- isPicked = (viewYear + i) === year;
- isDisabled = false;
-
- if (startDate) {
- isDisabled = date.getFullYear() < startDate.getFullYear();
-
- if (i === start) {
- isPrevDisabled = isDisabled;
- }
+ case 'year':
+ viewYear = parseInt($target.text(), 10);
+ this.date = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+
+ if (format.hasMonth) {
+ this.viewDate = new Date(this.date);
+ this.showView(VIEWS.MONTHS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
}
- if (!isDisabled && endDate) {
- isDisabled = date.getFullYear() > endDate.getFullYear();
+ this.pick('year');
+ break;
- if (i === end) {
- isNextDisabled = isDisabled;
- }
+ case 'month prev':
+ case 'month next':
+ viewMonth = view === 'month prev' ? viewMonth - 1 : viewMonth + 1;
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.renderDays();
+ break;
+
+ case 'month current':
+ if (format.hasMonth) {
+ this.showView(VIEWS.MONTHS);
}
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
+ break;
+
+ case 'month picked':
+ if (format.hasDay) {
+ this.showView(VIEWS.DAYS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
}
- list += this.createItem({
- text: viewYear + i,
- view: isDisabled ? 'year disabled' : isPicked ? 'year picked' : 'year',
- muted: isMuted,
- picked: isPicked,
- disabled: isDisabled,
- highlighted: date.getFullYear() === thisYear
- });
- }
+ this.pick('month');
+ break;
- this.$yearsPrev.toggleClass(disabledClass, isPrevDisabled);
- this.$yearsNext.toggleClass(disabledClass, isNextDisabled);
- this.$yearsCurrent.
- toggleClass(disabledClass, true).
- html((viewYear + start) + suffix + ' - ' + (viewYear + end) + suffix);
- this.$years.html(list);
- },
+ case 'month':
+ viewMonth = $.inArray($target.text(), options.monthsShort);
+ this.date = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
- fillMonths: function () {
- var options = this.options;
- var disabledClass = options.disabledClass || '';
- var months = options.monthsShort;
- var filter = $.isFunction(options.filter) && options.filter;
- var startDate = this.startDate;
- var endDate = this.endDate;
- var viewDate = this.viewDate;
- var viewYear = viewDate.getFullYear();
- var now = new Date();
- var thisYear = now.getFullYear();
- var thisMonth = now.getMonth();
- var date = this.date;
- var year = date.getFullYear();
- var month = date.getMonth();
- var isPrevDisabled = false;
- var isNextDisabled = false;
- var isDisabled = false;
- var isPicked = false;
- var list = '';
- var i;
-
- for (i = 0; i <= 11; i++) {
- date = new Date(viewYear, i, 1);
- isPicked = viewYear === year && i === month;
- isDisabled = false;
-
- if (startDate) {
- isPrevDisabled = date.getFullYear() === startDate.getFullYear();
- isDisabled = isPrevDisabled && date.getMonth() < startDate.getMonth();
+ if (format.hasDay) {
+ this.viewDate = new Date(viewYear, viewMonth, getMinDay(viewYear, viewMonth, viewDay));
+ this.showView(VIEWS.DAYS);
+ } else {
+ $target.addClass(options.pickedClass).siblings().removeClass(options.pickedClass);
+ this.hideView();
}
- if (!isDisabled && endDate) {
- isNextDisabled = date.getFullYear() === endDate.getFullYear();
- isDisabled = isNextDisabled && date.getMonth() > endDate.getMonth();
- console.log(isNextDisabled, date, endDate)
- }
+ this.pick('month');
+ break;
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
+ case 'day prev':
+ case 'day next':
+ case 'day':
+ if (view === 'day prev') {
+ viewMonth -= 1;
+ } else if (view === 'day next') {
+ viewMonth += 1;
}
- list += this.createItem({
- index: i,
- text: months[i],
- view: isDisabled ? 'month disabled' : isPicked ? 'month picked' : 'month',
- picked: isPicked,
- disabled: isDisabled,
- highlighted: viewYear === thisYear && date.getMonth() === thisMonth
- });
- }
+ viewDay = parseInt($target.text(), 10);
+ this.date = new Date(viewYear, viewMonth, viewDay);
+ this.viewDate = new Date(viewYear, viewMonth, viewDay);
+ this.renderDays();
- this.$yearPrev.toggleClass(disabledClass, isPrevDisabled);
- this.$yearNext.toggleClass(disabledClass, isNextDisabled);
- this.$yearCurrent.
- toggleClass(disabledClass, isPrevDisabled && isNextDisabled).
- html(viewYear + options.yearSuffix || '');
- this.$months.html(list);
- },
+ if (view === 'day') {
+ this.hideView();
+ }
- fillDays: function () {
- var options = this.options;
- var disabledClass = options.disabledClass || '';
- var suffix = options.yearSuffix || '';
- var months = options.monthsShort;
- var weekStart = parseInt(options.weekStart, 10) % 7;
- var filter = $.isFunction(options.filter) && options.filter;
- var startDate = this.startDate;
- var endDate = this.endDate;
- var viewDate = this.viewDate;
- var viewYear = viewDate.getFullYear();
- var viewMonth = viewDate.getMonth();
- var prevViewYear = viewYear;
- var prevViewMonth = viewMonth;
- var nextViewYear = viewYear;
- var now = new Date();
- var thisYear = now.getFullYear();
- var thisMonth = now.getMonth();
- var today = now.getDate();
- var nextViewMonth = viewMonth;
- var date = this.date;
- var year = date.getFullYear();
- var month = date.getMonth();
- var day = date.getDate();
- var isPrevDisabled = false;
- var isNextDisabled = false;
- var isDisabled = false;
- var isPicked = false;
- var prevItems = [];
- var nextItems = [];
- var items = [];
- var total = 42; // 6 rows and 7 columns on the days picker
- var length;
- var i;
- var n;
-
- // Days of previous month
- // -----------------------------------------------------------------------
-
- if (viewMonth === 0) {
- prevViewYear -= 1;
- prevViewMonth = 11;
- } else {
- prevViewMonth -= 1;
- }
+ this.pick('day');
+ break;
- // The length of the days of previous month
- length = getDaysInMonth(prevViewYear, prevViewMonth);
+ case 'day picked':
+ this.hideView();
+ this.pick('day');
+ break;
- // The first day of current month
- date = new Date(viewYear, viewMonth, 1);
+ default:
+ }
+ },
+ globalClick: function globalClick(_ref) {
+ var target = _ref.target;
+ var element = this.element,
+ $trigger = this.$trigger;
- // The visible length of the days of previous month
- // [0,1,2,3,4,5,6] - [0,1,2,3,4,5,6] => [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6]
- n = date.getDay() - weekStart;
+ var trigger = $trigger[0];
+ var hidden = true;
- // [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6] => [1,2,3,4,5,6,7]
- if (n <= 0) {
- n += 7;
+ while (target !== document) {
+ if (target === trigger || target === element) {
+ hidden = false;
+ break;
}
+ target = target.parentNode;
+ }
+
+ if (hidden) {
+ this.hide();
+ }
+ },
+ keyup: function keyup() {
+ this.update();
+ },
+ globalKeyup: function globalKeyup(_ref2) {
+ var target = _ref2.target,
+ key = _ref2.key,
+ keyCode = _ref2.keyCode;
+
+ if (this.isInput && target !== this.element && this.shown && (key === 'Tab' || keyCode === 9)) {
+ this.hide();
+ }
+ }
+};
+
+var render = {
+ render: function render() {
+ this.renderYears();
+ this.renderMonths();
+ this.renderDays();
+ },
+ renderWeek: function renderWeek() {
+ var _this = this;
+
+ var items = [];
+ var _options = this.options,
+ weekStart = _options.weekStart,
+ daysMin = _options.daysMin;
+
+
+ weekStart = parseInt(weekStart, 10) % 7;
+ daysMin = daysMin.slice(weekStart).concat(daysMin.slice(0, weekStart));
+ $.each(daysMin, function (i, day) {
+ items.push(_this.createItem({
+ text: day
+ }));
+ });
+
+ this.$week.html(items.join(''));
+ },
+ renderYears: function renderYears() {
+ var options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate;
+ var disabledClass = options.disabledClass,
+ filter = options.filter,
+ yearSuffix = options.yearSuffix;
+
+ var viewYear = this.viewDate.getFullYear();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var year = this.date.getFullYear();
+ var start = -5;
+ var end = 6;
+ var items = [];
+ var prevDisabled = false;
+ var nextDisabled = false;
+ var i = void 0;
+
+ for (i = start; i <= end; i += 1) {
+ var date = new Date(viewYear + i, 1, 1);
+ var disabled = false;
+
if (startDate) {
- isPrevDisabled = date.getTime() <= startDate.getTime();
+ disabled = date.getFullYear() < startDate.getFullYear();
+
+ if (i === start) {
+ prevDisabled = disabled;
+ }
}
- for (i = length - (n - 1); i <= length; i++) {
- date = new Date(prevViewYear, prevViewMonth, i);
- isPicked = prevViewYear === year && prevViewMonth === month && i === day;
- isDisabled = false;
+ if (!disabled && endDate) {
+ disabled = date.getFullYear() > endDate.getFullYear();
- if (startDate) {
- isDisabled = date.getTime() < startDate.getTime();
+ if (i === end) {
+ nextDisabled = disabled;
}
+ }
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
- }
+ if (!disabled && filter) {
+ disabled = filter.call(this.$element, date) === false;
+ }
+
+ var picked = viewYear + i === year;
+ var view = picked ? 'year picked' : 'year';
+
+ items.push(this.createItem({
+ picked: picked,
+ disabled: disabled,
+ muted: i === start || i === end,
+ text: viewYear + i,
+ view: disabled ? 'year disabled' : view,
+ highlighted: date.getFullYear() === thisYear
+ }));
+ }
- prevItems.push(this.createItem({
- text: i,
- view: 'day prev',
- muted: true,
- picked: isPicked,
- disabled: isDisabled,
- highlighted: prevViewYear === thisYear && prevViewMonth === thisMonth && date.getDate() === today
- }));
+ this.$yearsPrev.toggleClass(disabledClass, prevDisabled);
+ this.$yearsNext.toggleClass(disabledClass, nextDisabled);
+ this.$yearsCurrent.toggleClass(disabledClass, true).html(viewYear + start + yearSuffix + ' - ' + (viewYear + end) + yearSuffix);
+ this.$years.html(items.join(''));
+ },
+ renderMonths: function renderMonths() {
+ var options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate,
+ viewDate = this.viewDate;
+
+ var disabledClass = options.disabledClass || '';
+ var months = options.monthsShort;
+ var filter = $.isFunction(options.filter) && options.filter;
+ var viewYear = viewDate.getFullYear();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var thisMonth = now.getMonth();
+ var year = this.date.getFullYear();
+ var month = this.date.getMonth();
+ var items = [];
+ var prevDisabled = false;
+ var nextDisabled = false;
+ var i = void 0;
+
+ for (i = 0; i <= 11; i += 1) {
+ var date = new Date(viewYear, i, 1);
+ var disabled = false;
+
+ if (startDate) {
+ prevDisabled = date.getFullYear() === startDate.getFullYear();
+ disabled = prevDisabled && date.getMonth() < startDate.getMonth();
}
- // Days of next month
- // -----------------------------------------------------------------------
+ if (!disabled && endDate) {
+ nextDisabled = date.getFullYear() === endDate.getFullYear();
+ disabled = nextDisabled && date.getMonth() > endDate.getMonth();
+ }
- if (viewMonth === 11) {
- nextViewYear += 1;
- nextViewMonth = 0;
- } else {
- nextViewMonth += 1;
+ if (!disabled && filter) {
+ disabled = filter.call(this.$element, date) === false;
}
- // The length of the days of current month
- length = getDaysInMonth(viewYear, viewMonth);
+ var picked = viewYear === year && i === month;
+ var view = picked ? 'month picked' : 'month';
- // The visible length of next month
- n = total - (prevItems.length + length);
+ items.push(this.createItem({
+ disabled: disabled,
+ picked: picked,
+ highlighted: viewYear === thisYear && date.getMonth() === thisMonth,
+ index: i,
+ text: months[i],
+ view: disabled ? 'month disabled' : view
+ }));
+ }
- // The last day of current month
- date = new Date(viewYear, viewMonth, length);
+ this.$yearPrev.toggleClass(disabledClass, prevDisabled);
+ this.$yearNext.toggleClass(disabledClass, nextDisabled);
+ this.$yearCurrent.toggleClass(disabledClass, prevDisabled && nextDisabled).html(viewYear + options.yearSuffix || '');
+ this.$months.html(items.join(''));
+ },
+ renderDays: function renderDays() {
+ var $element = this.$element,
+ options = this.options,
+ startDate = this.startDate,
+ endDate = this.endDate,
+ viewDate = this.viewDate,
+ currentDate = this.date;
+ var disabledClass = options.disabledClass,
+ filter = options.filter,
+ monthsShort = options.monthsShort,
+ weekStart = options.weekStart,
+ yearSuffix = options.yearSuffix;
+
+ var viewYear = viewDate.getFullYear();
+ var viewMonth = viewDate.getMonth();
+ var now = new Date();
+ var thisYear = now.getFullYear();
+ var thisMonth = now.getMonth();
+ var thisDay = now.getDate();
+ var year = currentDate.getFullYear();
+ var month = currentDate.getMonth();
+ var day = currentDate.getDate();
+ var length = void 0;
+ var i = void 0;
+ var n = void 0;
+
+ // Days of prev month
+ // -----------------------------------------------------------------------
+
+ var prevItems = [];
+ var prevViewYear = viewYear;
+ var prevViewMonth = viewMonth;
+ var prevDisabled = false;
+
+ if (viewMonth === 0) {
+ prevViewYear -= 1;
+ prevViewMonth = 11;
+ } else {
+ prevViewMonth -= 1;
+ }
- if (endDate) {
- isNextDisabled = date.getTime() >= endDate.getTime();
+ // The length of the days of prev month
+ length = getDaysInMonth(prevViewYear, prevViewMonth);
+
+ // The first day of current month
+ var firstDay = new Date(viewYear, viewMonth, 1);
+
+ // The visible length of the days of prev month
+ // [0,1,2,3,4,5,6] - [0,1,2,3,4,5,6] => [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6]
+ n = firstDay.getDay() - parseInt(weekStart, 10) % 7;
+
+ // [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6] => [1,2,3,4,5,6,7]
+ if (n <= 0) {
+ n += 7;
+ }
+
+ if (startDate) {
+ prevDisabled = firstDay.getTime() <= startDate.getTime();
+ }
+
+ for (i = length - (n - 1); i <= length; i += 1) {
+ var prevViewDate = new Date(prevViewYear, prevViewMonth, i);
+ var disabled = false;
+
+ if (startDate) {
+ disabled = prevViewDate.getTime() < startDate.getTime();
+ }
+
+ if (!disabled && filter) {
+ disabled = filter.call($element, prevViewDate) === false;
}
- for (i = 1; i <= n; i++) {
- date = new Date(nextViewYear, nextViewMonth, i);
- isPicked = nextViewYear === year && nextViewMonth === month && i === day;
- isDisabled = false;
+ prevItems.push(this.createItem({
+ disabled: disabled,
+ highlighted: prevViewYear === thisYear && prevViewMonth === thisMonth && prevViewDate.getDate() === thisDay,
+ muted: true,
+ picked: prevViewYear === year && prevViewMonth === month && i === day,
+ text: i,
+ view: 'day prev'
+ }));
+ }
+
+ // Days of next month
+ // -----------------------------------------------------------------------
+
+ var nextItems = [];
+ var nextViewYear = viewYear;
+ var nextViewMonth = viewMonth;
+ var nextDisabled = false;
+
+ if (viewMonth === 11) {
+ nextViewYear += 1;
+ nextViewMonth = 0;
+ } else {
+ nextViewMonth += 1;
+ }
+
+ // The length of the days of current month
+ length = getDaysInMonth(viewYear, viewMonth);
+
+ // The visible length of next month (42 means 6 rows and 7 columns)
+ n = 42 - (prevItems.length + length);
- if (endDate) {
- isDisabled = date.getTime() > endDate.getTime();
- }
+ // The last day of current month
+ var lastDate = new Date(viewYear, viewMonth, length);
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
- }
+ if (endDate) {
+ nextDisabled = lastDate.getTime() >= endDate.getTime();
+ }
+
+ for (i = 1; i <= n; i += 1) {
+ var date = new Date(nextViewYear, nextViewMonth, i);
+ var picked = nextViewYear === year && nextViewMonth === month && i === day;
+ var _disabled = false;
- nextItems.push(this.createItem({
- text: i,
- view: 'day next',
- muted: true,
- picked: isPicked,
- disabled: isDisabled,
- highlighted: nextViewYear === thisYear && nextViewMonth === thisMonth && date.getDate() === today
- }));
+ if (endDate) {
+ _disabled = date.getTime() > endDate.getTime();
}
- // Days of current month
- // -----------------------------------------------------------------------
+ if (!_disabled && filter) {
+ _disabled = filter.call($element, date) === false;
+ }
- for (i = 1; i <= length; i++) {
- date = new Date(viewYear, viewMonth, i);
- isPicked = viewYear === year && viewMonth === month && i === day;
- isDisabled = false;
+ nextItems.push(this.createItem({
+ disabled: _disabled,
+ picked: picked,
+ highlighted: nextViewYear === thisYear && nextViewMonth === thisMonth && date.getDate() === thisDay,
+ muted: true,
+ text: i,
+ view: 'day next'
+ }));
+ }
- if (startDate) {
- isDisabled = date.getTime() < startDate.getTime();
- }
+ // Days of current month
+ // -----------------------------------------------------------------------
- if (!isDisabled && endDate) {
- isDisabled = date.getTime() > endDate.getTime();
- }
+ var items = [];
- if (!isDisabled && filter) {
- isDisabled = filter.call(this.$element, date) === false;
- }
+ for (i = 1; i <= length; i += 1) {
+ var _date = new Date(viewYear, viewMonth, i);
+ var _disabled2 = false;
- items.push(this.createItem({
- text: i,
- view: isDisabled ? 'day disabled' : isPicked ? 'day picked' : 'day',
- picked: isPicked,
- disabled: isDisabled,
- highlighted: viewYear === thisYear && viewMonth === thisMonth && date.getDate() === today
- }));
+ if (startDate) {
+ _disabled2 = _date.getTime() < startDate.getTime();
}
- // Render days picker
- // -----------------------------------------------------------------------
-
- this.$monthPrev.toggleClass(disabledClass, isPrevDisabled);
- this.$monthNext.toggleClass(disabledClass, isNextDisabled);
- this.$monthCurrent.
- toggleClass(disabledClass, isPrevDisabled && isNextDisabled).
- html(
- options.yearFirst ?
- viewYear + suffix + ' ' + months[viewMonth] :
- months[viewMonth] + ' ' + viewYear + suffix
- );
- this.$days.html(prevItems.join('') + items.join(' ') + nextItems.join(''));
- },
-
- click: function (e) {
- var $target = $(e.target);
- var options = this.options;
- var viewDate = this.viewDate;
- var viewYear;
- var viewMonth;
- var viewDay;
- var isYear;
- var year;
- var view;
-
- e.stopPropagation();
- e.preventDefault();
-
- if ($target.hasClass('disabled')) {
- return;
+ if (!_disabled2 && endDate) {
+ _disabled2 = _date.getTime() > endDate.getTime();
}
- viewYear = viewDate.getFullYear();
- viewMonth = viewDate.getMonth();
- viewDay = viewDate.getDate();
- view = $target.data('view');
+ if (!_disabled2 && filter) {
+ _disabled2 = filter.call($element, _date) === false;
+ }
- switch (view) {
- case 'years prev':
- case 'years next':
- viewYear = view === 'years prev' ? viewYear - 10 : viewYear + 10;
- year = $target.text();
- isYear = REGEXP_YEAR.test(year);
+ var _picked = viewYear === year && viewMonth === month && i === day;
+ var view = _picked ? 'day picked' : 'day';
- if (isYear) {
- viewYear = parseInt(year, 10);
- this.date = new Date(viewYear, viewMonth, min(viewDay, 28));
- }
+ items.push(this.createItem({
+ disabled: _disabled2,
+ picked: _picked,
+ highlighted: viewYear === thisYear && viewMonth === thisMonth && _date.getDate() === thisDay,
+ text: i,
+ view: _disabled2 ? 'day disabled' : view
+ }));
+ }
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.fillYears();
+ // Render days picker
+ // -----------------------------------------------------------------------
- if (isYear) {
- this.showView(VIEWS.MONTHS);
- this.pick('year');
- }
+ this.$monthPrev.toggleClass(disabledClass, prevDisabled);
+ this.$monthNext.toggleClass(disabledClass, nextDisabled);
+ this.$monthCurrent.toggleClass(disabledClass, prevDisabled && nextDisabled).html(options.yearFirst ? viewYear + yearSuffix + ' ' + monthsShort[viewMonth] : monthsShort[viewMonth] + ' ' + viewYear + yearSuffix);
+ this.$days.html(prevItems.join('') + items.join('') + nextItems.join(''));
+ }
+};
- break;
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
- case 'year prev':
- case 'year next':
- viewYear = view === 'year prev' ? viewYear - 1 : viewYear + 1;
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.fillMonths();
- break;
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- case 'year current':
- if (this.format.hasYear) {
- this.showView(VIEWS.YEARS);
- }
+var _window = window;
+var document$1 = _window.document;
- break;
+var $document = $(document$1);
- case 'year picked':
- if (this.format.hasMonth) {
- this.showView(VIEWS.MONTHS);
- } else {
- $target.addClass(options.pickedClass)
- .siblings()
- .removeClass(options.pickedClass);
- this.hideView();
- }
-
- this.pick('year');
- break;
+// Classes
+var CLASS_TOP_LEFT = NAMESPACE + '-top-left';
+var CLASS_TOP_RIGHT = NAMESPACE + '-top-right';
+var CLASS_BOTTOM_LEFT = NAMESPACE + '-bottom-left';
+var CLASS_BOTTOM_RIGHT = NAMESPACE + '-bottom-right';
+var CLASS_PLACEMENTS = [CLASS_TOP_LEFT, CLASS_TOP_RIGHT, CLASS_BOTTOM_LEFT, CLASS_BOTTOM_RIGHT].join(' ');
- case 'year':
- viewYear = parseInt($target.text(), 10);
- this.date = new Date(viewYear, viewMonth, min(viewDay, 28));
-
- if (this.format.hasMonth) {
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.showView(VIEWS.MONTHS);
- } else {
- $target.addClass(options.pickedClass)
- .siblings()
- .removeClass(options.pickedClass);
- this.hideView();
- }
-
- this.pick('year');
- break;
+var Datepicker = function () {
+ function Datepicker(element) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- case 'month prev':
- case 'month next':
- viewMonth = view === 'month prev' ? viewMonth - 1 : view === 'month next' ? viewMonth + 1 : viewMonth;
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.fillDays();
- break;
+ _classCallCheck(this, Datepicker);
- case 'month current':
- if (this.format.hasMonth) {
- this.showView(VIEWS.MONTHS);
- }
+ this.$element = $(element);
+ this.element = element;
+ this.options = $.extend({}, DEFAULTS, LANGUAGES[options.language], options);
+ this.built = false;
+ this.shown = false;
+ this.isInput = false;
+ this.inline = false;
+ this.initialValue = '';
+ this.initialDate = null;
+ this.startDate = null;
+ this.endDate = null;
+ this.init();
+ }
- break;
+ _createClass(Datepicker, [{
+ key: 'init',
+ value: function init() {
+ var $this = this.$element,
+ options = this.options;
+ var startDate = options.startDate,
+ endDate = options.endDate,
+ date = options.date;
- case 'month picked':
- if (this.format.hasDay) {
- this.showView(VIEWS.DAYS);
- } else {
- $target.addClass(options.pickedClass)
- .siblings()
- .removeClass(options.pickedClass);
- this.hideView();
- }
-
- this.pick('month');
- break;
- case 'month':
- viewMonth = $.inArray($target.text(), options.monthsShort);
- this.date = new Date(viewYear, viewMonth, min(viewDay, 28));
-
- if (this.format.hasDay) {
- this.viewDate = new Date(viewYear, viewMonth, min(viewDay, 28));
- this.showView(VIEWS.DAYS);
- } else {
- $target.addClass(options.pickedClass)
- .siblings()
- .removeClass(options.pickedClass);
- this.hideView();
- }
-
- this.pick('month');
- break;
+ this.$trigger = $(options.trigger);
+ this.isInput = $this.is('input') || $this.is('textarea');
+ this.inline = options.inline && (options.container || !this.isInput);
+ this.format = parseFormat(options.format);
- case 'day prev':
- case 'day next':
- case 'day':
- viewMonth = view === 'day prev' ? viewMonth - 1 : view === 'day next' ? viewMonth + 1 : viewMonth;
- viewDay = parseInt($target.text(), 10);
- this.date = new Date(viewYear, viewMonth, viewDay);
- this.viewDate = new Date(viewYear, viewMonth, viewDay);
- this.fillDays();
+ var initialValue = this.getValue();
- if (view === 'day') {
- this.hideView();
- }
+ this.initialValue = initialValue;
+ this.oldValue = initialValue;
+ date = this.parseDate(date || initialValue);
- this.pick('day');
- break;
+ if (startDate) {
+ startDate = this.parseDate(startDate);
- case 'day picked':
- this.hideView();
- this.pick('day');
- break;
+ if (date.getTime() < startDate.getTime()) {
+ date = new Date(startDate);
+ }
- // No default
+ this.startDate = startDate;
}
- },
- clickDoc: function (e) {
- var target = e.target;
- var element = this.$element[0];
- var trigger = this.$trigger[0];
- var ignored;
+ if (endDate) {
+ endDate = this.parseDate(endDate);
- while (target !== document) {
- if (target === trigger || target === element) {
- ignored = true;
- break;
+ if (startDate && endDate.getTime() < startDate.getTime()) {
+ endDate = new Date(startDate);
}
- target = target.parentNode;
- }
+ if (date.getTime() > endDate.getTime()) {
+ date = new Date(endDate);
+ }
- if (!ignored) {
- this.hide();
+ this.endDate = endDate;
}
- },
- keyup: function () {
- this.update();
- },
+ this.date = date;
+ this.viewDate = new Date(date);
+ this.initialDate = new Date(this.date);
+ this.bind();
- keyupDoc: function (e) {
- if (this.isInput && e.target !== this.$element[0] &&
- this.isShown && (e.key === 'Tab' || e.keyCode === 9)) {
- this.hide();
+ if (options.autoShow || this.inline) {
+ this.show();
}
- },
-
- getValue: function () {
- var $this = this.$element;
- var val = '';
- if (this.isInput) {
- val = $this.val();
- } else if (this.isInline) {
- if (this.options.container) {
- val = $this.text();
- }
- } else {
- val = $this.text();
+ if (options.autoPick) {
+ this.pick();
+ }
+ }
+ }, {
+ key: 'build',
+ value: function build() {
+ if (this.built) {
+ return;
}
- return val;
- },
+ this.built = true;
- setValue: function (val) {
- var $this = this.$element;
+ var $this = this.$element,
+ options = this.options;
- val = isString(val) ? val : '';
+ var $picker = $(options.template);
- if (this.isInput) {
- $this.val(val);
- } else if (this.isInline) {
- if (this.options.container) {
- $this.text(val);
- }
- } else {
- $this.text(val);
- }
- },
+ this.$picker = $picker;
+ this.$week = $picker.find(selectorOf('week'));
+ // Years view
+ this.$yearsPicker = $picker.find(selectorOf('years picker'));
+ this.$yearsPrev = $picker.find(selectorOf('years prev'));
+ this.$yearsNext = $picker.find(selectorOf('years next'));
+ this.$yearsCurrent = $picker.find(selectorOf('years current'));
+ this.$years = $picker.find(selectorOf('years'));
- // Methods
- // -------------------------------------------------------------------------
+ // Months view
+ this.$monthsPicker = $picker.find(selectorOf('months picker'));
+ this.$yearPrev = $picker.find(selectorOf('year prev'));
+ this.$yearNext = $picker.find(selectorOf('year next'));
+ this.$yearCurrent = $picker.find(selectorOf('year current'));
+ this.$months = $picker.find(selectorOf('months'));
- // Show the datepicker
- show: function () {
- if (!this.isBuilt) {
- this.build();
+ // Days view
+ this.$daysPicker = $picker.find(selectorOf('days picker'));
+ this.$monthPrev = $picker.find(selectorOf('month prev'));
+ this.$monthNext = $picker.find(selectorOf('month next'));
+ this.$monthCurrent = $picker.find(selectorOf('month current'));
+ this.$days = $picker.find(selectorOf('days'));
+
+ if (this.inline) {
+ $(options.container || $this).append($picker.addClass(NAMESPACE + '-inline'));
+ } else {
+ $(document$1.body).append($picker.addClass(NAMESPACE + '-dropdown'));
+ $picker.addClass(CLASS_HIDE);
}
- if (this.isShown) {
+ this.renderWeek();
+ }
+ }, {
+ key: 'unbuild',
+ value: function unbuild() {
+ if (!this.built) {
return;
}
- if (this.trigger(EVENT_SHOW).isDefaultPrevented()) {
- return;
- }
+ this.built = false;
+ this.$picker.remove();
+ }
+ }, {
+ key: 'bind',
+ value: function bind() {
+ var options = this.options,
+ $this = this.$element;
- this.isShown = true;
- this.$picker.removeClass(CLASS_HIDE).on(EVENT_CLICK, $.proxy(this.click, this));
- this.showView(this.options.startView);
- if (!this.isInline) {
- $window.on(EVENT_RESIZE, (this._place = proxy(this.place, this)));
- $document.on(EVENT_CLICK, (this._clickDoc = proxy(this.clickDoc, this)));
- $document.on(EVENT_KEYUP, (this._keyupDoc = proxy(this.keyupDoc, this)));
- this.place();
+ if ($.isFunction(options.show)) {
+ $this.on(EVENT_SHOW, options.show);
}
- },
- // Hide the datepicker
- hide: function () {
- if (!this.isShown) {
- return;
+ if ($.isFunction(options.hide)) {
+ $this.on(EVENT_HIDE, options.hide);
}
- if (this.trigger(EVENT_HIDE).isDefaultPrevented()) {
- return;
+ if ($.isFunction(options.pick)) {
+ $this.on(EVENT_PICK, options.pick);
}
- this.isShown = false;
- this.$picker.addClass(CLASS_HIDE).off(EVENT_CLICK, this.click);
-
- if (!this.isInline) {
- $window.off(EVENT_RESIZE, this._place);
- $document.off(EVENT_CLICK, this._clickDoc);
- $document.off(EVENT_KEYUP, this._keyupDoc);
+ if (this.isInput) {
+ $this.on(EVENT_KEYUP, $.proxy(this.keyup, this));
}
- },
- toggle: function () {
- if (this.isShown) {
- this.hide();
- } else {
- this.show();
+ if (!this.inline) {
+ if (options.trigger) {
+ this.$trigger.on(EVENT_CLICK, $.proxy(this.toggle, this));
+ } else if (this.isInput) {
+ $this.on(EVENT_FOCUS, $.proxy(this.show, this));
+ } else {
+ $this.on(EVENT_CLICK, $.proxy(this.show, this));
+ }
}
- },
+ }
+ }, {
+ key: 'unbind',
+ value: function unbind() {
+ var $this = this.$element,
+ options = this.options;
- // Update the datepicker with the current input value
- update: function () {
- var value = this.getValue();
- if (value === this.oldValue) {
- return;
+ if ($.isFunction(options.show)) {
+ $this.off(EVENT_SHOW, options.show);
}
- this.setDate(value, true);
- this.oldValue = value;
- },
-
- /**
- * Pick the current date to the element
- *
- * @param {String} _view (private)
- */
- pick: function (_view) {
- var $this = this.$element;
- var date = this.date;
-
- if (this.trigger(EVENT_PICK, {
- view: _view || '',
- date: date
- }).isDefaultPrevented()) {
- return;
+ if ($.isFunction(options.hide)) {
+ $this.off(EVENT_HIDE, options.hide);
}
- this.setValue(date = this.formatDate(this.date));
+ if ($.isFunction(options.pick)) {
+ $this.off(EVENT_PICK, options.pick);
+ }
if (this.isInput) {
- $this.trigger('change');
+ $this.off(EVENT_KEYUP, this.keyup);
}
- },
- // Reset the datepicker
- reset: function () {
- this.setDate(this.initialDate, true);
- this.setValue(this.initialValue);
-
- if (this.isShown) {
- this.showView(this.options.startView);
+ if (!this.inline) {
+ if (options.trigger) {
+ this.$trigger.off(EVENT_CLICK, this.toggle);
+ } else if (this.isInput) {
+ $this.off(EVENT_FOCUS, this.show);
+ } else {
+ $this.off(EVENT_CLICK, this.show);
+ }
}
- },
-
- /**
- * Get the month name with given argument or the current date
- *
- * @param {Number} month (optional)
- * @param {Boolean} short (optional)
- * @return {String} (month name)
- */
- getMonthName: function (month, short) {
- var options = this.options;
- var months = options.months;
+ }
+ }, {
+ key: 'showView',
+ value: function showView(view) {
+ var $yearsPicker = this.$yearsPicker,
+ $monthsPicker = this.$monthsPicker,
+ $daysPicker = this.$daysPicker,
+ format = this.format;
- if ($.isNumeric(month)) {
- month = Number(month);
- } else if (isUndefined(short)) {
- short = month;
- }
- if (short === true) {
- months = options.monthsShort;
- }
+ if (format.hasYear || format.hasMonth || format.hasDay) {
+ switch (Number(view)) {
+ case VIEWS.YEARS:
+ $monthsPicker.addClass(CLASS_HIDE);
+ $daysPicker.addClass(CLASS_HIDE);
- return months[isNumber(month) ? month : this.date.getMonth()];
- },
-
- /**
- * Get the day name with given argument or the current date
- *
- * @param {Number} day (optional)
- * @param {Boolean} short (optional)
- * @param {Boolean} min (optional)
- * @return {String} (day name)
- */
- getDayName: function (day, short, min) {
- var options = this.options;
- var days = options.days;
+ if (format.hasYear) {
+ this.renderYears();
+ $yearsPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.DAYS);
+ }
- if ($.isNumeric(day)) {
- day = Number(day);
- } else {
- if (isUndefined(min)) {
- min = short;
- }
+ break;
- if (isUndefined(short)) {
- short = day;
- }
- }
+ case VIEWS.MONTHS:
+ $yearsPicker.addClass(CLASS_HIDE);
+ $daysPicker.addClass(CLASS_HIDE);
- days = min === true ? options.daysMin : short === true ? options.daysShort : days;
-
- return days[isNumber(day) ? day : this.date.getDay()];
- },
-
- /**
- * Get the current date
- *
- * @param {Boolean} formatted (optional)
- * @return {Date|String} (date)
- */
- getDate: function (formatted) {
- var date = this.date;
-
- return formatted ? this.formatDate(date) : new Date(date);
- },
-
- /**
- * Set the current date with a new date
- *
- * @param {Date} date
- * @param {Boolean} _isUpdated (private)
- */
- setDate: function (date, _isUpdated) {
- var filter = this.options.filter;
-
- if (isDate(date) || isString(date)) {
- date = this.parseDate(date);
-
- if ($.isFunction(filter) && filter.call(this.$element, date) === false) {
- return;
- }
+ if (format.hasMonth) {
+ this.renderMonths();
+ $monthsPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.YEARS);
+ }
- this.date = date;
- this.viewDate = new Date(date);
+ break;
- if (!_isUpdated) {
- this.pick();
- }
+ // case VIEWS.DAYS:
+ default:
+ $yearsPicker.addClass(CLASS_HIDE);
+ $monthsPicker.addClass(CLASS_HIDE);
- if (this.isBuilt) {
- this.fillAll();
- }
- }
- },
-
- /**
- * Set the start view date with a new date
- *
- * @param {Date} date
- */
- setStartDate: function (date) {
- if (isDate(date) || isString(date)) {
- this.startDate = this.parseDate(date);
-
- if (this.isBuilt) {
- this.fillAll();
- }
- }
- },
-
- /**
- * Set the end view date with a new date
- *
- * @param {Date} date
- */
- setEndDate: function (date) {
- if (isDate(date) || isString(date)) {
- this.endDate = this.parseDate(date);
-
- if (this.isBuilt) {
- this.fillAll();
+ if (format.hasDay) {
+ this.renderDays();
+ $daysPicker.removeClass(CLASS_HIDE);
+ this.place();
+ } else {
+ this.showView(VIEWS.MONTHS);
+ }
}
}
- },
-
- /**
- * Parse a date string with the set date format
- *
- * @param {String} date
- * @return {Date} (parsed date)
- */
- parseDate: function (date) {
- var format = this.format;
- var parts = [];
- var length;
- var year;
- var day;
- var month;
- var val;
- var i;
-
- if (isDate(date)) {
- return new Date(date.getFullYear(), date.getMonth(), date.getDate());
- } else if (isString(date)) {
- parts = date.match(REGEXP_DIGITS) || [];
- }
-
- date = new Date();
- year = date.getFullYear();
- day = date.getDate();
- month = date.getMonth();
- length = format.parts.length;
-
- if (parts.length === length) {
- for (i = 0; i < length; i++) {
- val = parseInt(parts[i], 10) || 1;
-
- switch (format.parts[i]) {
- case 'dd':
- case 'd':
- day = val;
- break;
-
- case 'mm':
- case 'm':
- month = val - 1;
- break;
-
- case 'yy':
- year = 2000 + val;
- break;
-
- case 'yyyy':
- year = val;
- break;
-
- // No default
- }
- }
+ }
+ }, {
+ key: 'hideView',
+ value: function hideView() {
+ if (!this.inline && this.options.autoHide) {
+ this.hide();
}
-
- return new Date(year, month, day);
- },
-
- /**
- * Format a date object to a string with the set date format
- *
- * @param {Date} date
- * @return {String} (formatted date)
- */
- formatDate: function (date) {
- var format = this.format;
- var formatted = '';
- var length;
- var year;
- var part;
- var val;
- var i;
-
- if (isDate(date)) {
- formatted = format.source;
- year = date.getFullYear();
- val = {
- d: date.getDate(),
- m: date.getMonth() + 1,
- yy: year.toString().substring(2),
- yyyy: year
- };
-
- val.dd = (val.d < 10 ? '0' : '') + val.d;
- val.mm = (val.m < 10 ? '0' : '') + val.m;
- length = format.parts.length;
-
- for (i = 0; i < length; i++) {
- part = format.parts[i];
- formatted = formatted.replace(part, val[part]);
- }
+ }
+ }, {
+ key: 'place',
+ value: function place() {
+ if (this.inline) {
+ return;
}
- return formatted;
- },
+ var $this = this.$element,
+ options = this.options,
+ $picker = this.$picker;
- // Destroy the datepicker and remove the instance from the target element
- destroy: function () {
- this.unbind();
- this.unbuild();
- this.$element.removeData(NAMESPACE);
- }
- };
-
- Datepicker.LANGUAGES = {};
+ var containerWidth = $document.outerWidth();
+ var containerHeight = $document.outerHeight();
+ var elementWidth = $this.outerWidth();
+ var elementHeight = $this.outerHeight();
+ var width = $picker.width();
+ var height = $picker.height();
- Datepicker.DEFAULTS = {
- // Show the datepicker automatically when initialized
- autoShow: false,
+ var _$this$offset = $this.offset(),
+ left = _$this$offset.left,
+ top = _$this$offset.top;
- // Hide the datepicker automatically when picked
- autoHide: false,
+ var offset = parseFloat(options.offset);
+ var placement = CLASS_TOP_LEFT;
- // Pick the initial date automatically when initialized
- autoPick: false,
+ if (isNaN(offset)) {
+ offset = 10;
+ }
- // Enable inline mode
- inline: false,
+ if (top > height && top + elementHeight + height > containerHeight) {
+ top -= height + offset;
+ placement = CLASS_BOTTOM_LEFT;
+ } else {
+ top += elementHeight + offset;
+ }
- // A element (or selector) for putting the datepicker
- container: null,
+ if (left + width > containerWidth) {
+ left += elementWidth - width;
+ placement = placement.replace('left', 'right');
+ }
- // A element (or selector) for triggering the datepicker
- trigger: null,
+ $picker.removeClass(CLASS_PLACEMENTS).addClass(placement).css({
+ top: top,
+ left: left,
+ zIndex: parseInt(options.zIndex, 10)
+ });
+ }
- // The ISO language code (built-in: en-US)
- language: '',
+ // A shortcut for triggering custom events
- // The date string format
- format: 'mm/dd/yyyy',
+ }, {
+ key: 'trigger',
+ value: function trigger(type, data) {
+ var e = $.Event(type, data);
- // The initial date
- date: null,
+ this.$element.trigger(e);
- // The start view date
- startDate: null,
+ return e;
+ }
+ }, {
+ key: 'createItem',
+ value: function createItem(data) {
+ var options = this.options;
+ var itemTag = options.itemTag;
- // The end view date
- endDate: null,
+ var item = {
+ text: '',
+ view: '',
+ muted: false,
+ picked: false,
+ disabled: false,
+ highlighted: false
+ };
+ var classes = [];
- // The start view when initialized
- startView: 0, // 0 for days, 1 for months, 2 for years
+ $.extend(item, data);
- // The start day of the week
- weekStart: 0, // 0 for Sunday, 1 for Monday, 2 for Tuesday, 3 for Wednesday, 4 for Thursday, 5 for Friday, 6 for Saturday
+ if (item.muted) {
+ classes.push(options.mutedClass);
+ }
- // Show year before month on the datepicker header
- yearFirst: false,
+ if (item.highlighted) {
+ classes.push(options.highlightedClass);
+ }
- // A string suffix to the year number.
- yearSuffix: '',
+ if (item.picked) {
+ classes.push(options.pickedClass);
+ }
- // Days' name of the week.
- days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+ if (item.disabled) {
+ classes.push(options.disabledClass);
+ }
- // Shorter days' name
- daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ return '<' + itemTag + ' class="' + classes.join(' ') + '" data-view="' + item.view + '">' + item.text + '' + itemTag + '>';
+ }
+ }, {
+ key: 'getValue',
+ value: function getValue() {
+ var $this = this.$element;
- // Shortest days' name
- daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
+ return this.isInput ? $this.val() : $this.text();
+ }
+ }, {
+ key: 'setValue',
+ value: function setValue() {
+ var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
- // Months' name
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ var $this = this.$element;
- // Shorter months' name
- monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ if (this.isInput) {
+ $this.val(value);
+ } else {
+ $this.text(value);
+ }
+ }
+ }], [{
+ key: 'setDefaults',
+ value: function setDefaults() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- // A element tag for each item of years, months and days
- itemTag: 'li',
+ $.extend(DEFAULTS, LANGUAGES[options.language], options);
+ }
+ }]);
- // A class (CSS) for muted date item
- mutedClass: 'muted',
+ return Datepicker;
+}();
- // A class (CSS) for picked date item
- pickedClass: 'picked',
+$.extend(Datepicker.prototype, render, handlers, methods);
- // A class (CSS) for disabled date item
- disabledClass: 'disabled',
+var AnotherDatepicker = $.fn.datepicker;
- // A class (CSS) for highlight date item
- highlightedClass: 'highlighted',
+$.fn.datepicker = function jQueryDatepicker(option) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
- // The template of the datepicker
- template: (
- '' +
- '
' +
- '
' +
- '- ‹
' +
- '' +
- '- ›
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '- ‹
' +
- '' +
- '- ›
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '- ‹
' +
- '' +
- '- ›
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
'
- ),
+ var result = void 0;
- // The offset top or bottom of the datepicker from the element
- offset: 10,
+ this.each(function each() {
+ var $this = $(this);
+ var data = $this.data('datepicker');
- // The `z-index` of the datepicker
- zIndex: 1000,
-
- // Filter each date item (return `false` to disable a date item)
- filter: null,
-
- // Event shortcuts
- show: null,
- hide: null,
- pick: null
- };
+ if (!data) {
+ if (/destroy/.test(option)) {
+ return;
+ }
- Datepicker.setDefaults = function (options) {
- options = $.isPlainObject(options) ? options : {};
+ var options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
- if (options.language) {
- options = $.extend({}, Datepicker.LANGUAGES[options.language], options);
+ data = new Datepicker(this, options);
+ $this.data('datepicker', data);
}
- $.extend(Datepicker.DEFAULTS, options);
- };
-
- // Save the other datepicker
- Datepicker.other = $.fn.datepicker;
-
- // Register as jQuery plugin
- $.fn.datepicker = function (option) {
- var args = toArray(arguments, 1);
- var result;
-
- this.each(function () {
- var $this = $(this);
- var data = $this.data(NAMESPACE);
- var options;
- var fn;
-
- if (!data) {
- if (/destroy/.test(option)) {
- return;
- }
-
- options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
- $this.data(NAMESPACE, (data = new Datepicker(this, options)));
- }
+ if (typeof option === 'string') {
+ var fn = data[option];
- if (isString(option) && $.isFunction(fn = data[option])) {
+ if ($.isFunction(fn)) {
result = fn.apply(data, args);
}
- });
-
- return isUndefined(result) ? this : result;
- };
+ }
+ });
- $.fn.datepicker.Constructor = Datepicker;
- $.fn.datepicker.languages = Datepicker.LANGUAGES;
- $.fn.datepicker.setDefaults = Datepicker.setDefaults;
+ return typeof result !== 'undefined' ? result : this;
+};
- // No conflict
- $.fn.datepicker.noConflict = function () {
- $.fn.datepicker = Datepicker.other;
- return this;
- };
+$.fn.datepicker.Constructor = Datepicker;
+$.fn.datepicker.languages = LANGUAGES;
+$.fn.datepicker.setDefaults = Datepicker.setDefaults;
+$.fn.datepicker.noConflict = function noConflict() {
+ $.fn.datepicker = AnotherDatepicker;
+ return this;
+};
-});
+})));
diff --git a/package.json b/package.json
index 78a52d9..d96c8ba 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,10 @@
{
"name": "@fengyuanchen/datepicker",
"description": "A simple jQuery datepicker plugin.",
- "version": "0.5.5",
- "main": "dist/datepicker.js",
+ "version": "0.6.0",
+ "main": "dist/datepicker.common.js",
+ "module": "dist/datepicker.esm.js",
+ "browser": "dist/datepicker.js",
"license": "MIT",
"repository": "fengyuanchen/datepicker",
"homepage": "https://github.com/fengyuanchen/datepicker",