flatpickr.js 119 KB

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