UNPKG

121 kBJavaScriptView Raw
1/* flatpickr v4.6.6, @license MIT */
2(function (global, factory) {
3 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
4 typeof define === 'function' && define.amd ? define(factory) :
5 (global = global || self, global.flatpickr = factory());
6}(this, (function () { 'use strict';
7
8 /*! *****************************************************************************
9 Copyright (c) Microsoft Corporation.
10
11 Permission to use, copy, modify, and/or distribute this software for any
12 purpose with or without fee is hereby granted.
13
14 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
15 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
17 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
18 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 PERFORMANCE OF THIS SOFTWARE.
21 ***************************************************************************** */
22
23 var __assign = function() {
24 __assign = Object.assign || function __assign(t) {
25 for (var s, i = 1, n = arguments.length; i < n; i++) {
26 s = arguments[i];
27 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
28 }
29 return t;
30 };
31 return __assign.apply(this, arguments);
32 };
33
34 function __spreadArrays() {
35 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
36 for (var r = Array(s), k = 0, i = 0; i < il; i++)
37 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
38 r[k] = a[j];
39 return r;
40 }
41
42 var HOOKS = [
43 "onChange",
44 "onClose",
45 "onDayCreate",
46 "onDestroy",
47 "onKeyDown",
48 "onMonthChange",
49 "onOpen",
50 "onParseConfig",
51 "onReady",
52 "onValueUpdate",
53 "onYearChange",
54 "onPreCalendarPosition",
55 ];
56 var defaults = {
57 _disable: [],
58 _enable: [],
59 allowInput: false,
60 allowInvalidPreload: false,
61 altFormat: "F j, Y",
62 altInput: false,
63 altInputClass: "form-control input",
64 animate: typeof window === "object" &&
65 window.navigator.userAgent.indexOf("MSIE") === -1,
66 ariaDateFormat: "F j, Y",
67 autoFillDefaultTime: true,
68 clickOpens: true,
69 closeOnSelect: true,
70 conjunction: ", ",
71 dateFormat: "Y-m-d",
72 defaultHour: 12,
73 defaultMinute: 0,
74 defaultSeconds: 0,
75 disable: [],
76 disableMobile: false,
77 enable: [],
78 enableSeconds: false,
79 enableTime: false,
80 errorHandler: function (err) {
81 return typeof console !== "undefined" && console.warn(err);
82 },
83 getWeek: function (givenDate) {
84 var date = new Date(givenDate.getTime());
85 date.setHours(0, 0, 0, 0);
86 // Thursday in current week decides the year.
87 date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));
88 // January 4 is always in week 1.
89 var week1 = new Date(date.getFullYear(), 0, 4);
90 // Adjust to Thursday in week 1 and count number of weeks from date to week1.
91 return (1 +
92 Math.round(((date.getTime() - week1.getTime()) / 86400000 -
93 3 +
94 ((week1.getDay() + 6) % 7)) /
95 7));
96 },
97 hourIncrement: 1,
98 ignoredFocusElements: [],
99 inline: false,
100 locale: "default",
101 minuteIncrement: 5,
102 mode: "single",
103 monthSelectorType: "dropdown",
104 nextArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",
105 noCalendar: false,
106 now: new Date(),
107 onChange: [],
108 onClose: [],
109 onDayCreate: [],
110 onDestroy: [],
111 onKeyDown: [],
112 onMonthChange: [],
113 onOpen: [],
114 onParseConfig: [],
115 onReady: [],
116 onValueUpdate: [],
117 onYearChange: [],
118 onPreCalendarPosition: [],
119 plugins: [],
120 position: "auto",
121 positionElement: undefined,
122 prevArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",
123 shorthandCurrentMonth: false,
124 showMonths: 1,
125 static: false,
126 time_24hr: false,
127 weekNumbers: false,
128 wrap: false,
129 };
130
131 var english = {
132 weekdays: {
133 shorthand: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
134 longhand: [
135 "Sunday",
136 "Monday",
137 "Tuesday",
138 "Wednesday",
139 "Thursday",
140 "Friday",
141 "Saturday",
142 ],
143 },
144 months: {
145 shorthand: [
146 "Jan",
147 "Feb",
148 "Mar",
149 "Apr",
150 "May",
151 "Jun",
152 "Jul",
153 "Aug",
154 "Sep",
155 "Oct",
156 "Nov",
157 "Dec",
158 ],
159 longhand: [
160 "January",
161 "February",
162 "March",
163 "April",
164 "May",
165 "June",
166 "July",
167 "August",
168 "September",
169 "October",
170 "November",
171 "December",
172 ],
173 },
174 daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
175 firstDayOfWeek: 0,
176 ordinal: function (nth) {
177 var s = nth % 100;
178 if (s > 3 && s < 21)
179 return "th";
180 switch (s % 10) {
181 case 1:
182 return "st";
183 case 2:
184 return "nd";
185 case 3:
186 return "rd";
187 default:
188 return "th";
189 }
190 },
191 rangeSeparator: " to ",
192 weekAbbreviation: "Wk",
193 scrollTitle: "Scroll to increment",
194 toggleTitle: "Click to toggle",
195 amPM: ["AM", "PM"],
196 yearAriaLabel: "Year",
197 monthAriaLabel: "Month",
198 hourAriaLabel: "Hour",
199 minuteAriaLabel: "Minute",
200 time_24hr: false,
201 };
202
203 var pad = function (number, length) {
204 if (length === void 0) { length = 2; }
205 return ("000" + number).slice(length * -1);
206 };
207 var int = function (bool) { return (bool === true ? 1 : 0); };
208 /* istanbul ignore next */
209 function debounce(func, wait, immediate) {
210 if (immediate === void 0) { immediate = false; }
211 var timeout;
212 return function () {
213 var context = this, args = arguments;
214 timeout !== null && clearTimeout(timeout);
215 timeout = window.setTimeout(function () {
216 timeout = null;
217 if (!immediate)
218 func.apply(context, args);
219 }, wait);
220 if (immediate && !timeout)
221 func.apply(context, args);
222 };
223 }
224 var arrayify = function (obj) {
225 return obj instanceof Array ? obj : [obj];
226 };
227
228 function toggleClass(elem, className, bool) {
229 if (bool === true)
230 return elem.classList.add(className);
231 elem.classList.remove(className);
232 }
233 function createElement(tag, className, content) {
234 var e = window.document.createElement(tag);
235 className = className || "";
236 content = content || "";
237 e.className = className;
238 if (content !== undefined)
239 e.textContent = content;
240 return e;
241 }
242 function clearNode(node) {
243 while (node.firstChild)
244 node.removeChild(node.firstChild);
245 }
246 function findParent(node, condition) {
247 if (condition(node))
248 return node;
249 else if (node.parentNode)
250 return findParent(node.parentNode, condition);
251 return undefined; // nothing found
252 }
253 function createNumberInput(inputClassName, opts) {
254 var wrapper = createElement("div", "numInputWrapper"), numInput = createElement("input", "numInput " + inputClassName), arrowUp = createElement("span", "arrowUp"), arrowDown = createElement("span", "arrowDown");
255 if (navigator.userAgent.indexOf("MSIE 9.0") === -1) {
256 numInput.type = "number";
257 }
258 else {
259 numInput.type = "text";
260 numInput.pattern = "\\d*";
261 }
262 if (opts !== undefined)
263 for (var key in opts)
264 numInput.setAttribute(key, opts[key]);
265 wrapper.appendChild(numInput);
266 wrapper.appendChild(arrowUp);
267 wrapper.appendChild(arrowDown);
268 return wrapper;
269 }
270 function getEventTarget(event) {
271 try {
272 if (typeof event.composedPath === "function") {
273 var path = event.composedPath();
274 return path[0];
275 }
276 return event.target;
277 }
278 catch (error) {
279 return event.target;
280 }
281 }
282
283 var doNothing = function () { return undefined; };
284 var monthToStr = function (monthNumber, shorthand, locale) { return locale.months[shorthand ? "shorthand" : "longhand"][monthNumber]; };
285 var revFormat = {
286 D: doNothing,
287 F: function (dateObj, monthName, locale) {
288 dateObj.setMonth(locale.months.longhand.indexOf(monthName));
289 },
290 G: function (dateObj, hour) {
291 dateObj.setHours(parseFloat(hour));
292 },
293 H: function (dateObj, hour) {
294 dateObj.setHours(parseFloat(hour));
295 },
296 J: function (dateObj, day) {
297 dateObj.setDate(parseFloat(day));
298 },
299 K: function (dateObj, amPM, locale) {
300 dateObj.setHours((dateObj.getHours() % 12) +
301 12 * int(new RegExp(locale.amPM[1], "i").test(amPM)));
302 },
303 M: function (dateObj, shortMonth, locale) {
304 dateObj.setMonth(locale.months.shorthand.indexOf(shortMonth));
305 },
306 S: function (dateObj, seconds) {
307 dateObj.setSeconds(parseFloat(seconds));
308 },
309 U: function (_, unixSeconds) { return new Date(parseFloat(unixSeconds) * 1000); },
310 W: function (dateObj, weekNum, locale) {
311 var weekNumber = parseInt(weekNum);
312 var date = new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0);
313 date.setDate(date.getDate() - date.getDay() + locale.firstDayOfWeek);
314 return date;
315 },
316 Y: function (dateObj, year) {
317 dateObj.setFullYear(parseFloat(year));
318 },
319 Z: function (_, ISODate) { return new Date(ISODate); },
320 d: function (dateObj, day) {
321 dateObj.setDate(parseFloat(day));
322 },
323 h: function (dateObj, hour) {
324 dateObj.setHours(parseFloat(hour));
325 },
326 i: function (dateObj, minutes) {
327 dateObj.setMinutes(parseFloat(minutes));
328 },
329 j: function (dateObj, day) {
330 dateObj.setDate(parseFloat(day));
331 },
332 l: doNothing,
333 m: function (dateObj, month) {
334 dateObj.setMonth(parseFloat(month) - 1);
335 },
336 n: function (dateObj, month) {
337 dateObj.setMonth(parseFloat(month) - 1);
338 },
339 s: function (dateObj, seconds) {
340 dateObj.setSeconds(parseFloat(seconds));
341 },
342 u: function (_, unixMillSeconds) {
343 return new Date(parseFloat(unixMillSeconds));
344 },
345 w: doNothing,
346 y: function (dateObj, year) {
347 dateObj.setFullYear(2000 + parseFloat(year));
348 },
349 };
350 var tokenRegex = {
351 D: "(\\w+)",
352 F: "(\\w+)",
353 G: "(\\d\\d|\\d)",
354 H: "(\\d\\d|\\d)",
355 J: "(\\d\\d|\\d)\\w+",
356 K: "",
357 M: "(\\w+)",
358 S: "(\\d\\d|\\d)",
359 U: "(.+)",
360 W: "(\\d\\d|\\d)",
361 Y: "(\\d{4})",
362 Z: "(.+)",
363 d: "(\\d\\d|\\d)",
364 h: "(\\d\\d|\\d)",
365 i: "(\\d\\d|\\d)",
366 j: "(\\d\\d|\\d)",
367 l: "(\\w+)",
368 m: "(\\d\\d|\\d)",
369 n: "(\\d\\d|\\d)",
370 s: "(\\d\\d|\\d)",
371 u: "(.+)",
372 w: "(\\d\\d|\\d)",
373 y: "(\\d{2})",
374 };
375 var formats = {
376 // get the date in UTC
377 Z: function (date) { return date.toISOString(); },
378 // weekday name, short, e.g. Thu
379 D: function (date, locale, options) {
380 return locale.weekdays.shorthand[formats.w(date, locale, options)];
381 },
382 // full month name e.g. January
383 F: function (date, locale, options) {
384 return monthToStr(formats.n(date, locale, options) - 1, false, locale);
385 },
386 // padded hour 1-12
387 G: function (date, locale, options) {
388 return pad(formats.h(date, locale, options));
389 },
390 // hours with leading zero e.g. 03
391 H: function (date) { return pad(date.getHours()); },
392 // day (1-30) with ordinal suffix e.g. 1st, 2nd
393 J: function (date, locale) {
394 return locale.ordinal !== undefined
395 ? date.getDate() + locale.ordinal(date.getDate())
396 : date.getDate();
397 },
398 // AM/PM
399 K: function (date, locale) { return locale.amPM[int(date.getHours() > 11)]; },
400 // shorthand month e.g. Jan, Sep, Oct, etc
401 M: function (date, locale) {
402 return monthToStr(date.getMonth(), true, locale);
403 },
404 // seconds 00-59
405 S: function (date) { return pad(date.getSeconds()); },
406 // unix timestamp
407 U: function (date) { return date.getTime() / 1000; },
408 W: function (date, _, options) {
409 return options.getWeek(date);
410 },
411 // full year e.g. 2016, padded (0001-9999)
412 Y: function (date) { return pad(date.getFullYear(), 4); },
413 // day in month, padded (01-30)
414 d: function (date) { return pad(date.getDate()); },
415 // hour from 1-12 (am/pm)
416 h: function (date) { return (date.getHours() % 12 ? date.getHours() % 12 : 12); },
417 // minutes, padded with leading zero e.g. 09
418 i: function (date) { return pad(date.getMinutes()); },
419 // day in month (1-30)
420 j: function (date) { return date.getDate(); },
421 // weekday name, full, e.g. Thursday
422 l: function (date, locale) {
423 return locale.weekdays.longhand[date.getDay()];
424 },
425 // padded month number (01-12)
426 m: function (date) { return pad(date.getMonth() + 1); },
427 // the month number (1-12)
428 n: function (date) { return date.getMonth() + 1; },
429 // seconds 0-59
430 s: function (date) { return date.getSeconds(); },
431 // Unix Milliseconds
432 u: function (date) { return date.getTime(); },
433 // number of the day of the week
434 w: function (date) { return date.getDay(); },
435 // last two digits of year e.g. 16 for 2016
436 y: function (date) { return String(date.getFullYear()).substring(2); },
437 };
438
439 var createDateFormatter = function (_a) {
440 var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c, _d = _a.isMobile, isMobile = _d === void 0 ? false : _d;
441 return function (dateObj, frmt, overrideLocale) {
442 var locale = overrideLocale || l10n;
443 if (config.formatDate !== undefined && !isMobile) {
444 return config.formatDate(dateObj, frmt, locale);
445 }
446 return frmt
447 .split("")
448 .map(function (c, i, arr) {
449 return formats[c] && arr[i - 1] !== "\\"
450 ? formats[c](dateObj, locale, config)
451 : c !== "\\"
452 ? c
453 : "";
454 })
455 .join("");
456 };
457 };
458 var createDateParser = function (_a) {
459 var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c;
460 return function (date, givenFormat, timeless, customLocale) {
461 if (date !== 0 && !date)
462 return undefined;
463 var locale = customLocale || l10n;
464 var parsedDate;
465 var dateOrig = date;
466 if (date instanceof Date)
467 parsedDate = new Date(date.getTime());
468 else if (typeof date !== "string" &&
469 date.toFixed !== undefined // timestamp
470 )
471 // create a copy
472 parsedDate = new Date(date);
473 else if (typeof date === "string") {
474 // date string
475 var format = givenFormat || (config || defaults).dateFormat;
476 var datestr = String(date).trim();
477 if (datestr === "today") {
478 parsedDate = new Date();
479 timeless = true;
480 }
481 else if (/Z$/.test(datestr) ||
482 /GMT$/.test(datestr) // datestrings w/ timezone
483 )
484 parsedDate = new Date(date);
485 else if (config && config.parseDate)
486 parsedDate = config.parseDate(date, format);
487 else {
488 parsedDate =
489 !config || !config.noCalendar
490 ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0)
491 : new Date(new Date().setHours(0, 0, 0, 0));
492 var matched = void 0, ops = [];
493 for (var i = 0, matchIndex = 0, regexStr = ""; i < format.length; i++) {
494 var token_1 = format[i];
495 var isBackSlash = token_1 === "\\";
496 var escaped = format[i - 1] === "\\" || isBackSlash;
497 if (tokenRegex[token_1] && !escaped) {
498 regexStr += tokenRegex[token_1];
499 var match = new RegExp(regexStr).exec(date);
500 if (match && (matched = true)) {
501 ops[token_1 !== "Y" ? "push" : "unshift"]({
502 fn: revFormat[token_1],
503 val: match[++matchIndex],
504 });
505 }
506 }
507 else if (!isBackSlash)
508 regexStr += "."; // don't really care
509 ops.forEach(function (_a) {
510 var fn = _a.fn, val = _a.val;
511 return (parsedDate = fn(parsedDate, val, locale) || parsedDate);
512 });
513 }
514 parsedDate = matched ? parsedDate : undefined;
515 }
516 }
517 /* istanbul ignore next */
518 if (!(parsedDate instanceof Date && !isNaN(parsedDate.getTime()))) {
519 config.errorHandler(new Error("Invalid date provided: " + dateOrig));
520 return undefined;
521 }
522 if (timeless === true)
523 parsedDate.setHours(0, 0, 0, 0);
524 return parsedDate;
525 };
526 };
527 /**
528 * Compute the difference in dates, measured in ms
529 */
530 function compareDates(date1, date2, timeless) {
531 if (timeless === void 0) { timeless = true; }
532 if (timeless !== false) {
533 return (new Date(date1.getTime()).setHours(0, 0, 0, 0) -
534 new Date(date2.getTime()).setHours(0, 0, 0, 0));
535 }
536 return date1.getTime() - date2.getTime();
537 }
538 var isBetween = function (ts, ts1, ts2) {
539 return ts > Math.min(ts1, ts2) && ts < Math.max(ts1, ts2);
540 };
541 var duration = {
542 DAY: 86400000,
543 };
544
545 if (typeof Object.assign !== "function") {
546 Object.assign = function (target) {
547 var args = [];
548 for (var _i = 1; _i < arguments.length; _i++) {
549 args[_i - 1] = arguments[_i];
550 }
551 if (!target) {
552 throw TypeError("Cannot convert undefined or null to object");
553 }
554 var _loop_1 = function (source) {
555 if (source) {
556 Object.keys(source).forEach(function (key) { return (target[key] = source[key]); });
557 }
558 };
559 for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
560 var source = args_1[_a];
561 _loop_1(source);
562 }
563 return target;
564 };
565 }
566
567 var DEBOUNCED_CHANGE_MS = 300;
568 function FlatpickrInstance(element, instanceConfig) {
569 var self = {
570 config: __assign(__assign({}, defaults), flatpickr.defaultConfig),
571 l10n: english,
572 };
573 self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });
574 self._handlers = [];
575 self.pluginElements = [];
576 self.loadedPlugins = [];
577 self._bind = bind;
578 self._setHoursFromDate = setHoursFromDate;
579 self._positionCalendar = positionCalendar;
580 self.changeMonth = changeMonth;
581 self.changeYear = changeYear;
582 self.clear = clear;
583 self.close = close;
584 self._createElement = createElement;
585 self.destroy = destroy;
586 self.isEnabled = isEnabled;
587 self.jumpToDate = jumpToDate;
588 self.open = open;
589 self.redraw = redraw;
590 self.set = set;
591 self.setDate = setDate;
592 self.toggle = toggle;
593 function setupHelperFunctions() {
594 self.utils = {
595 getDaysInMonth: function (month, yr) {
596 if (month === void 0) { month = self.currentMonth; }
597 if (yr === void 0) { yr = self.currentYear; }
598 if (month === 1 && ((yr % 4 === 0 && yr % 100 !== 0) || yr % 400 === 0))
599 return 29;
600 return self.l10n.daysInMonth[month];
601 },
602 };
603 }
604 function init() {
605 self.element = self.input = element;
606 self.isOpen = false;
607 parseConfig();
608 setupLocale();
609 setupInputs();
610 setupDates();
611 setupHelperFunctions();
612 if (!self.isMobile)
613 build();
614 bindEvents();
615 if (self.selectedDates.length || self.config.noCalendar) {
616 if (self.config.enableTime) {
617 setHoursFromDate(self.config.noCalendar
618 ? self.latestSelectedDateObj || self.config.minDate
619 : undefined);
620 }
621 updateValue(false);
622 }
623 setCalendarWidth();
624 var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
625 /* TODO: investigate this further
626
627 Currently, there is weird positioning behavior in safari causing pages
628 to scroll up. https://github.com/chmln/flatpickr/issues/563
629
630 However, most browsers are not Safari and positioning is expensive when used
631 in scale. https://github.com/chmln/flatpickr/issues/1096
632 */
633 if (!self.isMobile && isSafari) {
634 positionCalendar();
635 }
636 triggerEvent("onReady");
637 }
638 function bindToInstance(fn) {
639 return fn.bind(self);
640 }
641 function setCalendarWidth() {
642 var config = self.config;
643 if (config.weekNumbers === false && config.showMonths === 1) {
644 return;
645 }
646 else if (config.noCalendar !== true) {
647 window.requestAnimationFrame(function () {
648 if (self.calendarContainer !== undefined) {
649 self.calendarContainer.style.visibility = "hidden";
650 self.calendarContainer.style.display = "block";
651 }
652 if (self.daysContainer !== undefined) {
653 var daysWidth = (self.days.offsetWidth + 1) * config.showMonths;
654 self.daysContainer.style.width = daysWidth + "px";
655 self.calendarContainer.style.width =
656 daysWidth +
657 (self.weekWrapper !== undefined
658 ? self.weekWrapper.offsetWidth
659 : 0) +
660 "px";
661 self.calendarContainer.style.removeProperty("visibility");
662 self.calendarContainer.style.removeProperty("display");
663 }
664 });
665 }
666 }
667 /**
668 * The handler for all events targeting the time inputs
669 */
670 function updateTime(e) {
671 if (self.selectedDates.length === 0) {
672 var defaultDate = self.config.minDate !== undefined
673 ? new Date(self.config.minDate.getTime())
674 : new Date();
675 var _a = getDefaultHours(), hours = _a.hours, minutes = _a.minutes, seconds = _a.seconds;
676 defaultDate.setHours(hours, minutes, seconds, 0);
677 self.setDate(defaultDate, false);
678 }
679 if (e !== undefined && e.type !== "blur") {
680 timeWrapper(e);
681 }
682 var prevValue = self._input.value;
683 setHoursFromInputs();
684 updateValue();
685 if (self._input.value !== prevValue) {
686 self._debouncedChange();
687 }
688 }
689 function ampm2military(hour, amPM) {
690 return (hour % 12) + 12 * int(amPM === self.l10n.amPM[1]);
691 }
692 function military2ampm(hour) {
693 switch (hour % 24) {
694 case 0:
695 case 12:
696 return 12;
697 default:
698 return hour % 12;
699 }
700 }
701 /**
702 * Syncs the selected date object time with user's time input
703 */
704 function setHoursFromInputs() {
705 if (self.hourElement === undefined || self.minuteElement === undefined)
706 return;
707 var hours = (parseInt(self.hourElement.value.slice(-2), 10) || 0) % 24, minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60, seconds = self.secondElement !== undefined
708 ? (parseInt(self.secondElement.value, 10) || 0) % 60
709 : 0;
710 if (self.amPM !== undefined) {
711 hours = ampm2military(hours, self.amPM.textContent);
712 }
713 var limitMinHours = self.config.minTime !== undefined ||
714 (self.config.minDate &&
715 self.minDateHasTime &&
716 self.latestSelectedDateObj &&
717 compareDates(self.latestSelectedDateObj, self.config.minDate, true) ===
718 0);
719 var limitMaxHours = self.config.maxTime !== undefined ||
720 (self.config.maxDate &&
721 self.maxDateHasTime &&
722 self.latestSelectedDateObj &&
723 compareDates(self.latestSelectedDateObj, self.config.maxDate, true) ===
724 0);
725 if (limitMaxHours) {
726 var maxTime = self.config.maxTime !== undefined
727 ? self.config.maxTime
728 : self.config.maxDate;
729 hours = Math.min(hours, maxTime.getHours());
730 if (hours === maxTime.getHours())
731 minutes = Math.min(minutes, maxTime.getMinutes());
732 if (minutes === maxTime.getMinutes())
733 seconds = Math.min(seconds, maxTime.getSeconds());
734 }
735 if (limitMinHours) {
736 var minTime = self.config.minTime !== undefined
737 ? self.config.minTime
738 : self.config.minDate;
739 hours = Math.max(hours, minTime.getHours());
740 if (hours === minTime.getHours())
741 minutes = Math.max(minutes, minTime.getMinutes());
742 if (minutes === minTime.getMinutes())
743 seconds = Math.max(seconds, minTime.getSeconds());
744 }
745 setHours(hours, minutes, seconds);
746 }
747 /**
748 * Syncs time input values with a date
749 */
750 function setHoursFromDate(dateObj) {
751 var date = dateObj || self.latestSelectedDateObj;
752 if (date) {
753 setHours(date.getHours(), date.getMinutes(), date.getSeconds());
754 }
755 }
756 function getDefaultHours() {
757 var hours = self.config.defaultHour;
758 var minutes = self.config.defaultMinute;
759 var seconds = self.config.defaultSeconds;
760 if (self.config.minDate !== undefined) {
761 var minHr = self.config.minDate.getHours();
762 var minMinutes = self.config.minDate.getMinutes();
763 hours = Math.max(hours, minHr);
764 if (hours === minHr)
765 minutes = Math.max(minMinutes, minutes);
766 if (hours === minHr && minutes === minMinutes)
767 seconds = self.config.minDate.getSeconds();
768 }
769 if (self.config.maxDate !== undefined) {
770 var maxHr = self.config.maxDate.getHours();
771 var maxMinutes = self.config.maxDate.getMinutes();
772 hours = Math.min(hours, maxHr);
773 if (hours === maxHr)
774 minutes = Math.min(maxMinutes, minutes);
775 if (hours === maxHr && minutes === maxMinutes)
776 seconds = self.config.maxDate.getSeconds();
777 }
778 return { hours: hours, minutes: minutes, seconds: seconds };
779 }
780 /**
781 * Sets the hours, minutes, and optionally seconds
782 * of the latest selected date object and the
783 * corresponding time inputs
784 * @param {Number} hours the hour. whether its military
785 * or am-pm gets inferred from config
786 * @param {Number} minutes the minutes
787 * @param {Number} seconds the seconds (optional)
788 */
789 function setHours(hours, minutes, seconds) {
790 if (self.latestSelectedDateObj !== undefined) {
791 self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0);
792 }
793 if (!self.hourElement || !self.minuteElement || self.isMobile)
794 return;
795 self.hourElement.value = pad(!self.config.time_24hr
796 ? ((12 + hours) % 12) + 12 * int(hours % 12 === 0)
797 : hours);
798 self.minuteElement.value = pad(minutes);
799 if (self.amPM !== undefined)
800 self.amPM.textContent = self.l10n.amPM[int(hours >= 12)];
801 if (self.secondElement !== undefined)
802 self.secondElement.value = pad(seconds);
803 }
804 /**
805 * Handles the year input and incrementing events
806 * @param {Event} event the keyup or increment event
807 */
808 function onYearInput(event) {
809 var eventTarget = getEventTarget(event);
810 var year = parseInt(eventTarget.value) + (event.delta || 0);
811 if (year / 1000 > 1 ||
812 (event.key === "Enter" && !/[^\d]/.test(year.toString()))) {
813 changeYear(year);
814 }
815 }
816 /**
817 * Essentially addEventListener + tracking
818 * @param {Element} element the element to addEventListener to
819 * @param {String} event the event name
820 * @param {Function} handler the event handler
821 */
822 function bind(element, event, handler, options) {
823 if (event instanceof Array)
824 return event.forEach(function (ev) { return bind(element, ev, handler, options); });
825 if (element instanceof Array)
826 return element.forEach(function (el) { return bind(el, event, handler, options); });
827 element.addEventListener(event, handler, options);
828 self._handlers.push({
829 element: element,
830 event: event,
831 handler: handler,
832 options: options,
833 });
834 }
835 function triggerChange() {
836 triggerEvent("onChange");
837 }
838 /**
839 * Adds all the necessary event listeners
840 */
841 function bindEvents() {
842 if (self.config.wrap) {
843 ["open", "close", "toggle", "clear"].forEach(function (evt) {
844 Array.prototype.forEach.call(self.element.querySelectorAll("[data-" + evt + "]"), function (el) {
845 return bind(el, "click", self[evt]);
846 });
847 });
848 }
849 if (self.isMobile) {
850 setupMobile();
851 return;
852 }
853 var debouncedResize = debounce(onResize, 50);
854 self._debouncedChange = debounce(triggerChange, DEBOUNCED_CHANGE_MS);
855 if (self.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent))
856 bind(self.daysContainer, "mouseover", function (e) {
857 if (self.config.mode === "range")
858 onMouseOver(getEventTarget(e));
859 });
860 bind(window.document.body, "keydown", onKeyDown);
861 if (!self.config.inline && !self.config.static)
862 bind(window, "resize", debouncedResize);
863 if (window.ontouchstart !== undefined)
864 bind(window.document, "touchstart", documentClick);
865 else
866 bind(window.document, "click", documentClick);
867 bind(window.document, "focus", documentClick, { capture: true });
868 if (self.config.clickOpens === true) {
869 bind(self._input, "focus", self.open);
870 bind(self._input, "click", self.open);
871 }
872 if (self.daysContainer !== undefined) {
873 bind(self.monthNav, "click", onMonthNavClick);
874 bind(self.monthNav, ["keyup", "increment"], onYearInput);
875 bind(self.daysContainer, "click", selectDate);
876 }
877 if (self.timeContainer !== undefined &&
878 self.minuteElement !== undefined &&
879 self.hourElement !== undefined) {
880 var selText = function (e) {
881 return getEventTarget(e).select();
882 };
883 bind(self.timeContainer, ["increment"], updateTime);
884 bind(self.timeContainer, "blur", updateTime, { capture: true });
885 bind(self.timeContainer, "click", timeIncrement);
886 bind([self.hourElement, self.minuteElement], ["focus", "click"], selText);
887 if (self.secondElement !== undefined)
888 bind(self.secondElement, "focus", function () { return self.secondElement && self.secondElement.select(); });
889 if (self.amPM !== undefined) {
890 bind(self.amPM, "click", function (e) {
891 updateTime(e);
892 triggerChange();
893 });
894 }
895 }
896 if (self.config.allowInput)
897 bind(self._input, "blur", onBlur);
898 }
899 /**
900 * Set the calendar view to a particular date.
901 * @param {Date} jumpDate the date to set the view to
902 * @param {boolean} triggerChange if change events should be triggered
903 */
904 function jumpToDate(jumpDate, triggerChange) {
905 var jumpTo = jumpDate !== undefined
906 ? self.parseDate(jumpDate)
907 : self.latestSelectedDateObj ||
908 (self.config.minDate && self.config.minDate > self.now
909 ? self.config.minDate
910 : self.config.maxDate && self.config.maxDate < self.now
911 ? self.config.maxDate
912 : self.now);
913 var oldYear = self.currentYear;
914 var oldMonth = self.currentMonth;
915 try {
916 if (jumpTo !== undefined) {
917 self.currentYear = jumpTo.getFullYear();
918 self.currentMonth = jumpTo.getMonth();
919 }
920 }
921 catch (e) {
922 /* istanbul ignore next */
923 e.message = "Invalid date supplied: " + jumpTo;
924 self.config.errorHandler(e);
925 }
926 if (triggerChange && self.currentYear !== oldYear) {
927 triggerEvent("onYearChange");
928 buildMonthSwitch();
929 }
930 if (triggerChange &&
931 (self.currentYear !== oldYear || self.currentMonth !== oldMonth)) {
932 triggerEvent("onMonthChange");
933 }
934 self.redraw();
935 }
936 /**
937 * The up/down arrow handler for time inputs
938 * @param {Event} e the click event
939 */
940 function timeIncrement(e) {
941 var eventTarget = getEventTarget(e);
942 if (~eventTarget.className.indexOf("arrow"))
943 incrementNumInput(e, eventTarget.classList.contains("arrowUp") ? 1 : -1);
944 }
945 /**
946 * Increments/decrements the value of input associ-
947 * ated with the up/down arrow by dispatching an
948 * "increment" event on the input.
949 *
950 * @param {Event} e the click event
951 * @param {Number} delta the diff (usually 1 or -1)
952 * @param {Element} inputElem the input element
953 */
954 function incrementNumInput(e, delta, inputElem) {
955 var target = e && getEventTarget(e);
956 var input = inputElem ||
957 (target && target.parentNode && target.parentNode.firstChild);
958 var event = createEvent("increment");
959 event.delta = delta;
960 input && input.dispatchEvent(event);
961 }
962 function build() {
963 var fragment = window.document.createDocumentFragment();
964 self.calendarContainer = createElement("div", "flatpickr-calendar");
965 self.calendarContainer.tabIndex = -1;
966 if (!self.config.noCalendar) {
967 fragment.appendChild(buildMonthNav());
968 self.innerContainer = createElement("div", "flatpickr-innerContainer");
969 if (self.config.weekNumbers) {
970 var _a = buildWeeks(), weekWrapper = _a.weekWrapper, weekNumbers = _a.weekNumbers;
971 self.innerContainer.appendChild(weekWrapper);
972 self.weekNumbers = weekNumbers;
973 self.weekWrapper = weekWrapper;
974 }
975 self.rContainer = createElement("div", "flatpickr-rContainer");
976 self.rContainer.appendChild(buildWeekdays());
977 if (!self.daysContainer) {
978 self.daysContainer = createElement("div", "flatpickr-days");
979 self.daysContainer.tabIndex = -1;
980 }
981 buildDays();
982 self.rContainer.appendChild(self.daysContainer);
983 self.innerContainer.appendChild(self.rContainer);
984 fragment.appendChild(self.innerContainer);
985 }
986 if (self.config.enableTime) {
987 fragment.appendChild(buildTime());
988 }
989 toggleClass(self.calendarContainer, "rangeMode", self.config.mode === "range");
990 toggleClass(self.calendarContainer, "animate", self.config.animate === true);
991 toggleClass(self.calendarContainer, "multiMonth", self.config.showMonths > 1);
992 self.calendarContainer.appendChild(fragment);
993 var customAppend = self.config.appendTo !== undefined &&
994 self.config.appendTo.nodeType !== undefined;
995 if (self.config.inline || self.config.static) {
996 self.calendarContainer.classList.add(self.config.inline ? "inline" : "static");
997 if (self.config.inline) {
998 if (!customAppend && self.element.parentNode)
999 self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);
1000 else if (self.config.appendTo !== undefined)
1001 self.config.appendTo.appendChild(self.calendarContainer);
1002 }
1003 if (self.config.static) {
1004 var wrapper = createElement("div", "flatpickr-wrapper");
1005 if (self.element.parentNode)
1006 self.element.parentNode.insertBefore(wrapper, self.element);
1007 wrapper.appendChild(self.element);
1008 if (self.altInput)
1009 wrapper.appendChild(self.altInput);
1010 wrapper.appendChild(self.calendarContainer);
1011 }
1012 }
1013 if (!self.config.static && !self.config.inline)
1014 (self.config.appendTo !== undefined
1015 ? self.config.appendTo
1016 : window.document.body).appendChild(self.calendarContainer);
1017 }
1018 function createDay(className, date, dayNumber, i) {
1019 var dateIsEnabled = isEnabled(date, true), dayElement = createElement("span", "flatpickr-day " + className, date.getDate().toString());
1020 dayElement.dateObj = date;
1021 dayElement.$i = i;
1022 dayElement.setAttribute("aria-label", self.formatDate(date, self.config.ariaDateFormat));
1023 if (className.indexOf("hidden") === -1 &&
1024 compareDates(date, self.now) === 0) {
1025 self.todayDateElem = dayElement;
1026 dayElement.classList.add("today");
1027 dayElement.setAttribute("aria-current", "date");
1028 }
1029 if (dateIsEnabled) {
1030 dayElement.tabIndex = -1;
1031 if (isDateSelected(date)) {
1032 dayElement.classList.add("selected");
1033 self.selectedDateElem = dayElement;
1034 if (self.config.mode === "range") {
1035 toggleClass(dayElement, "startRange", self.selectedDates[0] &&
1036 compareDates(date, self.selectedDates[0], true) === 0);
1037 toggleClass(dayElement, "endRange", self.selectedDates[1] &&
1038 compareDates(date, self.selectedDates[1], true) === 0);
1039 if (className === "nextMonthDay")
1040 dayElement.classList.add("inRange");
1041 }
1042 }
1043 }
1044 else {
1045 dayElement.classList.add("flatpickr-disabled");
1046 }
1047 if (self.config.mode === "range") {
1048 if (isDateInRange(date) && !isDateSelected(date))
1049 dayElement.classList.add("inRange");
1050 }
1051 if (self.weekNumbers &&
1052 self.config.showMonths === 1 &&
1053 className !== "prevMonthDay" &&
1054 dayNumber % 7 === 1) {
1055 self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='flatpickr-day'>" + self.config.getWeek(date) + "</span>");
1056 }
1057 triggerEvent("onDayCreate", dayElement);
1058 return dayElement;
1059 }
1060 function focusOnDayElem(targetNode) {
1061 targetNode.focus();
1062 if (self.config.mode === "range")
1063 onMouseOver(targetNode);
1064 }
1065 function getFirstAvailableDay(delta) {
1066 var startMonth = delta > 0 ? 0 : self.config.showMonths - 1;
1067 var endMonth = delta > 0 ? self.config.showMonths : -1;
1068 for (var m = startMonth; m != endMonth; m += delta) {
1069 var month = self.daysContainer.children[m];
1070 var startIndex = delta > 0 ? 0 : month.children.length - 1;
1071 var endIndex = delta > 0 ? month.children.length : -1;
1072 for (var i = startIndex; i != endIndex; i += delta) {
1073 var c = month.children[i];
1074 if (c.className.indexOf("hidden") === -1 && isEnabled(c.dateObj))
1075 return c;
1076 }
1077 }
1078 return undefined;
1079 }
1080 function getNextAvailableDay(current, delta) {
1081 var givenMonth = current.className.indexOf("Month") === -1
1082 ? current.dateObj.getMonth()
1083 : self.currentMonth;
1084 var endMonth = delta > 0 ? self.config.showMonths : -1;
1085 var loopDelta = delta > 0 ? 1 : -1;
1086 for (var m = givenMonth - self.currentMonth; m != endMonth; m += loopDelta) {
1087 var month = self.daysContainer.children[m];
1088 var startIndex = givenMonth - self.currentMonth === m
1089 ? current.$i + delta
1090 : delta < 0
1091 ? month.children.length - 1
1092 : 0;
1093 var numMonthDays = month.children.length;
1094 for (var i = startIndex; i >= 0 && i < numMonthDays && i != (delta > 0 ? numMonthDays : -1); i += loopDelta) {
1095 var c = month.children[i];
1096 if (c.className.indexOf("hidden") === -1 &&
1097 isEnabled(c.dateObj) &&
1098 Math.abs(current.$i - i) >= Math.abs(delta))
1099 return focusOnDayElem(c);
1100 }
1101 }
1102 self.changeMonth(loopDelta);
1103 focusOnDay(getFirstAvailableDay(loopDelta), 0);
1104 return undefined;
1105 }
1106 function focusOnDay(current, offset) {
1107 var dayFocused = isInView(document.activeElement || document.body);
1108 var startElem = current !== undefined
1109 ? current
1110 : dayFocused
1111 ? document.activeElement
1112 : self.selectedDateElem !== undefined && isInView(self.selectedDateElem)
1113 ? self.selectedDateElem
1114 : self.todayDateElem !== undefined && isInView(self.todayDateElem)
1115 ? self.todayDateElem
1116 : getFirstAvailableDay(offset > 0 ? 1 : -1);
1117 if (startElem === undefined) {
1118 self._input.focus();
1119 }
1120 else if (!dayFocused) {
1121 focusOnDayElem(startElem);
1122 }
1123 else {
1124 getNextAvailableDay(startElem, offset);
1125 }
1126 }
1127 function buildMonthDays(year, month) {
1128 var firstOfMonth = (new Date(year, month, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7;
1129 var prevMonthDays = self.utils.getDaysInMonth((month - 1 + 12) % 12, year);
1130 var daysInMonth = self.utils.getDaysInMonth(month, year), days = window.document.createDocumentFragment(), isMultiMonth = self.config.showMonths > 1, prevMonthDayClass = isMultiMonth ? "prevMonthDay hidden" : "prevMonthDay", nextMonthDayClass = isMultiMonth ? "nextMonthDay hidden" : "nextMonthDay";
1131 var dayNumber = prevMonthDays + 1 - firstOfMonth, dayIndex = 0;
1132 // prepend days from the ending of previous month
1133 for (; dayNumber <= prevMonthDays; dayNumber++, dayIndex++) {
1134 days.appendChild(createDay(prevMonthDayClass, new Date(year, month - 1, dayNumber), dayNumber, dayIndex));
1135 }
1136 // Start at 1 since there is no 0th day
1137 for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {
1138 days.appendChild(createDay("", new Date(year, month, dayNumber), dayNumber, dayIndex));
1139 }
1140 // append days from the next month
1141 for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth &&
1142 (self.config.showMonths === 1 || dayIndex % 7 !== 0); dayNum++, dayIndex++) {
1143 days.appendChild(createDay(nextMonthDayClass, new Date(year, month + 1, dayNum % daysInMonth), dayNum, dayIndex));
1144 }
1145 //updateNavigationCurrentMonth();
1146 var dayContainer = createElement("div", "dayContainer");
1147 dayContainer.appendChild(days);
1148 return dayContainer;
1149 }
1150 function buildDays() {
1151 if (self.daysContainer === undefined) {
1152 return;
1153 }
1154 clearNode(self.daysContainer);
1155 // TODO: week numbers for each month
1156 if (self.weekNumbers)
1157 clearNode(self.weekNumbers);
1158 var frag = document.createDocumentFragment();
1159 for (var i = 0; i < self.config.showMonths; i++) {
1160 var d = new Date(self.currentYear, self.currentMonth, 1);
1161 d.setMonth(self.currentMonth + i);
1162 frag.appendChild(buildMonthDays(d.getFullYear(), d.getMonth()));
1163 }
1164 self.daysContainer.appendChild(frag);
1165 self.days = self.daysContainer.firstChild;
1166 if (self.config.mode === "range" && self.selectedDates.length === 1) {
1167 onMouseOver();
1168 }
1169 }
1170 function buildMonthSwitch() {
1171 if (self.config.showMonths > 1 ||
1172 self.config.monthSelectorType !== "dropdown")
1173 return;
1174 var shouldBuildMonth = function (month) {
1175 if (self.config.minDate !== undefined &&
1176 self.currentYear === self.config.minDate.getFullYear() &&
1177 month < self.config.minDate.getMonth()) {
1178 return false;
1179 }
1180 return !(self.config.maxDate !== undefined &&
1181 self.currentYear === self.config.maxDate.getFullYear() &&
1182 month > self.config.maxDate.getMonth());
1183 };
1184 self.monthsDropdownContainer.tabIndex = -1;
1185 self.monthsDropdownContainer.innerHTML = "";
1186 for (var i = 0; i < 12; i++) {
1187 if (!shouldBuildMonth(i))
1188 continue;
1189 var month = createElement("option", "flatpickr-monthDropdown-month");
1190 month.value = new Date(self.currentYear, i).getMonth().toString();
1191 month.textContent = monthToStr(i, self.config.shorthandCurrentMonth, self.l10n);
1192 month.tabIndex = -1;
1193 if (self.currentMonth === i) {
1194 month.selected = true;
1195 }
1196 self.monthsDropdownContainer.appendChild(month);
1197 }
1198 }
1199 function buildMonth() {
1200 var container = createElement("div", "flatpickr-month");
1201 var monthNavFragment = window.document.createDocumentFragment();
1202 var monthElement;
1203 if (self.config.showMonths > 1 ||
1204 self.config.monthSelectorType === "static") {
1205 monthElement = createElement("span", "cur-month");
1206 }
1207 else {
1208 self.monthsDropdownContainer = createElement("select", "flatpickr-monthDropdown-months");
1209 self.monthsDropdownContainer.setAttribute("aria-label", self.l10n.monthAriaLabel);
1210 bind(self.monthsDropdownContainer, "change", function (e) {
1211 var target = getEventTarget(e);
1212 var selectedMonth = parseInt(target.value, 10);
1213 self.changeMonth(selectedMonth - self.currentMonth);
1214 triggerEvent("onMonthChange");
1215 });
1216 buildMonthSwitch();
1217 monthElement = self.monthsDropdownContainer;
1218 }
1219 var yearInput = createNumberInput("cur-year", { tabindex: "-1" });
1220 var yearElement = yearInput.getElementsByTagName("input")[0];
1221 yearElement.setAttribute("aria-label", self.l10n.yearAriaLabel);
1222 if (self.config.minDate) {
1223 yearElement.setAttribute("min", self.config.minDate.getFullYear().toString());
1224 }
1225 if (self.config.maxDate) {
1226 yearElement.setAttribute("max", self.config.maxDate.getFullYear().toString());
1227 yearElement.disabled =
1228 !!self.config.minDate &&
1229 self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();
1230 }
1231 var currentMonth = createElement("div", "flatpickr-current-month");
1232 currentMonth.appendChild(monthElement);
1233 currentMonth.appendChild(yearInput);
1234 monthNavFragment.appendChild(currentMonth);
1235 container.appendChild(monthNavFragment);
1236 return {
1237 container: container,
1238 yearElement: yearElement,
1239 monthElement: monthElement,
1240 };
1241 }
1242 function buildMonths() {
1243 clearNode(self.monthNav);
1244 self.monthNav.appendChild(self.prevMonthNav);
1245 if (self.config.showMonths) {
1246 self.yearElements = [];
1247 self.monthElements = [];
1248 }
1249 for (var m = self.config.showMonths; m--;) {
1250 var month = buildMonth();
1251 self.yearElements.push(month.yearElement);
1252 self.monthElements.push(month.monthElement);
1253 self.monthNav.appendChild(month.container);
1254 }
1255 self.monthNav.appendChild(self.nextMonthNav);
1256 }
1257 function buildMonthNav() {
1258 self.monthNav = createElement("div", "flatpickr-months");
1259 self.yearElements = [];
1260 self.monthElements = [];
1261 self.prevMonthNav = createElement("span", "flatpickr-prev-month");
1262 self.prevMonthNav.innerHTML = self.config.prevArrow;
1263 self.nextMonthNav = createElement("span", "flatpickr-next-month");
1264 self.nextMonthNav.innerHTML = self.config.nextArrow;
1265 buildMonths();
1266 Object.defineProperty(self, "_hidePrevMonthArrow", {
1267 get: function () { return self.__hidePrevMonthArrow; },
1268 set: function (bool) {
1269 if (self.__hidePrevMonthArrow !== bool) {
1270 toggleClass(self.prevMonthNav, "flatpickr-disabled", bool);
1271 self.__hidePrevMonthArrow = bool;
1272 }
1273 },
1274 });
1275 Object.defineProperty(self, "_hideNextMonthArrow", {
1276 get: function () { return self.__hideNextMonthArrow; },
1277 set: function (bool) {
1278 if (self.__hideNextMonthArrow !== bool) {
1279 toggleClass(self.nextMonthNav, "flatpickr-disabled", bool);
1280 self.__hideNextMonthArrow = bool;
1281 }
1282 },
1283 });
1284 self.currentYearElement = self.yearElements[0];
1285 updateNavigationCurrentMonth();
1286 return self.monthNav;
1287 }
1288 function buildTime() {
1289 self.calendarContainer.classList.add("hasTime");
1290 if (self.config.noCalendar)
1291 self.calendarContainer.classList.add("noCalendar");
1292 self.timeContainer = createElement("div", "flatpickr-time");
1293 self.timeContainer.tabIndex = -1;
1294 var separator = createElement("span", "flatpickr-time-separator", ":");
1295 var hourInput = createNumberInput("flatpickr-hour", {
1296 "aria-label": self.l10n.hourAriaLabel,
1297 });
1298 self.hourElement = hourInput.getElementsByTagName("input")[0];
1299 var minuteInput = createNumberInput("flatpickr-minute", {
1300 "aria-label": self.l10n.minuteAriaLabel,
1301 });
1302 self.minuteElement = minuteInput.getElementsByTagName("input")[0];
1303 self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;
1304 self.hourElement.value = pad(self.latestSelectedDateObj
1305 ? self.latestSelectedDateObj.getHours()
1306 : self.config.time_24hr
1307 ? self.config.defaultHour
1308 : military2ampm(self.config.defaultHour));
1309 self.minuteElement.value = pad(self.latestSelectedDateObj
1310 ? self.latestSelectedDateObj.getMinutes()
1311 : self.config.defaultMinute);
1312 self.hourElement.setAttribute("step", self.config.hourIncrement.toString());
1313 self.minuteElement.setAttribute("step", self.config.minuteIncrement.toString());
1314 self.hourElement.setAttribute("min", self.config.time_24hr ? "0" : "1");
1315 self.hourElement.setAttribute("max", self.config.time_24hr ? "23" : "12");
1316 self.minuteElement.setAttribute("min", "0");
1317 self.minuteElement.setAttribute("max", "59");
1318 self.timeContainer.appendChild(hourInput);
1319 self.timeContainer.appendChild(separator);
1320 self.timeContainer.appendChild(minuteInput);
1321 if (self.config.time_24hr)
1322 self.timeContainer.classList.add("time24hr");
1323 if (self.config.enableSeconds) {
1324 self.timeContainer.classList.add("hasSeconds");
1325 var secondInput = createNumberInput("flatpickr-second");
1326 self.secondElement = secondInput.getElementsByTagName("input")[0];
1327 self.secondElement.value = pad(self.latestSelectedDateObj
1328 ? self.latestSelectedDateObj.getSeconds()
1329 : self.config.defaultSeconds);
1330 self.secondElement.setAttribute("step", self.minuteElement.getAttribute("step"));
1331 self.secondElement.setAttribute("min", "0");
1332 self.secondElement.setAttribute("max", "59");
1333 self.timeContainer.appendChild(createElement("span", "flatpickr-time-separator", ":"));
1334 self.timeContainer.appendChild(secondInput);
1335 }
1336 if (!self.config.time_24hr) {
1337 // add self.amPM if appropriate
1338 self.amPM = createElement("span", "flatpickr-am-pm", self.l10n.amPM[int((self.latestSelectedDateObj
1339 ? self.hourElement.value
1340 : self.config.defaultHour) > 11)]);
1341 self.amPM.title = self.l10n.toggleTitle;
1342 self.amPM.tabIndex = -1;
1343 self.timeContainer.appendChild(self.amPM);
1344 }
1345 return self.timeContainer;
1346 }
1347 function buildWeekdays() {
1348 if (!self.weekdayContainer)
1349 self.weekdayContainer = createElement("div", "flatpickr-weekdays");
1350 else
1351 clearNode(self.weekdayContainer);
1352 for (var i = self.config.showMonths; i--;) {
1353 var container = createElement("div", "flatpickr-weekdaycontainer");
1354 self.weekdayContainer.appendChild(container);
1355 }
1356 updateWeekdays();
1357 return self.weekdayContainer;
1358 }
1359 function updateWeekdays() {
1360 if (!self.weekdayContainer) {
1361 return;
1362 }
1363 var firstDayOfWeek = self.l10n.firstDayOfWeek;
1364 var weekdays = __spreadArrays(self.l10n.weekdays.shorthand);
1365 if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {
1366 weekdays = __spreadArrays(weekdays.splice(firstDayOfWeek, weekdays.length), weekdays.splice(0, firstDayOfWeek));
1367 }
1368 for (var i = self.config.showMonths; i--;) {
1369 self.weekdayContainer.children[i].innerHTML = "\n <span class='flatpickr-weekday'>\n " + weekdays.join("</span><span class='flatpickr-weekday'>") + "\n </span>\n ";
1370 }
1371 }
1372 /* istanbul ignore next */
1373 function buildWeeks() {
1374 self.calendarContainer.classList.add("hasWeeks");
1375 var weekWrapper = createElement("div", "flatpickr-weekwrapper");
1376 weekWrapper.appendChild(createElement("span", "flatpickr-weekday", self.l10n.weekAbbreviation));
1377 var weekNumbers = createElement("div", "flatpickr-weeks");
1378 weekWrapper.appendChild(weekNumbers);
1379 return {
1380 weekWrapper: weekWrapper,
1381 weekNumbers: weekNumbers,
1382 };
1383 }
1384 function changeMonth(value, isOffset) {
1385 if (isOffset === void 0) { isOffset = true; }
1386 var delta = isOffset ? value : value - self.currentMonth;
1387 if ((delta < 0 && self._hidePrevMonthArrow === true) ||
1388 (delta > 0 && self._hideNextMonthArrow === true))
1389 return;
1390 self.currentMonth += delta;
1391 if (self.currentMonth < 0 || self.currentMonth > 11) {
1392 self.currentYear += self.currentMonth > 11 ? 1 : -1;
1393 self.currentMonth = (self.currentMonth + 12) % 12;
1394 triggerEvent("onYearChange");
1395 buildMonthSwitch();
1396 }
1397 buildDays();
1398 triggerEvent("onMonthChange");
1399 updateNavigationCurrentMonth();
1400 }
1401 function clear(triggerChangeEvent, toInitial) {
1402 if (triggerChangeEvent === void 0) { triggerChangeEvent = true; }
1403 if (toInitial === void 0) { toInitial = true; }
1404 self.input.value = "";
1405 if (self.altInput !== undefined)
1406 self.altInput.value = "";
1407 if (self.mobileInput !== undefined)
1408 self.mobileInput.value = "";
1409 self.selectedDates = [];
1410 self.latestSelectedDateObj = undefined;
1411 if (toInitial === true) {
1412 self.currentYear = self._initialDate.getFullYear();
1413 self.currentMonth = self._initialDate.getMonth();
1414 }
1415 if (self.config.enableTime === true) {
1416 var _a = getDefaultHours(), hours = _a.hours, minutes = _a.minutes, seconds = _a.seconds;
1417 setHours(hours, minutes, seconds);
1418 }
1419 self.redraw();
1420 if (triggerChangeEvent)
1421 // triggerChangeEvent is true (default) or an Event
1422 triggerEvent("onChange");
1423 }
1424 function close() {
1425 self.isOpen = false;
1426 if (!self.isMobile) {
1427 if (self.calendarContainer !== undefined) {
1428 self.calendarContainer.classList.remove("open");
1429 }
1430 if (self._input !== undefined) {
1431 self._input.classList.remove("active");
1432 }
1433 }
1434 triggerEvent("onClose");
1435 }
1436 function destroy() {
1437 if (self.config !== undefined)
1438 triggerEvent("onDestroy");
1439 for (var i = self._handlers.length; i--;) {
1440 var h = self._handlers[i];
1441 h.element.removeEventListener(h.event, h.handler, h.options);
1442 }
1443 self._handlers = [];
1444 if (self.mobileInput) {
1445 if (self.mobileInput.parentNode)
1446 self.mobileInput.parentNode.removeChild(self.mobileInput);
1447 self.mobileInput = undefined;
1448 }
1449 else if (self.calendarContainer && self.calendarContainer.parentNode) {
1450 if (self.config.static && self.calendarContainer.parentNode) {
1451 var wrapper = self.calendarContainer.parentNode;
1452 wrapper.lastChild && wrapper.removeChild(wrapper.lastChild);
1453 if (wrapper.parentNode) {
1454 while (wrapper.firstChild)
1455 wrapper.parentNode.insertBefore(wrapper.firstChild, wrapper);
1456 wrapper.parentNode.removeChild(wrapper);
1457 }
1458 }
1459 else
1460 self.calendarContainer.parentNode.removeChild(self.calendarContainer);
1461 }
1462 if (self.altInput) {
1463 self.input.type = "text";
1464 if (self.altInput.parentNode)
1465 self.altInput.parentNode.removeChild(self.altInput);
1466 delete self.altInput;
1467 }
1468 if (self.input) {
1469 self.input.type = self.input._type;
1470 self.input.classList.remove("flatpickr-input");
1471 self.input.removeAttribute("readonly");
1472 }
1473 [
1474 "_showTimeInput",
1475 "latestSelectedDateObj",
1476 "_hideNextMonthArrow",
1477 "_hidePrevMonthArrow",
1478 "__hideNextMonthArrow",
1479 "__hidePrevMonthArrow",
1480 "isMobile",
1481 "isOpen",
1482 "selectedDateElem",
1483 "minDateHasTime",
1484 "maxDateHasTime",
1485 "days",
1486 "daysContainer",
1487 "_input",
1488 "_positionElement",
1489 "innerContainer",
1490 "rContainer",
1491 "monthNav",
1492 "todayDateElem",
1493 "calendarContainer",
1494 "weekdayContainer",
1495 "prevMonthNav",
1496 "nextMonthNav",
1497 "monthsDropdownContainer",
1498 "currentMonthElement",
1499 "currentYearElement",
1500 "navigationCurrentMonth",
1501 "selectedDateElem",
1502 "config",
1503 ].forEach(function (k) {
1504 try {
1505 delete self[k];
1506 }
1507 catch (_) { }
1508 });
1509 }
1510 function isCalendarElem(elem) {
1511 if (self.config.appendTo && self.config.appendTo.contains(elem))
1512 return true;
1513 return self.calendarContainer.contains(elem);
1514 }
1515 function documentClick(e) {
1516 if (self.isOpen && !self.config.inline) {
1517 var eventTarget_1 = getEventTarget(e);
1518 var isCalendarElement = isCalendarElem(eventTarget_1);
1519 var isInput = eventTarget_1 === self.input ||
1520 eventTarget_1 === self.altInput ||
1521 self.element.contains(eventTarget_1) ||
1522 // web components
1523 // e.path is not present in all browsers. circumventing typechecks
1524 (e.path &&
1525 e.path.indexOf &&
1526 (~e.path.indexOf(self.input) ||
1527 ~e.path.indexOf(self.altInput)));
1528 var lostFocus = e.type === "blur"
1529 ? isInput &&
1530 e.relatedTarget &&
1531 !isCalendarElem(e.relatedTarget)
1532 : !isInput &&
1533 !isCalendarElement &&
1534 !isCalendarElem(e.relatedTarget);
1535 var isIgnored = !self.config.ignoredFocusElements.some(function (elem) {
1536 return elem.contains(eventTarget_1);
1537 });
1538 if (lostFocus && isIgnored) {
1539 if (self.timeContainer !== undefined &&
1540 self.minuteElement !== undefined &&
1541 self.hourElement !== undefined &&
1542 self.input.value !== "" &&
1543 self.input.value !== undefined) {
1544 updateTime();
1545 }
1546 self.close();
1547 if (self.config &&
1548 self.config.mode === "range" &&
1549 self.selectedDates.length === 1) {
1550 self.clear(false);
1551 self.redraw();
1552 }
1553 }
1554 }
1555 }
1556 function changeYear(newYear) {
1557 if (!newYear ||
1558 (self.config.minDate && newYear < self.config.minDate.getFullYear()) ||
1559 (self.config.maxDate && newYear > self.config.maxDate.getFullYear()))
1560 return;
1561 var newYearNum = newYear, isNewYear = self.currentYear !== newYearNum;
1562 self.currentYear = newYearNum || self.currentYear;
1563 if (self.config.maxDate &&
1564 self.currentYear === self.config.maxDate.getFullYear()) {
1565 self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);
1566 }
1567 else if (self.config.minDate &&
1568 self.currentYear === self.config.minDate.getFullYear()) {
1569 self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);
1570 }
1571 if (isNewYear) {
1572 self.redraw();
1573 triggerEvent("onYearChange");
1574 buildMonthSwitch();
1575 }
1576 }
1577 function isEnabled(date, timeless) {
1578 if (timeless === void 0) { timeless = true; }
1579 var dateToCheck = self.parseDate(date, undefined, timeless); // timeless
1580 if ((self.config.minDate &&
1581 dateToCheck &&
1582 compareDates(dateToCheck, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0) ||
1583 (self.config.maxDate &&
1584 dateToCheck &&
1585 compareDates(dateToCheck, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0))
1586 return false;
1587 if (self.config.enable.length === 0 && self.config.disable.length === 0)
1588 return true;
1589 if (dateToCheck === undefined)
1590 return false;
1591 var bool = self.config.enable.length > 0, array = bool ? self.config.enable : self.config.disable;
1592 for (var i = 0, d = void 0; i < array.length; i++) {
1593 d = array[i];
1594 if (typeof d === "function" &&
1595 d(dateToCheck) // disabled by function
1596 )
1597 return bool;
1598 else if (d instanceof Date &&
1599 dateToCheck !== undefined &&
1600 d.getTime() === dateToCheck.getTime())
1601 // disabled by date
1602 return bool;
1603 else if (typeof d === "string" && dateToCheck !== undefined) {
1604 // disabled by date string
1605 var parsed = self.parseDate(d, undefined, true);
1606 return parsed && parsed.getTime() === dateToCheck.getTime()
1607 ? bool
1608 : !bool;
1609 }
1610 else if (
1611 // disabled by range
1612 typeof d === "object" &&
1613 dateToCheck !== undefined &&
1614 d.from &&
1615 d.to &&
1616 dateToCheck.getTime() >= d.from.getTime() &&
1617 dateToCheck.getTime() <= d.to.getTime())
1618 return bool;
1619 }
1620 return !bool;
1621 }
1622 function isInView(elem) {
1623 if (self.daysContainer !== undefined)
1624 return (elem.className.indexOf("hidden") === -1 &&
1625 elem.className.indexOf("flatpickr-disabled") === -1 &&
1626 self.daysContainer.contains(elem));
1627 return false;
1628 }
1629 function onBlur(e) {
1630 var isInput = e.target === self._input;
1631 if (isInput &&
1632 !(e.relatedTarget && isCalendarElem(e.relatedTarget))) {
1633 self.setDate(self._input.value, true, e.target === self.altInput
1634 ? self.config.altFormat
1635 : self.config.dateFormat);
1636 }
1637 }
1638 function onKeyDown(e) {
1639 // e.key e.keyCode
1640 // "Backspace" 8
1641 // "Tab" 9
1642 // "Enter" 13
1643 // "Escape" (IE "Esc") 27
1644 // "ArrowLeft" (IE "Left") 37
1645 // "ArrowUp" (IE "Up") 38
1646 // "ArrowRight" (IE "Right") 39
1647 // "ArrowDown" (IE "Down") 40
1648 // "Delete" (IE "Del") 46
1649 var eventTarget = getEventTarget(e);
1650 var isInput = self.config.wrap
1651 ? element.contains(eventTarget)
1652 : eventTarget === self._input;
1653 var allowInput = self.config.allowInput;
1654 var allowKeydown = self.isOpen && (!allowInput || !isInput);
1655 var allowInlineKeydown = self.config.inline && isInput && !allowInput;
1656 if (e.keyCode === 13 && isInput) {
1657 if (allowInput) {
1658 self.setDate(self._input.value, true, eventTarget === self.altInput
1659 ? self.config.altFormat
1660 : self.config.dateFormat);
1661 return eventTarget.blur();
1662 }
1663 else {
1664 self.open();
1665 }
1666 }
1667 else if (isCalendarElem(eventTarget) ||
1668 allowKeydown ||
1669 allowInlineKeydown) {
1670 var isTimeObj = !!self.timeContainer &&
1671 self.timeContainer.contains(eventTarget);
1672 switch (e.keyCode) {
1673 case 13:
1674 if (isTimeObj) {
1675 e.preventDefault();
1676 updateTime();
1677 focusAndClose();
1678 }
1679 else
1680 selectDate(e);
1681 break;
1682 case 27: // escape
1683 e.preventDefault();
1684 focusAndClose();
1685 break;
1686 case 8:
1687 case 46:
1688 if (isInput && !self.config.allowInput) {
1689 e.preventDefault();
1690 self.clear();
1691 }
1692 break;
1693 case 37:
1694 case 39:
1695 if (!isTimeObj && !isInput) {
1696 e.preventDefault();
1697 if (self.daysContainer !== undefined &&
1698 (allowInput === false ||
1699 (document.activeElement && isInView(document.activeElement)))) {
1700 var delta_1 = e.keyCode === 39 ? 1 : -1;
1701 if (!e.ctrlKey)
1702 focusOnDay(undefined, delta_1);
1703 else {
1704 e.stopPropagation();
1705 changeMonth(delta_1);
1706 focusOnDay(getFirstAvailableDay(1), 0);
1707 }
1708 }
1709 }
1710 else if (self.hourElement)
1711 self.hourElement.focus();
1712 break;
1713 case 38:
1714 case 40:
1715 e.preventDefault();
1716 var delta = e.keyCode === 40 ? 1 : -1;
1717 if ((self.daysContainer &&
1718 eventTarget.$i !== undefined) ||
1719 eventTarget === self.input ||
1720 eventTarget === self.altInput) {
1721 if (e.ctrlKey) {
1722 e.stopPropagation();
1723 changeYear(self.currentYear - delta);
1724 focusOnDay(getFirstAvailableDay(1), 0);
1725 }
1726 else if (!isTimeObj)
1727 focusOnDay(undefined, delta * 7);
1728 }
1729 else if (eventTarget === self.currentYearElement) {
1730 changeYear(self.currentYear - delta);
1731 }
1732 else if (self.config.enableTime) {
1733 if (!isTimeObj && self.hourElement)
1734 self.hourElement.focus();
1735 updateTime(e);
1736 self._debouncedChange();
1737 }
1738 break;
1739 case 9:
1740 if (isTimeObj) {
1741 var elems = [
1742 self.hourElement,
1743 self.minuteElement,
1744 self.secondElement,
1745 self.amPM,
1746 ]
1747 .concat(self.pluginElements)
1748 .filter(function (x) { return x; });
1749 var i = elems.indexOf(eventTarget);
1750 if (i !== -1) {
1751 var target = elems[i + (e.shiftKey ? -1 : 1)];
1752 e.preventDefault();
1753 (target || self._input).focus();
1754 }
1755 }
1756 else if (!self.config.noCalendar &&
1757 self.daysContainer &&
1758 self.daysContainer.contains(eventTarget) &&
1759 e.shiftKey) {
1760 e.preventDefault();
1761 self._input.focus();
1762 }
1763 break;
1764 }
1765 }
1766 if (self.amPM !== undefined && eventTarget === self.amPM) {
1767 switch (e.key) {
1768 case self.l10n.amPM[0].charAt(0):
1769 case self.l10n.amPM[0].charAt(0).toLowerCase():
1770 self.amPM.textContent = self.l10n.amPM[0];
1771 setHoursFromInputs();
1772 updateValue();
1773 break;
1774 case self.l10n.amPM[1].charAt(0):
1775 case self.l10n.amPM[1].charAt(0).toLowerCase():
1776 self.amPM.textContent = self.l10n.amPM[1];
1777 setHoursFromInputs();
1778 updateValue();
1779 break;
1780 }
1781 }
1782 if (isInput || isCalendarElem(eventTarget)) {
1783 triggerEvent("onKeyDown", e);
1784 }
1785 }
1786 function onMouseOver(elem) {
1787 if (self.selectedDates.length !== 1 ||
1788 (elem &&
1789 (!elem.classList.contains("flatpickr-day") ||
1790 elem.classList.contains("flatpickr-disabled"))))
1791 return;
1792 var hoverDate = elem
1793 ? elem.dateObj.getTime()
1794 : self.days.firstElementChild.dateObj.getTime(), initialDate = self.parseDate(self.selectedDates[0], undefined, true).getTime(), rangeStartDate = Math.min(hoverDate, self.selectedDates[0].getTime()), rangeEndDate = Math.max(hoverDate, self.selectedDates[0].getTime());
1795 var containsDisabled = false;
1796 var minRange = 0, maxRange = 0;
1797 for (var t = rangeStartDate; t < rangeEndDate; t += duration.DAY) {
1798 if (!isEnabled(new Date(t), true)) {
1799 containsDisabled =
1800 containsDisabled || (t > rangeStartDate && t < rangeEndDate);
1801 if (t < initialDate && (!minRange || t > minRange))
1802 minRange = t;
1803 else if (t > initialDate && (!maxRange || t < maxRange))
1804 maxRange = t;
1805 }
1806 }
1807 for (var m = 0; m < self.config.showMonths; m++) {
1808 var month = self.daysContainer.children[m];
1809 var _loop_1 = function (i, l) {
1810 var dayElem = month.children[i], date = dayElem.dateObj;
1811 var timestamp = date.getTime();
1812 var outOfRange = (minRange > 0 && timestamp < minRange) ||
1813 (maxRange > 0 && timestamp > maxRange);
1814 if (outOfRange) {
1815 dayElem.classList.add("notAllowed");
1816 ["inRange", "startRange", "endRange"].forEach(function (c) {
1817 dayElem.classList.remove(c);
1818 });
1819 return "continue";
1820 }
1821 else if (containsDisabled && !outOfRange)
1822 return "continue";
1823 ["startRange", "inRange", "endRange", "notAllowed"].forEach(function (c) {
1824 dayElem.classList.remove(c);
1825 });
1826 if (elem !== undefined) {
1827 elem.classList.add(hoverDate <= self.selectedDates[0].getTime()
1828 ? "startRange"
1829 : "endRange");
1830 if (initialDate < hoverDate && timestamp === initialDate)
1831 dayElem.classList.add("startRange");
1832 else if (initialDate > hoverDate && timestamp === initialDate)
1833 dayElem.classList.add("endRange");
1834 if (timestamp >= minRange &&
1835 (maxRange === 0 || timestamp <= maxRange) &&
1836 isBetween(timestamp, initialDate, hoverDate))
1837 dayElem.classList.add("inRange");
1838 }
1839 };
1840 for (var i = 0, l = month.children.length; i < l; i++) {
1841 _loop_1(i, l);
1842 }
1843 }
1844 }
1845 function onResize() {
1846 if (self.isOpen && !self.config.static && !self.config.inline)
1847 positionCalendar();
1848 }
1849 function open(e, positionElement) {
1850 if (positionElement === void 0) { positionElement = self._positionElement; }
1851 if (self.isMobile === true) {
1852 if (e) {
1853 e.preventDefault();
1854 var eventTarget = getEventTarget(e);
1855 eventTarget && eventTarget.blur();
1856 }
1857 if (self.mobileInput !== undefined) {
1858 self.mobileInput.focus();
1859 self.mobileInput.click();
1860 }
1861 triggerEvent("onOpen");
1862 return;
1863 }
1864 if (self._input.disabled || self.config.inline)
1865 return;
1866 var wasOpen = self.isOpen;
1867 self.isOpen = true;
1868 if (!wasOpen) {
1869 self.calendarContainer.classList.add("open");
1870 self._input.classList.add("active");
1871 triggerEvent("onOpen");
1872 positionCalendar(positionElement);
1873 }
1874 if (self.config.enableTime === true && self.config.noCalendar === true) {
1875 if (self.config.allowInput === false &&
1876 (e === undefined ||
1877 !self.timeContainer.contains(e.relatedTarget))) {
1878 setTimeout(function () { return self.hourElement.select(); }, 50);
1879 }
1880 }
1881 }
1882 function minMaxDateSetter(type) {
1883 return function (date) {
1884 var dateObj = (self.config["_" + type + "Date"] = self.parseDate(date, self.config.dateFormat));
1885 var inverseDateObj = self.config["_" + (type === "min" ? "max" : "min") + "Date"];
1886 if (dateObj !== undefined) {
1887 self[type === "min" ? "minDateHasTime" : "maxDateHasTime"] =
1888 dateObj.getHours() > 0 ||
1889 dateObj.getMinutes() > 0 ||
1890 dateObj.getSeconds() > 0;
1891 }
1892 if (self.selectedDates) {
1893 self.selectedDates = self.selectedDates.filter(function (d) { return isEnabled(d); });
1894 if (!self.selectedDates.length && type === "min")
1895 setHoursFromDate(dateObj);
1896 updateValue();
1897 }
1898 if (self.daysContainer) {
1899 redraw();
1900 if (dateObj !== undefined)
1901 self.currentYearElement[type] = dateObj.getFullYear().toString();
1902 else
1903 self.currentYearElement.removeAttribute(type);
1904 self.currentYearElement.disabled =
1905 !!inverseDateObj &&
1906 dateObj !== undefined &&
1907 inverseDateObj.getFullYear() === dateObj.getFullYear();
1908 }
1909 };
1910 }
1911 function parseConfig() {
1912 var boolOpts = [
1913 "wrap",
1914 "weekNumbers",
1915 "allowInput",
1916 "allowInvalidPreload",
1917 "clickOpens",
1918 "time_24hr",
1919 "enableTime",
1920 "noCalendar",
1921 "altInput",
1922 "shorthandCurrentMonth",
1923 "inline",
1924 "static",
1925 "enableSeconds",
1926 "disableMobile",
1927 ];
1928 var userConfig = __assign(__assign({}, JSON.parse(JSON.stringify(element.dataset || {}))), instanceConfig);
1929 var formats = {};
1930 self.config.parseDate = userConfig.parseDate;
1931 self.config.formatDate = userConfig.formatDate;
1932 Object.defineProperty(self.config, "enable", {
1933 get: function () { return self.config._enable; },
1934 set: function (dates) {
1935 self.config._enable = parseDateRules(dates);
1936 },
1937 });
1938 Object.defineProperty(self.config, "disable", {
1939 get: function () { return self.config._disable; },
1940 set: function (dates) {
1941 self.config._disable = parseDateRules(dates);
1942 },
1943 });
1944 var timeMode = userConfig.mode === "time";
1945 if (!userConfig.dateFormat && (userConfig.enableTime || timeMode)) {
1946 var defaultDateFormat = flatpickr.defaultConfig.dateFormat || defaults.dateFormat;
1947 formats.dateFormat =
1948 userConfig.noCalendar || timeMode
1949 ? "H:i" + (userConfig.enableSeconds ? ":S" : "")
1950 : defaultDateFormat + " H:i" + (userConfig.enableSeconds ? ":S" : "");
1951 }
1952 if (userConfig.altInput &&
1953 (userConfig.enableTime || timeMode) &&
1954 !userConfig.altFormat) {
1955 var defaultAltFormat = flatpickr.defaultConfig.altFormat || defaults.altFormat;
1956 formats.altFormat =
1957 userConfig.noCalendar || timeMode
1958 ? "h:i" + (userConfig.enableSeconds ? ":S K" : " K")
1959 : defaultAltFormat + (" h:i" + (userConfig.enableSeconds ? ":S" : "") + " K");
1960 }
1961 Object.defineProperty(self.config, "minDate", {
1962 get: function () { return self.config._minDate; },
1963 set: minMaxDateSetter("min"),
1964 });
1965 Object.defineProperty(self.config, "maxDate", {
1966 get: function () { return self.config._maxDate; },
1967 set: minMaxDateSetter("max"),
1968 });
1969 var minMaxTimeSetter = function (type) { return function (val) {
1970 self.config[type === "min" ? "_minTime" : "_maxTime"] = self.parseDate(val, "H:i:S");
1971 }; };
1972 Object.defineProperty(self.config, "minTime", {
1973 get: function () { return self.config._minTime; },
1974 set: minMaxTimeSetter("min"),
1975 });
1976 Object.defineProperty(self.config, "maxTime", {
1977 get: function () { return self.config._maxTime; },
1978 set: minMaxTimeSetter("max"),
1979 });
1980 if (userConfig.mode === "time") {
1981 self.config.noCalendar = true;
1982 self.config.enableTime = true;
1983 }
1984 Object.assign(self.config, formats, userConfig);
1985 for (var i = 0; i < boolOpts.length; i++)
1986 // https://github.com/microsoft/TypeScript/issues/31663
1987 self.config[boolOpts[i]] =
1988 self.config[boolOpts[i]] === true ||
1989 self.config[boolOpts[i]] === "true";
1990 HOOKS.filter(function (hook) { return self.config[hook] !== undefined; }).forEach(function (hook) {
1991 self.config[hook] = arrayify(self.config[hook] || []).map(bindToInstance);
1992 });
1993 self.isMobile =
1994 !self.config.disableMobile &&
1995 !self.config.inline &&
1996 self.config.mode === "single" &&
1997 !self.config.disable.length &&
1998 !self.config.enable.length &&
1999 !self.config.weekNumbers &&
2000 /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
2001 for (var i = 0; i < self.config.plugins.length; i++) {
2002 var pluginConf = self.config.plugins[i](self) || {};
2003 for (var key in pluginConf) {
2004 if (HOOKS.indexOf(key) > -1) {
2005 self.config[key] = arrayify(pluginConf[key])
2006 .map(bindToInstance)
2007 .concat(self.config[key]);
2008 }
2009 else if (typeof userConfig[key] === "undefined")
2010 self.config[key] = pluginConf[key];
2011 }
2012 }
2013 if (!userConfig.altInputClass) {
2014 self.config.altInputClass =
2015 getInputElem().className + " " + self.config.altInputClass;
2016 }
2017 triggerEvent("onParseConfig");
2018 }
2019 function getInputElem() {
2020 return self.config.wrap
2021 ? element.querySelector("[data-input]")
2022 : element;
2023 }
2024 function setupLocale() {
2025 if (typeof self.config.locale !== "object" &&
2026 typeof flatpickr.l10ns[self.config.locale] === "undefined")
2027 self.config.errorHandler(new Error("flatpickr: invalid locale " + self.config.locale));
2028 self.l10n = __assign(__assign({}, flatpickr.l10ns.default), (typeof self.config.locale === "object"
2029 ? self.config.locale
2030 : self.config.locale !== "default"
2031 ? flatpickr.l10ns[self.config.locale]
2032 : undefined));
2033 tokenRegex.K = "(" + self.l10n.amPM[0] + "|" + self.l10n.amPM[1] + "|" + self.l10n.amPM[0].toLowerCase() + "|" + self.l10n.amPM[1].toLowerCase() + ")";
2034 var userConfig = __assign(__assign({}, instanceConfig), JSON.parse(JSON.stringify(element.dataset || {})));
2035 if (userConfig.time_24hr === undefined &&
2036 flatpickr.defaultConfig.time_24hr === undefined) {
2037 self.config.time_24hr = self.l10n.time_24hr;
2038 }
2039 self.formatDate = createDateFormatter(self);
2040 self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });
2041 }
2042 function positionCalendar(customPositionElement) {
2043 if (self.calendarContainer === undefined)
2044 return;
2045 triggerEvent("onPreCalendarPosition");
2046 var positionElement = customPositionElement || self._positionElement;
2047 var calendarHeight = Array.prototype.reduce.call(self.calendarContainer.children, (function (acc, child) { return acc + child.offsetHeight; }), 0), calendarWidth = self.calendarContainer.offsetWidth, configPos = self.config.position.split(" "), configPosVertical = configPos[0], configPosHorizontal = configPos.length > 1 ? configPos[1] : null, inputBounds = positionElement.getBoundingClientRect(), distanceFromBottom = window.innerHeight - inputBounds.bottom, showOnTop = configPosVertical === "above" ||
2048 (configPosVertical !== "below" &&
2049 distanceFromBottom < calendarHeight &&
2050 inputBounds.top > calendarHeight);
2051 var top = window.pageYOffset +
2052 inputBounds.top +
2053 (!showOnTop ? positionElement.offsetHeight + 2 : -calendarHeight - 2);
2054 toggleClass(self.calendarContainer, "arrowTop", !showOnTop);
2055 toggleClass(self.calendarContainer, "arrowBottom", showOnTop);
2056 if (self.config.inline)
2057 return;
2058 var left = window.pageXOffset + inputBounds.left;
2059 var isCenter = false;
2060 var isRight = false;
2061 if (configPosHorizontal === "center") {
2062 left -= (calendarWidth - inputBounds.width) / 2;
2063 isCenter = true;
2064 }
2065 else if (configPosHorizontal === "right") {
2066 left -= calendarWidth - inputBounds.width;
2067 isRight = true;
2068 }
2069 toggleClass(self.calendarContainer, "arrowLeft", !isCenter && !isRight);
2070 toggleClass(self.calendarContainer, "arrowCenter", isCenter);
2071 toggleClass(self.calendarContainer, "arrowRight", isRight);
2072 var right = window.document.body.offsetWidth -
2073 (window.pageXOffset + inputBounds.right);
2074 var rightMost = left + calendarWidth > window.document.body.offsetWidth;
2075 var centerMost = right + calendarWidth > window.document.body.offsetWidth;
2076 toggleClass(self.calendarContainer, "rightMost", rightMost);
2077 if (self.config.static)
2078 return;
2079 self.calendarContainer.style.top = top + "px";
2080 if (!rightMost) {
2081 self.calendarContainer.style.left = left + "px";
2082 self.calendarContainer.style.right = "auto";
2083 }
2084 else if (!centerMost) {
2085 self.calendarContainer.style.left = "auto";
2086 self.calendarContainer.style.right = right + "px";
2087 }
2088 else {
2089 var doc = getDocumentStyleSheet();
2090 // some testing environments don't have css support
2091 if (doc === undefined)
2092 return;
2093 var bodyWidth = window.document.body.offsetWidth;
2094 var centerLeft = Math.max(0, bodyWidth / 2 - calendarWidth / 2);
2095 var centerBefore = ".flatpickr-calendar.centerMost:before";
2096 var centerAfter = ".flatpickr-calendar.centerMost:after";
2097 var centerIndex = doc.cssRules.length;
2098 var centerStyle = "{left:" + inputBounds.left + "px;right:auto;}";
2099 toggleClass(self.calendarContainer, "rightMost", false);
2100 toggleClass(self.calendarContainer, "centerMost", true);
2101 doc.insertRule(centerBefore + "," + centerAfter + centerStyle, centerIndex);
2102 self.calendarContainer.style.left = centerLeft + "px";
2103 self.calendarContainer.style.right = "auto";
2104 }
2105 }
2106 function getDocumentStyleSheet() {
2107 var editableSheet = null;
2108 for (var i = 0; i < document.styleSheets.length; i++) {
2109 var sheet = document.styleSheets[i];
2110 try {
2111 sheet.cssRules;
2112 }
2113 catch (err) {
2114 continue;
2115 }
2116 editableSheet = sheet;
2117 break;
2118 }
2119 return editableSheet != null ? editableSheet : createStyleSheet();
2120 }
2121 function createStyleSheet() {
2122 var style = document.createElement("style");
2123 document.head.appendChild(style);
2124 return style.sheet;
2125 }
2126 function redraw() {
2127 if (self.config.noCalendar || self.isMobile)
2128 return;
2129 buildMonthSwitch();
2130 updateNavigationCurrentMonth();
2131 buildDays();
2132 }
2133 function focusAndClose() {
2134 self._input.focus();
2135 if (window.navigator.userAgent.indexOf("MSIE") !== -1 ||
2136 navigator.msMaxTouchPoints !== undefined) {
2137 // hack - bugs in the way IE handles focus keeps the calendar open
2138 setTimeout(self.close, 0);
2139 }
2140 else {
2141 self.close();
2142 }
2143 }
2144 function selectDate(e) {
2145 e.preventDefault();
2146 e.stopPropagation();
2147 var isSelectable = function (day) {
2148 return day.classList &&
2149 day.classList.contains("flatpickr-day") &&
2150 !day.classList.contains("flatpickr-disabled") &&
2151 !day.classList.contains("notAllowed");
2152 };
2153 var t = findParent(getEventTarget(e), isSelectable);
2154 if (t === undefined)
2155 return;
2156 var target = t;
2157 var selectedDate = (self.latestSelectedDateObj = new Date(target.dateObj.getTime()));
2158 var shouldChangeMonth = (selectedDate.getMonth() < self.currentMonth ||
2159 selectedDate.getMonth() >
2160 self.currentMonth + self.config.showMonths - 1) &&
2161 self.config.mode !== "range";
2162 self.selectedDateElem = target;
2163 if (self.config.mode === "single")
2164 self.selectedDates = [selectedDate];
2165 else if (self.config.mode === "multiple") {
2166 var selectedIndex = isDateSelected(selectedDate);
2167 if (selectedIndex)
2168 self.selectedDates.splice(parseInt(selectedIndex), 1);
2169 else
2170 self.selectedDates.push(selectedDate);
2171 }
2172 else if (self.config.mode === "range") {
2173 if (self.selectedDates.length === 2) {
2174 self.clear(false, false);
2175 }
2176 self.latestSelectedDateObj = selectedDate;
2177 self.selectedDates.push(selectedDate);
2178 // unless selecting same date twice, sort ascendingly
2179 if (compareDates(selectedDate, self.selectedDates[0], true) !== 0)
2180 self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });
2181 }
2182 setHoursFromInputs();
2183 if (shouldChangeMonth) {
2184 var isNewYear = self.currentYear !== selectedDate.getFullYear();
2185 self.currentYear = selectedDate.getFullYear();
2186 self.currentMonth = selectedDate.getMonth();
2187 if (isNewYear) {
2188 triggerEvent("onYearChange");
2189 buildMonthSwitch();
2190 }
2191 triggerEvent("onMonthChange");
2192 }
2193 updateNavigationCurrentMonth();
2194 buildDays();
2195 updateValue();
2196 // maintain focus
2197 if (!shouldChangeMonth &&
2198 self.config.mode !== "range" &&
2199 self.config.showMonths === 1)
2200 focusOnDayElem(target);
2201 else if (self.selectedDateElem !== undefined &&
2202 self.hourElement === undefined) {
2203 self.selectedDateElem && self.selectedDateElem.focus();
2204 }
2205 if (self.hourElement !== undefined)
2206 self.hourElement !== undefined && self.hourElement.focus();
2207 if (self.config.closeOnSelect) {
2208 var single = self.config.mode === "single" && !self.config.enableTime;
2209 var range = self.config.mode === "range" &&
2210 self.selectedDates.length === 2 &&
2211 !self.config.enableTime;
2212 if (single || range) {
2213 focusAndClose();
2214 }
2215 }
2216 triggerChange();
2217 }
2218 var CALLBACKS = {
2219 locale: [setupLocale, updateWeekdays],
2220 showMonths: [buildMonths, setCalendarWidth, buildWeekdays],
2221 minDate: [jumpToDate],
2222 maxDate: [jumpToDate],
2223 };
2224 function set(option, value) {
2225 if (option !== null && typeof option === "object") {
2226 Object.assign(self.config, option);
2227 for (var key in option) {
2228 if (CALLBACKS[key] !== undefined)
2229 CALLBACKS[key].forEach(function (x) { return x(); });
2230 }
2231 }
2232 else {
2233 self.config[option] = value;
2234 if (CALLBACKS[option] !== undefined)
2235 CALLBACKS[option].forEach(function (x) { return x(); });
2236 else if (HOOKS.indexOf(option) > -1)
2237 self.config[option] = arrayify(value);
2238 }
2239 self.redraw();
2240 updateValue(true);
2241 }
2242 function setSelectedDate(inputDate, format) {
2243 var dates = [];
2244 if (inputDate instanceof Array)
2245 dates = inputDate.map(function (d) { return self.parseDate(d, format); });
2246 else if (inputDate instanceof Date || typeof inputDate === "number")
2247 dates = [self.parseDate(inputDate, format)];
2248 else if (typeof inputDate === "string") {
2249 switch (self.config.mode) {
2250 case "single":
2251 case "time":
2252 dates = [self.parseDate(inputDate, format)];
2253 break;
2254 case "multiple":
2255 dates = inputDate
2256 .split(self.config.conjunction)
2257 .map(function (date) { return self.parseDate(date, format); });
2258 break;
2259 case "range":
2260 dates = inputDate
2261 .split(self.l10n.rangeSeparator)
2262 .map(function (date) { return self.parseDate(date, format); });
2263 break;
2264 }
2265 }
2266 else
2267 self.config.errorHandler(new Error("Invalid date supplied: " + JSON.stringify(inputDate)));
2268 self.selectedDates = (self.config.allowInvalidPreload
2269 ? dates
2270 : dates.filter(function (d) { return d instanceof Date && isEnabled(d, false); }));
2271 if (self.config.mode === "range")
2272 self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });
2273 }
2274 function setDate(date, triggerChange, format) {
2275 if (triggerChange === void 0) { triggerChange = false; }
2276 if (format === void 0) { format = self.config.dateFormat; }
2277 if ((date !== 0 && !date) || (date instanceof Array && date.length === 0))
2278 return self.clear(triggerChange);
2279 setSelectedDate(date, format);
2280 self.latestSelectedDateObj =
2281 self.selectedDates[self.selectedDates.length - 1];
2282 self.redraw();
2283 jumpToDate(undefined, triggerChange);
2284 setHoursFromDate();
2285 if (self.selectedDates.length === 0) {
2286 self.clear(false);
2287 }
2288 updateValue(triggerChange);
2289 if (triggerChange)
2290 triggerEvent("onChange");
2291 }
2292 function parseDateRules(arr) {
2293 return arr
2294 .slice()
2295 .map(function (rule) {
2296 if (typeof rule === "string" ||
2297 typeof rule === "number" ||
2298 rule instanceof Date) {
2299 return self.parseDate(rule, undefined, true);
2300 }
2301 else if (rule &&
2302 typeof rule === "object" &&
2303 rule.from &&
2304 rule.to)
2305 return {
2306 from: self.parseDate(rule.from, undefined),
2307 to: self.parseDate(rule.to, undefined),
2308 };
2309 return rule;
2310 })
2311 .filter(function (x) { return x; }); // remove falsy values
2312 }
2313 function setupDates() {
2314 self.selectedDates = [];
2315 self.now = self.parseDate(self.config.now) || new Date();
2316 // Workaround IE11 setting placeholder as the input's value
2317 var preloadedDate = self.config.defaultDate ||
2318 ((self.input.nodeName === "INPUT" ||
2319 self.input.nodeName === "TEXTAREA") &&
2320 self.input.placeholder &&
2321 self.input.value === self.input.placeholder
2322 ? null
2323 : self.input.value);
2324 if (preloadedDate)
2325 setSelectedDate(preloadedDate, self.config.dateFormat);
2326 self._initialDate =
2327 self.selectedDates.length > 0
2328 ? self.selectedDates[0]
2329 : self.config.minDate &&
2330 self.config.minDate.getTime() > self.now.getTime()
2331 ? self.config.minDate
2332 : self.config.maxDate &&
2333 self.config.maxDate.getTime() < self.now.getTime()
2334 ? self.config.maxDate
2335 : self.now;
2336 self.currentYear = self._initialDate.getFullYear();
2337 self.currentMonth = self._initialDate.getMonth();
2338 if (self.selectedDates.length > 0)
2339 self.latestSelectedDateObj = self.selectedDates[0];
2340 if (self.config.minTime !== undefined)
2341 self.config.minTime = self.parseDate(self.config.minTime, "H:i");
2342 if (self.config.maxTime !== undefined)
2343 self.config.maxTime = self.parseDate(self.config.maxTime, "H:i");
2344 self.minDateHasTime =
2345 !!self.config.minDate &&
2346 (self.config.minDate.getHours() > 0 ||
2347 self.config.minDate.getMinutes() > 0 ||
2348 self.config.minDate.getSeconds() > 0);
2349 self.maxDateHasTime =
2350 !!self.config.maxDate &&
2351 (self.config.maxDate.getHours() > 0 ||
2352 self.config.maxDate.getMinutes() > 0 ||
2353 self.config.maxDate.getSeconds() > 0);
2354 }
2355 function setupInputs() {
2356 self.input = getInputElem();
2357 /* istanbul ignore next */
2358 if (!self.input) {
2359 self.config.errorHandler(new Error("Invalid input element specified"));
2360 return;
2361 }
2362 // hack: store previous type to restore it after destroy()
2363 self.input._type = self.input.type;
2364 self.input.type = "text";
2365 self.input.classList.add("flatpickr-input");
2366 self._input = self.input;
2367 if (self.config.altInput) {
2368 // replicate self.element
2369 self.altInput = createElement(self.input.nodeName, self.config.altInputClass);
2370 self._input = self.altInput;
2371 self.altInput.placeholder = self.input.placeholder;
2372 self.altInput.disabled = self.input.disabled;
2373 self.altInput.required = self.input.required;
2374 self.altInput.tabIndex = self.input.tabIndex;
2375 self.altInput.type = "text";
2376 self.input.setAttribute("type", "hidden");
2377 if (!self.config.static && self.input.parentNode)
2378 self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
2379 }
2380 if (!self.config.allowInput)
2381 self._input.setAttribute("readonly", "readonly");
2382 self._positionElement = self.config.positionElement || self._input;
2383 }
2384 function setupMobile() {
2385 var inputType = self.config.enableTime
2386 ? self.config.noCalendar
2387 ? "time"
2388 : "datetime-local"
2389 : "date";
2390 self.mobileInput = createElement("input", self.input.className + " flatpickr-mobile");
2391 self.mobileInput.tabIndex = 1;
2392 self.mobileInput.type = inputType;
2393 self.mobileInput.disabled = self.input.disabled;
2394 self.mobileInput.required = self.input.required;
2395 self.mobileInput.placeholder = self.input.placeholder;
2396 self.mobileFormatStr =
2397 inputType === "datetime-local"
2398 ? "Y-m-d\\TH:i:S"
2399 : inputType === "date"
2400 ? "Y-m-d"
2401 : "H:i:S";
2402 if (self.selectedDates.length > 0) {
2403 self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr);
2404 }
2405 if (self.config.minDate)
2406 self.mobileInput.min = self.formatDate(self.config.minDate, "Y-m-d");
2407 if (self.config.maxDate)
2408 self.mobileInput.max = self.formatDate(self.config.maxDate, "Y-m-d");
2409 if (self.input.getAttribute("step"))
2410 self.mobileInput.step = String(self.input.getAttribute("step"));
2411 self.input.type = "hidden";
2412 if (self.altInput !== undefined)
2413 self.altInput.type = "hidden";
2414 try {
2415 if (self.input.parentNode)
2416 self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);
2417 }
2418 catch (_a) { }
2419 bind(self.mobileInput, "change", function (e) {
2420 self.setDate(getEventTarget(e).value, false, self.mobileFormatStr);
2421 triggerEvent("onChange");
2422 triggerEvent("onClose");
2423 });
2424 }
2425 function toggle(e) {
2426 if (self.isOpen === true)
2427 return self.close();
2428 self.open(e);
2429 }
2430 function triggerEvent(event, data) {
2431 // If the instance has been destroyed already, all hooks have been removed
2432 if (self.config === undefined)
2433 return;
2434 var hooks = self.config[event];
2435 if (hooks !== undefined && hooks.length > 0) {
2436 for (var i = 0; hooks[i] && i < hooks.length; i++)
2437 hooks[i](self.selectedDates, self.input.value, self, data);
2438 }
2439 if (event === "onChange") {
2440 self.input.dispatchEvent(createEvent("change"));
2441 // many front-end frameworks bind to the input event
2442 self.input.dispatchEvent(createEvent("input"));
2443 }
2444 }
2445 function createEvent(name) {
2446 var e = document.createEvent("Event");
2447 e.initEvent(name, true, true);
2448 return e;
2449 }
2450 function isDateSelected(date) {
2451 for (var i = 0; i < self.selectedDates.length; i++) {
2452 if (compareDates(self.selectedDates[i], date) === 0)
2453 return "" + i;
2454 }
2455 return false;
2456 }
2457 function isDateInRange(date) {
2458 if (self.config.mode !== "range" || self.selectedDates.length < 2)
2459 return false;
2460 return (compareDates(date, self.selectedDates[0]) >= 0 &&
2461 compareDates(date, self.selectedDates[1]) <= 0);
2462 }
2463 function updateNavigationCurrentMonth() {
2464 if (self.config.noCalendar || self.isMobile || !self.monthNav)
2465 return;
2466 self.yearElements.forEach(function (yearElement, i) {
2467 var d = new Date(self.currentYear, self.currentMonth, 1);
2468 d.setMonth(self.currentMonth + i);
2469 if (self.config.showMonths > 1 ||
2470 self.config.monthSelectorType === "static") {
2471 self.monthElements[i].textContent =
2472 monthToStr(d.getMonth(), self.config.shorthandCurrentMonth, self.l10n) + " ";
2473 }
2474 else {
2475 self.monthsDropdownContainer.value = d.getMonth().toString();
2476 }
2477 yearElement.value = d.getFullYear().toString();
2478 });
2479 self._hidePrevMonthArrow =
2480 self.config.minDate !== undefined &&
2481 (self.currentYear === self.config.minDate.getFullYear()
2482 ? self.currentMonth <= self.config.minDate.getMonth()
2483 : self.currentYear < self.config.minDate.getFullYear());
2484 self._hideNextMonthArrow =
2485 self.config.maxDate !== undefined &&
2486 (self.currentYear === self.config.maxDate.getFullYear()
2487 ? self.currentMonth + 1 > self.config.maxDate.getMonth()
2488 : self.currentYear > self.config.maxDate.getFullYear());
2489 }
2490 function getDateStr(format) {
2491 return self.selectedDates
2492 .map(function (dObj) { return self.formatDate(dObj, format); })
2493 .filter(function (d, i, arr) {
2494 return self.config.mode !== "range" ||
2495 self.config.enableTime ||
2496 arr.indexOf(d) === i;
2497 })
2498 .join(self.config.mode !== "range"
2499 ? self.config.conjunction
2500 : self.l10n.rangeSeparator);
2501 }
2502 /**
2503 * Updates the values of inputs associated with the calendar
2504 */
2505 function updateValue(triggerChange) {
2506 if (triggerChange === void 0) { triggerChange = true; }
2507 if (self.mobileInput !== undefined && self.mobileFormatStr) {
2508 self.mobileInput.value =
2509 self.latestSelectedDateObj !== undefined
2510 ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr)
2511 : "";
2512 }
2513 self.input.value = getDateStr(self.config.dateFormat);
2514 if (self.altInput !== undefined) {
2515 self.altInput.value = getDateStr(self.config.altFormat);
2516 }
2517 if (triggerChange !== false)
2518 triggerEvent("onValueUpdate");
2519 }
2520 function onMonthNavClick(e) {
2521 var eventTarget = getEventTarget(e);
2522 var isPrevMonth = self.prevMonthNav.contains(eventTarget);
2523 var isNextMonth = self.nextMonthNav.contains(eventTarget);
2524 if (isPrevMonth || isNextMonth) {
2525 changeMonth(isPrevMonth ? -1 : 1);
2526 }
2527 else if (self.yearElements.indexOf(eventTarget) >= 0) {
2528 eventTarget.select();
2529 }
2530 else if (eventTarget.classList.contains("arrowUp")) {
2531 self.changeYear(self.currentYear + 1);
2532 }
2533 else if (eventTarget.classList.contains("arrowDown")) {
2534 self.changeYear(self.currentYear - 1);
2535 }
2536 }
2537 function timeWrapper(e) {
2538 e.preventDefault();
2539 var isKeyDown = e.type === "keydown", eventTarget = getEventTarget(e), input = eventTarget;
2540 if (self.amPM !== undefined && eventTarget === self.amPM) {
2541 self.amPM.textContent =
2542 self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];
2543 }
2544 var min = parseFloat(input.getAttribute("min")), max = parseFloat(input.getAttribute("max")), step = parseFloat(input.getAttribute("step")), curValue = parseInt(input.value, 10), delta = e.delta ||
2545 (isKeyDown ? (e.which === 38 ? 1 : -1) : 0);
2546 var newValue = curValue + step * delta;
2547 if (typeof input.value !== "undefined" && input.value.length === 2) {
2548 var isHourElem = input === self.hourElement, isMinuteElem = input === self.minuteElement;
2549 if (newValue < min) {
2550 newValue =
2551 max +
2552 newValue +
2553 int(!isHourElem) +
2554 (int(isHourElem) && int(!self.amPM));
2555 if (isMinuteElem)
2556 incrementNumInput(undefined, -1, self.hourElement);
2557 }
2558 else if (newValue > max) {
2559 newValue =
2560 input === self.hourElement ? newValue - max - int(!self.amPM) : min;
2561 if (isMinuteElem)
2562 incrementNumInput(undefined, 1, self.hourElement);
2563 }
2564 if (self.amPM &&
2565 isHourElem &&
2566 (step === 1
2567 ? newValue + curValue === 23
2568 : Math.abs(newValue - curValue) > step)) {
2569 self.amPM.textContent =
2570 self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];
2571 }
2572 input.value = pad(newValue);
2573 }
2574 }
2575 init();
2576 return self;
2577 }
2578 /* istanbul ignore next */
2579 function _flatpickr(nodeList, config) {
2580 // static list
2581 var nodes = Array.prototype.slice
2582 .call(nodeList)
2583 .filter(function (x) { return x instanceof HTMLElement; });
2584 var instances = [];
2585 for (var i = 0; i < nodes.length; i++) {
2586 var node = nodes[i];
2587 try {
2588 if (node.getAttribute("data-fp-omit") !== null)
2589 continue;
2590 if (node._flatpickr !== undefined) {
2591 node._flatpickr.destroy();
2592 node._flatpickr = undefined;
2593 }
2594 node._flatpickr = FlatpickrInstance(node, config || {});
2595 instances.push(node._flatpickr);
2596 }
2597 catch (e) {
2598 console.error(e);
2599 }
2600 }
2601 return instances.length === 1 ? instances[0] : instances;
2602 }
2603 /* istanbul ignore next */
2604 if (typeof HTMLElement !== "undefined" &&
2605 typeof HTMLCollection !== "undefined" &&
2606 typeof NodeList !== "undefined") {
2607 // browser env
2608 HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {
2609 return _flatpickr(this, config);
2610 };
2611 HTMLElement.prototype.flatpickr = function (config) {
2612 return _flatpickr([this], config);
2613 };
2614 }
2615 /* istanbul ignore next */
2616 var flatpickr = function (selector, config) {
2617 if (typeof selector === "string") {
2618 return _flatpickr(window.document.querySelectorAll(selector), config);
2619 }
2620 else if (selector instanceof Node) {
2621 return _flatpickr([selector], config);
2622 }
2623 else {
2624 return _flatpickr(selector, config);
2625 }
2626 };
2627 /* istanbul ignore next */
2628 flatpickr.defaultConfig = {};
2629 flatpickr.l10ns = {
2630 en: __assign({}, english),
2631 default: __assign({}, english),
2632 };
2633 flatpickr.localize = function (l10n) {
2634 flatpickr.l10ns.default = __assign(__assign({}, flatpickr.l10ns.default), l10n);
2635 };
2636 flatpickr.setDefaults = function (config) {
2637 flatpickr.defaultConfig = __assign(__assign({}, flatpickr.defaultConfig), config);
2638 };
2639 flatpickr.parseDate = createDateParser({});
2640 flatpickr.formatDate = createDateFormatter({});
2641 flatpickr.compareDates = compareDates;
2642 /* istanbul ignore next */
2643 if (typeof jQuery !== "undefined" && typeof jQuery.fn !== "undefined") {
2644 jQuery.fn.flatpickr = function (config) {
2645 return _flatpickr(this, config);
2646 };
2647 }
2648 // eslint-disable-next-line @typescript-eslint/camelcase
2649 Date.prototype.fp_incr = function (days) {
2650 return new Date(this.getFullYear(), this.getMonth(), this.getDate() + (typeof days === "string" ? parseInt(days, 10) : days));
2651 };
2652 if (typeof window !== "undefined") {
2653 window.flatpickr = flatpickr;
2654 }
2655
2656 return flatpickr;
2657
2658})));