flatpickr 2.4.2.0 → 2.4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a85d78c78d3aa652d5c54c8eb889a3bbd1e76a30
4
- data.tar.gz: bc8d1d8d90c3e89dbf882c271a265443f963c49f
3
+ metadata.gz: ed04cd311e8867738566ef9b88403e543d5fcb3d
4
+ data.tar.gz: 1f7ab3e2d47769a2ba47dd081c5ce10ca5e353ec
5
5
  SHA512:
6
- metadata.gz: 8ea9f6f61747f6512a823c1a70e0dafa33023483e662656edebe9d1b634c094730f56213b90ca2924a23a3d91e8eb43b3da5eff8235e2a44c7bf89e04bc334e1
7
- data.tar.gz: 37eac9df36a15b11ddc4394068b8218ca20b93e7acfbe58e408f2a0a7106874e0e36d4099c382212dea95d050337b27f0825d1193df85710a422f6b5517ffd8c
6
+ metadata.gz: 77073bcf7207e956cade258c0c0d60055dbb0962a48075543b96447d1a40e29f11e341e02725d656139084ae5caae18848fd61630f30cade2ad00a38c9cedcb3
7
+ data.tar.gz: eb4c19b81102d43065cc868b5ab514814f4c4990ae8f1aef97b018f1d3679c4166cb3439332f5c7e0e1148f00fbd9fc81a000299fc524666f48b4d318a4a27d1
@@ -1,3 +1,3 @@
1
1
  module Flatpickr
2
- VERSION = '2.4.2.0'
2
+ VERSION = '2.4.3.0'
3
3
  end
@@ -2,7 +2,7 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument
2
2
 
3
3
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4
4
 
