UNPKG

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