PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.4
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.4
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / assets / libs / flatpickr / flatpickr.js

flatpickr.js in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.4, at assets/libs/flatpickr/flatpickr.js

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