5
- /*! flatpickr v2.4.2, @license MIT */
5
+ /*! flatpickr v2.4.3, @license MIT */
6
6
  function Flatpickr(element, config) {
7
7
  var self = this;
8
8
 
@@ -31,7 +31,6 @@ function Flatpickr(element, config) {
31
31
  self.parseDate = Flatpickr.prototype.parseDate.bind(self);
32
32
 
33
33
  setupFormats();
34
-
35
34
  parseConfig();
36
35
  setupLocale();
37
36
  setupInputs();
@@ -46,16 +45,6 @@ function Flatpickr(element, config) {
46
45
 
47
46
  bind();
48
47
 
49
- if (!self.isMobile) {
50
- Object.defineProperty(self, "dateIsPicked", {
51
- set: function set(bool) {
52
- toggleClass(self.calendarContainer, "dateIsPicked", bool);
53
- }
54
- });
55
- }
56
-
57
- self.dateIsPicked = self.selectedDates.length > 0 || self.config.noCalendar;
58
-
59
48
  if (self.selectedDates.length) {
60
49
  if (self.config.enableTime) setHoursFromDate();
61
50
  updateValue();
@@ -65,9 +54,15 @@ function Flatpickr(element, config) {
65
54
  self.calendarContainer.style.width = self.days.clientWidth + self.weekWrapper.clientWidth + "px";
66
55
  }
67
56
 
57
+ self.showTimeInput = self.selectedDates.length || self.config.noCalendar;
68
58
  triggerEvent("Ready");
69
59
  }
70
60
 
61
+ function bindToInstance(fn) {
62
+ if (fn && fn.bind) return fn.bind(self);
63
+ return fn;
64
+ }
65
+
71
66
  function updateTime(e) {
72
67
  if (self.config.noCalendar && !self.selectedDates.length)
73
68
  // picking time only
@@ -135,6 +130,8 @@ function Flatpickr(element, config) {
135
130
 
136
131
  function onYearInput(event) {
137
132
  var year = event.target.value;
133
+ if (event.delta) year = (parseInt(year) + event.delta).toString();
134
+
138
135
  if (year.length === 4) {
139
136
  self.currentYearElement.blur();
140
137
  if (!/[^\d]/.test(year)) changeYear(year);
@@ -171,7 +168,7 @@ function Flatpickr(element, config) {
171
168
 
172
169
  if (self.config.mode === "range" && self.days) self.days.addEventListener("mouseover", onMouseOver);
173
170
 
174
- window.document.addEventListener("keydown", onKeyDown);
171
+ self.calendarContainer.addEventListener("keydown", onKeyDown);
175
172
 
176
173
  if (!self.config.inline && !self.config.static) window.addEventListener("resize", self.debouncedResize);
177
174
 
@@ -256,16 +253,18 @@ function Flatpickr(element, config) {
256
253
  self.redraw();
257
254
  }
258
255
 
259
- function incrementNumInput(e, delta) {
260
- var input = e.target.parentNode.childNodes[0];
261
- input.value = parseInt(input.value, 10) + delta * (input.step || 1);
256
+ function incrementNumInput(e, delta, inputElem) {
257
+ var input = inputElem || e.target.parentNode.childNodes[0];
262
258
 
263
- try {
264
- input.dispatchEvent(new Event("increment", { "bubbles": true }));
265
- } catch (e) {
266
- var ev = window.document.createEvent("CustomEvent");
267
- ev.initCustomEvent("increment", true, true, {});
259
+ if (typeof Event !== "undefined") {
260
+ var ev = new Event("increment", { "bubbles": true });
261
+ ev.delta = delta;
268
262
  input.dispatchEvent(ev);
263
+ } else {
264
+ var _ev = window.document.createEvent("CustomEvent");
265
+ _ev.initCustomEvent("increment", true, true, {});
266
+ _ev.delta = delta;
267
+ input.dispatchEvent(_ev);
269
268
  }
270
269
  }
271
270
 
@@ -336,6 +335,9 @@ function Flatpickr(element, config) {
336
335
  var wrapper = createElement("div", "flatpickr-wrapper");
337
336
  self.element.parentNode.insertBefore(wrapper, self.element);
338
337
  wrapper.appendChild(self.element);
338
+
339
+ if (self.altInput) wrapper.appendChild(self.altInput);
340
+
339
341
  wrapper.appendChild(self.calendarContainer);
340
342
  return;
341
343
  }
@@ -610,7 +612,7 @@ function Flatpickr(element, config) {
610
612
 
611
613
  self.selectedDates = [];
612
614
  self.latestSelectedDateObj = null;
613
- self.dateIsPicked = false;
615
+ self.showTimeInput = false;
614
616
 
615
617
  self.redraw();
616
618
 
@@ -634,7 +636,6 @@ function Flatpickr(element, config) {
634
636
  instance = instance || self;
635
637
  instance.clear(false);
636
638
 
637
- window.document.removeEventListener("keydown", onKeyDown);
638
639
  window.removeEventListener("resize", instance.debouncedResize);
639
640
 
640
641
  window.document.removeEventListener("click", documentClick);
@@ -742,7 +743,7 @@ function Flatpickr(element, config) {
742
743
  }
743
744
 
744
745
  function onKeyDown(e) {
745
- if (e.target === (self.altInput || self.input) && e.which === 13) selectDate(e);else if (self.isOpen && isCalendarElem(e.target)) {
746
+ if (e.target === (self.altInput || self.input) && e.which === 13) selectDate(e);else if (self.isOpen || self.config.inline) {
746
747
  switch (e.which) {
747
748
  case 13:
748
749
  if (self.timeContainer && self.timeContainer.contains(e.target)) updateValue();else selectDate(e);
@@ -756,6 +757,7 @@ function Flatpickr(element, config) {
756
757
 
757
758
  case 37:
758
759
  if (e.target !== self.input & e.target !== self.altInput) {
760
+ e.preventDefault();
759
761
  changeMonth(-1);
760
762
  self.currentMonthElement.focus();
761
763
  }
@@ -772,6 +774,7 @@ function Flatpickr(element, config) {
772
774
 
773
775
  case 39:
774
776
  if (e.target !== self.input & e.target !== self.altInput) {
777
+ e.preventDefault();
775
778
  changeMonth(1);
776
779
  self.currentMonthElement.focus();
777
780
  }
@@ -876,21 +879,25 @@ function Flatpickr(element, config) {
876
879
  function minMaxDateSetter(type) {
877
880
  return function (date) {
878
881
  var dateObj = self.config["_" + type + "Date"] = self.parseDate(date);
882
+
879
883
  var inverseDateObj = self.config["_" + (type === "min" ? "max" : "min") + "Date"];
880
884
  var isValidDate = date && dateObj instanceof Date;
881
885
 
886
+ if (isValidDate) {
887
+ self[type + "DateHasTime"] = dateObj.getHours() || dateObj.getMinutes() || dateObj.getSeconds();
888
+ }
889
+
882
890
  if (self.selectedDates) {
883
- self.selectedDates = self.selectedDates.filter(isEnabled);
891
+ self.selectedDates = self.selectedDates.filter(function (d) {
892
+ return isEnabled(d);
893
+ });
894
+ if (!self.selectedDates.length && type === "min") setHoursFromDate(dateObj);
884
895
  updateValue();
885
896
  }
886
897
 
887
- if (self.days) redraw();
898
+ if (self.days) {
899
+ redraw();
888
900
 
889
- if (isValidDate) {
890
- self[type + "DateHasTime"] = dateObj.getHours() || dateObj.getMinutes() || dateObj.getSeconds();
891
- }
892
-
893
- if (self.currentYearElement) {
894
901
  if (isValidDate) self.currentYearElement[type] = dateObj.getFullYear();else self.currentYearElement.removeAttribute(type);
895
902
 
896
903
  self.currentYearElement.disabled = inverseDateObj && dateObj && inverseDateObj.getFullYear() === dateObj.getFullYear();
@@ -901,10 +908,25 @@ function Flatpickr(element, config) {
901
908
  function parseConfig() {
902
909
  var boolOpts = ["utc", "wrap", "weekNumbers", "allowInput", "clickOpens", "time_24hr", "enableTime", "noCalendar", "altInput", "shorthandCurrentMonth", "inline", "static", "enableSeconds", "disableMobile"];
903
910
 
904
- var hooks = ["onChange", "onClose", "onDayCreate", "onMonthChange", "onOpen", "onReady", "onValueUpdate", "onYearChange"];
911
+ var hooks = ["onChange", "onClose", "onDayCreate", "onMonthChange", "onOpen", "onParseConfig", "onReady", "onValueUpdate", "onYearChange"];
905
912
 
906
913
  self.config = Object.create(Flatpickr.defaultConfig);
907
914
 
915
+ var userConfig = _extends({}, self.instanceConfig, JSON.parse(JSON.stringify(self.element.dataset || {})));
916
+
917
+ self.config.parseDate = userConfig.parseDate;
918
+ self.config.formatDate = userConfig.formatDate;
919
+
920
+ _extends(self.config, userConfig);
921
+
922
+ if (!userConfig.dateFormat && userConfig.enableTime) {
923
+ self.config.dateFormat = self.config.noCalendar ? "H:i" + (self.config.enableSeconds ? ":S" : "") : Flatpickr.defaultConfig.dateFormat + " H:i" + (self.config.enableSeconds ? ":S" : "");
924
+ }
925
+
926
+ if (userConfig.altInput && userConfig.enableTime && !userConfig.altFormat) {
927
+ self.config.altFormat = self.config.noCalendar ? "h:i" + (self.config.enableSeconds ? ":S K" : " K") : Flatpickr.defaultConfig.altFormat + (" h:i" + (self.config.enableSeconds ? ":S" : "") + " K");
928
+ }
929
+
908
930
  Object.defineProperty(self.config, "minDate", {
909
931
  get: function get() {
910
932
  return this._minDate;
@@ -919,33 +941,21 @@ function Flatpickr(element, config) {
919
941
  set: minMaxDateSetter("max")
920
942
  });
921
943
 
922
- var userConfig = _extends({}, self.instanceConfig, JSON.parse(JSON.stringify(self.element.dataset || {})));
923
-
924
- self.config.parseDate = userConfig.parseDate;
925
- self.config.formatDate = userConfig.formatDate;
926
-
927
- _extends(self.config, userConfig);
944
+ self.config.minDate = userConfig.minDate;
945
+ self.config.maxDate = userConfig.maxDate;
928
946
 
929
947
  for (var i = 0; i < boolOpts.length; i++) {
930
948
  self.config[boolOpts[i]] = self.config[boolOpts[i]] === true || self.config[boolOpts[i]] === "true";
931
949
  }for (var _i = 0; _i < hooks.length; _i++) {
932
- self.config[hooks[_i]] = arrayify(self.config[hooks[_i]] || []);
933
- }
934
-
935
- if (!userConfig.dateFormat && userConfig.enableTime) {
936
- self.config.dateFormat = self.config.noCalendar ? "H:i" + (self.config.enableSeconds ? ":S" : "") : Flatpickr.defaultConfig.dateFormat + " H:i" + (self.config.enableSeconds ? ":S" : "");
937
- }
938
-
939
- if (userConfig.altInput && userConfig.enableTime && !userConfig.altFormat) {
940
- self.config.altFormat = self.config.noCalendar ? "h:i" + (self.config.enableSeconds ? ":S K" : " K") : Flatpickr.defaultConfig.altFormat + (" h:i" + (self.config.enableSeconds ? ":S" : "") + " K");
941
- }
942
-
943
- for (var _i2 = 0; _i2 < self.config.plugins.length; _i2++) {
950
+ self.config[hooks[_i]] = arrayify(self.config[hooks[_i]] || []).map(bindToInstance);
951
+ }for (var _i2 = 0; _i2 < self.config.plugins.length; _i2++) {
944
952
  var pluginConf = self.config.plugins[_i2](self) || {};
945
953
  for (var key in pluginConf) {
946
- if (Array.isArray(self.config[key])) self.config[key] = arrayify(pluginConf[key]).concat(self.config[key]);else if (userConfig[key] !== undefined) self.config[key] = pluginConf[key];
954
+ if (Array.isArray(self.config[key])) self.config[key] = arrayify(pluginConf[key]).map(bindToInstance).concat(self.config[key]);else if (typeof userConfig[key] === "undefined") self.config[key] = pluginConf[key];
947
955
  }
948
956
  }
957
+
958
+ triggerEvent("ParseConfig");
949
959
  }
950
960
 
951
961
  function setupLocale() {
@@ -959,15 +969,16 @@ function Flatpickr(element, config) {
959
969
 
960
970
  var calendarHeight = self.calendarContainer.offsetHeight,
961
971
  calendarWidth = self.calendarContainer.offsetWidth,
972
+ configPos = self.config.position,
962
973
  input = self.altInput || self.input,
963
974
  inputBounds = input.getBoundingClientRect(),
964
975
  distanceFromBottom = window.innerHeight - inputBounds.bottom + input.offsetHeight,
965
- bottomCalendar = distanceFromBottom < calendarHeight + 60;
976
+ showOnTop = configPos === "above" || configPos !== "below" && distanceFromBottom < calendarHeight + 60;
966
977
 
967
- var top = window.pageYOffset + inputBounds.top + (!bottomCalendar ? input.offsetHeight + 2 : -calendarHeight - 2);
978
+ var top = window.pageYOffset + inputBounds.top + (!showOnTop ? input.offsetHeight + 2 : -calendarHeight - 2);
968
979
 
969
- toggleClass(self.calendarContainer, "arrowTop", !bottomCalendar);
970
- toggleClass(self.calendarContainer, "arrowBottom", bottomCalendar);
980
+ toggleClass(self.calendarContainer, "arrowTop", !showOnTop);
981
+ toggleClass(self.calendarContainer, "arrowBottom", showOnTop);
971
982
 
972
983
  if (self.config.inline) return;
973
984
 
@@ -1002,7 +1013,10 @@ function Flatpickr(element, config) {
1002
1013
  e.preventDefault();
1003
1014
  e.stopPropagation();
1004
1015
 
1005
- if (self.config.allowInput && e.which === 13 && e.target === (self.altInput || self.input)) return self.setDate((self.altInput || self.input).value), e.target.blur();
1016
+ if (self.config.allowInput && e.which === 13 && e.target === (self.altInput || self.input)) {
1017
+ self.setDate((self.altInput || self.input).value, true, e.target === self.altInput ? self.config.altFormat : self.config.dateFormat);
1018
+ return e.target.blur();
1019
+ }
1006
1020
 
1007
1021
  if (!e.target.classList.contains("flatpickr-day") || e.target.classList.contains("disabled") || e.target.classList.contains("notAllowed")) return;
1008
1022
 
@@ -1043,7 +1057,7 @@ function Flatpickr(element, config) {
1043
1057
  updateValue();
1044
1058
 
1045
1059
  setTimeout(function () {
1046
- return self.dateIsPicked = true;
1060
+ return self.showTimeInput = true;
1047
1061
  }, 50);
1048
1062
 
1049
1063
  if (self.config.mode === "range") {
@@ -1071,19 +1085,25 @@ function Flatpickr(element, config) {
1071
1085
  jumpToDate();
1072
1086
  }
1073
1087
 
1074
- function setSelectedDate(inputDate) {
1075
- if (Array.isArray(inputDate)) self.selectedDates = inputDate.map(self.parseDate);else if (inputDate instanceof Date || !isNaN(inputDate)) self.selectedDates = [self.parseDate(inputDate)];else if (inputDate && inputDate.substring) {
1088
+ function setSelectedDate(inputDate, format) {
1089
+ if (Array.isArray(inputDate)) self.selectedDates = inputDate.map(function (d) {
1090
+ return self.parseDate(d, false, format);
1091
+ });else if (inputDate instanceof Date || !isNaN(inputDate)) self.selectedDates = [self.parseDate(inputDate)];else if (inputDate && inputDate.substring) {
1076
1092
  switch (self.config.mode) {
1077
1093
  case "single":
1078
- self.selectedDates = [self.parseDate(inputDate)];
1094
+ self.selectedDates = [self.parseDate(inputDate, false, format)];
1079
1095
  break;
1080
1096
 
1081
1097
  case "multiple":
1082
- self.selectedDates = inputDate.split("; ").map(self.parseDate);
1098
+ self.selectedDates = inputDate.split("; ").map(function (date) {
1099
+ return self.parseDate(date, false, format);
1100
+ });
1083
1101
  break;
1084
1102
 
1085
1103
  case "range":
1086
- self.selectedDates = inputDate.split(self.l10n.rangeSeparator).map(self.parseDate);
1104
+ self.selectedDates = inputDate.split(self.l10n.rangeSeparator).map(function (date) {
1105
+ return self.parseDate(date, false, format);
1106
+ });
1087
1107
 
1088
1108
  break;
1089
1109
 
@@ -1101,13 +1121,13 @@ function Flatpickr(element, config) {
1101
1121
  });
1102
1122
  }
1103
1123
 
1104
- function setDate(date, triggerChange) {
1124
+ function setDate(date, triggerChange, format) {
1105
1125
  if (!date) return self.clear();
1106
1126
 
1107
- setSelectedDate(date);
1127
+ setSelectedDate(date, format);
1108
1128
 
1109
1129
  if (self.selectedDates.length > 0) {
1110
- self.dateIsPicked = true;
1130
+ self.showTimeInput = true;
1111
1131
  self.latestSelectedDateObj = self.selectedDates[0];
1112
1132
  } else self.latestSelectedDateObj = null;
1113
1133
 
@@ -1162,6 +1182,14 @@ function Flatpickr(element, config) {
1162
1182
  self._selectedDateObj = date;
1163
1183
  }
1164
1184
  });
1185
+
1186
+ if (!self.isMobile) {
1187
+ Object.defineProperty(self, "showTimeInput", {
1188
+ set: function set(bool) {
1189
+ if (self.calendarContainer) toggleClass(self.calendarContainer, "showTimeInput", bool);
1190
+ }
1191
+ });
1192
+ }
1165
1193
  }
1166
1194
 
1167
1195
  function setupHelperFunctions() {
@@ -1188,107 +1216,12 @@ function Flatpickr(element, config) {
1188
1216
 
1189
1217
  /* istanbul ignore next */
1190
1218
  function setupFormats() {
1191
- self.formats = {
1192
- // get the date in UTC
1193
- Z: function Z(date) {
1194
- return date.toISOString();
1195
- },
1196
-
1197
- // weekday name, short, e.g. Thu
1198
- D: function D(date) {
1199
- return self.l10n.weekdays.shorthand[self.formats.w(date)];
1200
- },
1201
-
1202
- // full month name e.g. January
1203
- F: function F(date) {
1204
- return self.utils.monthToStr(self.formats.n(date) - 1, false);
1205
- },
1206
-
1207
- // hours with leading zero e.g. 03
1208
- H: function H(date) {
1209
- return Flatpickr.prototype.pad(date.getHours());
1210
- },
1211
-
1212
- // day (1-30) with ordinal suffix e.g. 1st, 2nd
1213
- J: function J(date) {
1214
- return date.getDate() + self.l10n.ordinal(date.getDate());
1215
- },
1216
-
1217
- // AM/PM
1218
- K: function K(date) {
1219
- return date.getHours() > 11 ? "PM" : "AM";
1220
- },
1221
-
1222
- // shorthand month e.g. Jan, Sep, Oct, etc
1223
- M: function M(date) {
1224
- return self.utils.monthToStr(date.getMonth(), true);
1225
- },
1226
-
1227
- // seconds 00-59
1228
- S: function S(date) {
1229
- return Flatpickr.prototype.pad(date.getSeconds());
1230
- },
1231
-
1232
- // unix timestamp
1233
- U: function U(date) {
1234
- return date.getTime() / 1000;
1235
- },
1236
-
1237
- // full year e.g. 2016
1238
- Y: function Y(date) {
1239
- return date.getFullYear();
1240
- },
1241
-
1242
- // day in month, padded (01-30)
1243
- d: function d(date) {
1244
- return Flatpickr.prototype.pad(self.formats.j(date));
1245
- },
1246
-
1247
- // hour from 1-12 (am/pm)
1248
- h: function h(date) {
1249
- return date.getHours() % 12 ? date.getHours() % 12 : 12;
1250
- },
1251
-
1252
- // minutes, padded with leading zero e.g. 09
1253
- i: function i(date) {
1254
- return Flatpickr.prototype.pad(date.getMinutes());
1255
- },
1256
-
1257
- // day in month (1-30)
1258
- j: function j(date) {
1259
- return date.getDate();
1260
- },
1261
-
1262
- // weekday name, full, e.g. Thursday
1263
- l: function l(date) {
1264
- return self.l10n.weekdays.longhand[self.formats.w(date)];
1265
- },
1266
-
1267
- // padded month number (01-12)
1268
- m: function m(date) {
1269
- return Flatpickr.prototype.pad(self.formats.n(date));
1270
- },
1271
-
1272
- // the month number (1-12)
1273
- n: function n(date) {
1274
- return date.getMonth() + 1;
1275
- },
1276
-
1277
- // seconds 0-59
1278
- s: function s(date) {
1279
- return date.getSeconds();
1280
- },
1281
-
1282
- // number of the day of the week
1283
- w: function w(date) {
1284
- return date.getDay();
1285
- },
1219
+ ["D", "F", "J", "M", "W", "l"].forEach(function (f) {
1220
+ self.formats[f] = Flatpickr.prototype.formats[f].bind(self);
1221
+ });
1286
1222
 
1287
- // last two digits of year e.g. 16 for 2016
1288
- y: function y(date) {
1289
- return String(self.formats.Y(date)).substring(2);
1290
- }
1291
- };
1223
+ self.revFormat.F = Flatpickr.prototype.revFormat.F.bind(self);
1224
+ self.revFormat.M = Flatpickr.prototype.revFormat.M.bind(self);
1292
1225
  }
1293
1226
 
1294
1227
  function setupInputs() {
@@ -1306,9 +1239,9 @@ function Flatpickr(element, config) {
1306
1239
  self.altInput = createElement(self.input.nodeName, self.input.className + " " + self.config.altInputClass);
1307
1240
  self.altInput.placeholder = self.input.placeholder;
1308
1241
  self.altInput.type = "text";
1309
-
1310
1242
  self.input.type = "hidden";
1311
- if (self.input.parentNode) self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
1243
+
1244
+ if (!self.config.static && self.input.parentNode) self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
1312
1245
  }
1313
1246
 
1314
1247
  if (!self.config.allowInput) (self.altInput || self.input).setAttribute("readonly", "readonly");
@@ -1360,7 +1293,7 @@ function Flatpickr(element, config) {
1360
1293
 
1361
1294
  if (hooks) {
1362
1295
  for (var i = 0; i < hooks.length; i++) {
1363
- hooks[i](self.selectedDates, self.input.value, self, data);
1296
+ hooks[i](self.selectedDates, self.input && self.input.value, self, data);
1364
1297
  }
1365
1298
  }
1366
1299
 
@@ -1493,7 +1426,9 @@ function Flatpickr(element, config) {
1493
1426
  e.preventDefault();
1494
1427
 
1495
1428
  var isKeyDown = e.type === "keydown",
1496
- isWheel = e.type === "wheel";
1429
+ isWheel = e.type === "wheel",
1430
+ isIncrement = e.type === "increment",
1431
+ input = e.target;
1497
1432
 
1498
1433
  if (e.type !== "input" && !isKeyDown && (e.target.value || e.target.textContent).length >= 2 // typed two digits
1499
1434
  ) {
@@ -1503,26 +1438,31 @@ function Flatpickr(element, config) {
1503
1438
 
1504
1439
  if (self.amPM && e.target === self.amPM) return e.target.textContent = ["AM", "PM"][e.target.textContent === "AM" | 0];
1505
1440
 
1506
- var min = Number(e.target.min),
1507
- max = Number(e.target.max),
1508
- step = Number(e.target.step),
1509
- curValue = parseInt(e.target.value, 10),
1510
- delta = !isKeyDown ? Math.max(-1, Math.min(1, e.wheelDelta || -e.deltaY)) || 0 : e.which === 38 ? 1 : -1;
1441
+ var min = Number(input.min),
1442
+ max = Number(input.max),
1443
+ step = Number(input.step),
1444
+ curValue = parseInt(input.value, 10),
1445
+ delta = e.delta || (!isKeyDown ? Math.max(-1, Math.min(1, e.wheelDelta || -e.deltaY)) || 0 : e.which === 38 ? 1 : -1);
1511
1446
 
1512
- var newValue = curValue + (isWheel || isKeyDown) * step * delta;
1447
+ var newValue = curValue + step * delta;
1513
1448
 
1514
- if (e.target.value.length === 2) {
1515
- var isHourElem = e.target === self.hourElement;
1449
+ if (input.value.length === 2) {
1450
+ var isHourElem = input === self.hourElement,
1451
+ isMinuteElem = input === self.minuteElement;
1516
1452
 
1517
1453
  if (newValue < min) {
1518
1454
  newValue = max + newValue + !isHourElem + (isHourElem && !self.amPM);
1455
+
1456
+ if (isMinuteElem) incrementNumInput(null, -1, self.hourElement);
1519
1457
  } else if (newValue > max) {
1520
- newValue = e.target === self.hourElement ? newValue - max - !self.amPM : min;
1458
+ newValue = input === self.hourElement ? newValue - max - !self.amPM : min;
1459
+
1460
+ if (isMinuteElem) incrementNumInput(null, 1, self.hourElement);
1521
1461
  }
1522
1462
 
1523
1463
  if (self.amPM && isHourElem && (step === 1 ? newValue + curValue === 23 : Math.abs(newValue - curValue) > step)) self.amPM.textContent = self.amPM.textContent === "PM" ? "AM" : "PM";
1524
1464
 
1525
- e.target.value = self.pad(newValue);
1465
+ input.value = self.pad(newValue);
1526
1466
  }
1527
1467
  }
1528
1468
 
@@ -1535,6 +1475,8 @@ Flatpickr.defaultConfig = {
1535
1475
 
1536
1476
  mode: "single",
1537
1477
 
1478
+ position: "top",
1479
+
1538
1480
  /* if true, dates will be parsed, formatted, and displayed in UTC.
1539
1481
  preloading date strings w/ timezones is recommended but not necessary */
1540
1482
  utc: false,
@@ -1648,24 +1590,31 @@ Flatpickr.defaultConfig = {
1648
1590
 
1649
1591
  plugins: [],
1650
1592
 
1593
+ // called every time calendar is closed
1594
+ onClose: [], // function (dateObj, dateStr) {}
1595
+
1651
1596
  // onChange callback when user selects a date or time
1652
1597
  onChange: [], // function (dateObj, dateStr) {}
1653
1598
 
1599
+ // called for every day element
1600
+ onDayCreate: [],
1601
+
1602
+ // called every time the month is changed
1603
+ onMonthChange: [],
1604
+
1654
1605
  // called every time calendar is opened
1655
1606
  onOpen: [], // function (dateObj, dateStr) {}
1656
1607
 
1657
- // called every time calendar is closed
1658
- onClose: [], // function (dateObj, dateStr) {}
1608
+ // called after the configuration has been parsed
1609
+ onParseConfig: [],
1659
1610
 
1660
1611
  // called after calendar is ready
1661
1612
  onReady: [], // function (dateObj, dateStr) {}
1662
1613
 
1614
+ // called after input value updated
1663
1615
  onValueUpdate: [],
1664
1616
 
1665
- onDayCreate: [],
1666
-
1667
- onMonthChange: [],
1668
-
1617
+ // called every time the year is changed
1669
1618
  onYearChange: []
1670
1619
  };
1671
1620
 
@@ -1712,43 +1661,228 @@ Flatpickr.setDefaults = function (config) {
1712
1661
  };
1713
1662
 
1714
1663
  Flatpickr.prototype = {
1664
+ formats: {
1665
+ // get the date in UTC
1666
+ Z: function Z(date) {
1667
+ return date.toISOString();
1668
+ },
1669
+
1670
+ // weekday name, short, e.g. Thu
1671
+ D: function D(date) {
1672
+ return this.l10n.weekdays.shorthand[this.formats.w(date)];
1673
+ },
1674
+
1675
+ // full month name e.g. January
1676
+ F: function F(date) {
1677
+ return this.utils.monthToStr(this.formats.n(date) - 1, false);
1678
+ },
1679
+
1680
+ // hours with leading zero e.g. 03
1681
+ H: function H(date) {
1682
+ return Flatpickr.prototype.pad(date.getHours());
1683
+ },
1684
+
1685
+ // day (1-30) with ordinal suffix e.g. 1st, 2nd
1686
+ J: function J(date) {
1687
+ return date.getDate() + this.l10n.ordinal(date.getDate());
1688
+ },
1689
+
1690
+ // AM/PM
1691
+ K: function K(date) {
1692
+ return date.getHours() > 11 ? "PM" : "AM";
1693
+ },
1694
+
1695
+ // shorthand month e.g. Jan, Sep, Oct, etc
1696
+ M: function M(date) {
1697
+ return this.utils.monthToStr(date.getMonth(), true);
1698
+ },
1699
+
1700
+ // seconds 00-59
1701
+ S: function S(date) {
1702
+ return Flatpickr.prototype.pad(date.getSeconds());
1703
+ },
1704
+
1705
+ // unix timestamp
1706
+ U: function U(date) {
1707
+ return date.getTime() / 1000;
1708
+ },
1709
+
1710
+ W: function W(date) {
1711
+ return this.config.getWeek(date);
1712
+ },
1713
+
1714
+ // full year e.g. 2016
1715
+ Y: function Y(date) {
1716
+ return date.getFullYear();
1717
+ },
1718
+
1719
+ // day in month, padded (01-30)
1720
+ d: function d(date) {
1721
+ return Flatpickr.prototype.pad(date.getDate());
1722
+ },
1723
+
1724
+ // hour from 1-12 (am/pm)
1725
+ h: function h(date) {
1726
+ return date.getHours() % 12 ? date.getHours() % 12 : 12;
1727
+ },
1728
+
1729
+ // minutes, padded with leading zero e.g. 09
1730
+ i: function i(date) {
1731
+ return Flatpickr.prototype.pad(date.getMinutes());
1732
+ },
1733
+
1734
+ // day in month (1-30)
1735
+ j: function j(date) {
1736
+ return date.getDate();
1737
+ },
1738
+
1739
+ // weekday name, full, e.g. Thursday
1740
+ l: function l(date) {
1741
+ return this.l10n.weekdays.longhand[date.getDay()];
1742
+ },
1743
+
1744
+ // padded month number (01-12)
1745
+ m: function m(date) {
1746
+ return Flatpickr.prototype.pad(date.getMonth() + 1);
1747
+ },
1748
+
1749
+ // the month number (1-12)
1750
+ n: function n(date) {
1751
+ return date.getMonth() + 1;
1752
+ },
1753
+
1754
+ // seconds 0-59
1755
+ s: function s(date) {
1756
+ return date.getSeconds();
1757
+ },
1758
+
1759
+ // number of the day of the week
1760
+ w: function w(date) {
1761
+ return date.getDay();
1762
+ },
1763
+
1764
+ // last two digits of year e.g. 16 for 2016
1765
+ y: function y(date) {
1766
+ return String(date.getFullYear()).substring(2);
1767
+ }
1768
+ },
1769
+
1770
+ revFormat: {
1771
+ D: function D() {},
1772
+ F: function F(dateObj, monthName) {
1773
+ dateObj.setMonth(this.l10n.months.longhand.indexOf(monthName));
1774
+ },
1775
+ H: function H(dateObj, hour) {
1776
+ return dateObj.setHours(parseFloat(hour));
1777
+ },
1778
+ J: function J(dateObj, day) {
1779
+ return dateObj.setDate(parseFloat(day));
1780
+ },
1781
+ K: function K(dateObj, amPM) {
1782
+ var hours = dateObj.getHours();
1783
+
1784
+ if (hours !== 12) dateObj.setHours(hours % 12 + 12 * /pm/i.test(amPM));
1785
+ },
1786
+ M: function M(dateObj, shortMonth) {
1787
+ dateObj.setMonth(this.l10n.months.shorthand.indexOf(shortMonth));
1788
+ },
1789
+ S: function S(dateObj, seconds) {
1790
+ return dateObj.setSeconds(seconds);
1791
+ },
1792
+ W: function W() {},
1793
+ Y: function Y(dateObj, year) {
1794
+ return dateObj.setFullYear(year);
1795
+ },
1796
+ Z: function Z(dateObj, ISODate) {
1797
+ return dateObj = new Date(ISODate);
1798
+ },
1799
+
1800
+ d: function d(dateObj, day) {
1801
+ return dateObj.setDate(parseFloat(day));
1802
+ },
1803
+ h: function h(dateObj, hour) {
1804
+ return dateObj.setHours(parseFloat(hour));
1805
+ },
1806
+ i: function i(dateObj, minutes) {
1807
+ return dateObj.setMinutes(parseFloat(minutes));
1808
+ },
1809
+ j: function j(dateObj, day) {
1810
+ return dateObj.setDate(parseFloat(day));
1811
+ },
1812
+ l: function l() {},
1813
+ m: function m(dateObj, month) {
1814
+ return dateObj.setMonth(parseFloat(month) - 1);
1815
+ },
1816
+ n: function n(dateObj, month) {
1817
+ return dateObj.setMonth(parseFloat(month) - 1);
1818
+ },
1819
+ s: function s(dateObj, seconds) {
1820
+ return dateObj.setSeconds(parseFloat(seconds));
1821
+ },
1822
+ w: function w() {},
1823
+ y: function y(dateObj, year) {
1824
+ return dateObj.setFullYear(2000 + parseFloat(year));
1825
+ }
1826
+ },
1827
+
1828
+ tokenRegex: {
1829
+ D: "(\\w+)",
1830
+ F: "(\\w+)",
1831
+ H: "(\\d\\d|\\d)",
1832
+ J: "(\\d\\d|\\d)\\w+",
1833
+ K: "(\\w+)",
1834
+ M: "(\\w+)",
1835
+ S: "(\\d\\d|\\d)",
1836
+ Y: "(\\d{4})",
1837
+ Z: "(.+)",
1838
+ d: "(\\d\\d|\\d)",
1839
+ h: "(\\d\\d|\\d)",
1840
+ i: "(\\d\\d|\\d)",
1841
+ j: "(\\d\\d|\\d)",
1842
+ l: "(\\w+)",
1843
+ m: "(\\d\\d|\\d)",
1844
+ n: "(\\d\\d|\\d)",
1845
+ s: "(\\d\\d|\\d)",
1846
+ w: "(\\d\\d|\\d)",
1847
+ y: "(\\d{2})"
1848
+ },
1849
+
1715
1850
  pad: function pad(number) {
1716
1851
  return ("0" + number).slice(-2);
1717
1852
  },
1718
- parseDate: function parseDate(date, timeless) {
1853
+
1854
+ parseDate: function parseDate(date, timeless, givenFormat) {
1719
1855
  if (!date) return null;
1720
1856
 
1721
- var dateTimeRegex = /(\d+)/g,
1722
- timeRegex = /^(\d{1,2})[:\s](\d\d)?[:\s]?(\d\d)?\s?(a|p|A|P)?/i,
1723
- timestamp = /^(\d+)$/g,
1724
- date_orig = date;
1857
+ var date_orig = date;
1725
1858
 
1726
- if (date.toFixed || timestamp.test(date)) // timestamp
1859
+ if (date.toFixed) // timestamp
1727
1860
  date = new Date(date);else if (typeof date === "string") {
1861
+ var format = typeof givenFormat === "string" ? givenFormat : this.config.dateFormat;
1728
1862
  date = date.trim();
1729
1863
 
1730
1864
  if (date === "today") {
1731
1865
  date = new Date();
1732
1866
  timeless = true;
1733
- } else if (this.config && this.config.parseDate) date = this.config.parseDate(date);else if (timeRegex.test(date)) {
1734
- // time picker
1735
- var m = date.match(timeRegex),
1736
- hours = !m[4] ? m[1] // military time, no conversion needed
1737
- : m[1] % 12 + (m[4].toLowerCase() === "p" ? 12 : 0); // am/pm
1867
+ } else if (this.config && this.config.parseDate) date = this.config.parseDate(date);else if (/Z$/.test(date) || /GMT$/.test(date)) // datestrings w/ timezone
1868
+ date = new Date(date);else {
1869
+ var parsedDate = this.config.noCalendar ? new Date(new Date().setHours(0, 0, 0, 0)) : new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0);
1870
+
1871
+ var matched = false;
1872
+
1873
+ for (var i = 0, matchIndex = 0, regexStr = ""; i < format.length; i++) {
1874
+ var token = format[i];
1875
+ var isBackSlash = token === "\\";
1876
+ var escaped = format[i - 1] === "\\" || isBackSlash;
1877
+ if (this.tokenRegex[token] && !escaped) {
1878
+ regexStr += this.tokenRegex[token];
1879
+ var match = new RegExp(regexStr).exec(date);
1880
+ if (match && (matched = true)) this.revFormat[token](parsedDate, match[++matchIndex]);
1881
+ } else if (!isBackSlash) regexStr += "."; // don't really care
1882
+ }
1738
1883
 
1739
- date = new Date();
1740
- date.setHours(hours, m[2] || 0, m[3] || 0);
1741
- } else if (/Z$/.test(date) || /GMT$/.test(date)) // datestrings w/ timezone
1742
- date = new Date(date);else if (dateTimeRegex.test(date) && /^[0-9]/.test(date)) {
1743
- var d = date.match(dateTimeRegex),
1744
- isAM = /(am|AM)$/.test(date),
1745
- isPM = /(pm|PM)$/.test(date);
1746
-
1747
- date = new Date(d[0] + "/" + (d[1] || 1) + "/" + (d[2] || 1) + " " + (d[3] || 0) + ":" + (d[4] || 0) + ":" + (d[5] || 0));
1748
-
1749
- if (isAM || isPM) date.setHours(date.getHours() % 12 + 12 * isPM);
1750
- } else // fallback
1751
- date = new Date(date);
1884
+ date = matched ? parsedDate : null;
1885
+ }
1752
1886
  } else if (date instanceof Date) date = new Date(date.getTime()); // create a copy
1753
1887
 
1754
1888
  /* istanbul ignore next */