flatpickr_rails 0.0.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b8e2453da60064417141c7f5d3b61669c73d3027
4
- data.tar.gz: 2eb0b4f5699ae4f0101532dca9b9e339969f9fbb
3
+ metadata.gz: 50f7b3b2de24cbdca4152f52970c2a3fb94d304e
4
+ data.tar.gz: d6e87b110359eb61ea4605964db9c28215231a77
5
5
  SHA512:
6
- metadata.gz: bb607125c876602b4546b54db379081fac4a45ece9a38a545df67bd77d8288e9efd2740bc251bca9e3e6b5fd9189fcfc746cab1c04dae99c276adc3542020ee5
7
- data.tar.gz: a2b1250deb6cabd1154a34974e442be9bb1866ad3eaf14a5d735dfeea1bdaf4e385bfd43c219eccba02b1a4495317fa6a6678067a2306ec556261ddb1be9a338
6
+ metadata.gz: 17aac1145148b860f308425813ce64cba79fc4a04958580b7eea1a542711170cf70faa91ac5536d286a4c79f6ae9fb3dfd39c4804abd41c4fa3851259fa3f436
7
+ data.tar.gz: 932fb54899722e893911e91098db410e37412ff1b345d039043f8a5d89564f37481d39df5f73be57cf5d89c42d69b74ffcd5c5718518acbb32a3ec05db60e923
@@ -1,3 +1,3 @@
1
1
  module FlatpickrRails
2
- VERSION = '0.0.3'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -2,7 +2,7 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument
2
2
 
3
3
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4
4
 
5
- /*! flatpickr v2.1.1, @license MIT */
5
+ /*! flatpickr v2.2.3, @license MIT */
6
6
  function Flatpickr(element, config) {
7
7
  var self = this;
8
8
 
@@ -37,17 +37,34 @@ function Flatpickr(element, config) {
37
37
  self.setDate = setDate;
38
38
  self.toggle = toggle;
39
39
 
40
- self.isMobile = !self.config.disableMobile && self.config.mode === "single" && !self.config.disable.length && !self.config.enable.length && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
40
+ self.isMobile = !self.config.disableMobile && !self.config.inline && self.config.mode === "single" && !self.config.disable.length && !self.config.enable.length && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
41
41
 
42
42
  if (!self.isMobile) build();
43
43
 
44
44
  bind();
45
45
 
46
+ self.minDateHasTime = self.config.minDate && (self.config.minDate.getHours() || self.config.minDate.getMinutes() || self.config.minDate.getSeconds());
47
+
48
+ self.maxDateHasTime = self.config.maxDate && (self.config.maxDate.getHours() || self.config.maxDate.getMinutes() || self.config.maxDate.getSeconds());
49
+
50
+ if (!self.isMobile) {
51
+ Object.defineProperty(self, "dateIsPicked", {
52
+ set: function set(bool) {
53
+ if (bool) return self.calendarContainer.classList.add("dateIsPicked");
54
+ self.calendarContainer.classList.remove("dateIsPicked");
55
+ }
56
+ });
57
+ }
58
+
59
+ self.dateIsPicked = self.selectedDates.length > 0 || self.config.noCalendar;
60
+
46
61
  if (self.selectedDates.length) {
47
62
  if (self.config.enableTime) setHoursFromDate();
48
63
  updateValue();
49
64
  }
50
65
 
66
+ if (self.config.weekNumbers) self.calendarContainer.style.width = self.days.offsetWidth + self.weekWrapper.offsetWidth + 2 + "px";
67
+
51
68
  triggerEvent("Ready");
52
69
  }
53
70
 
@@ -68,22 +85,34 @@ function Flatpickr(element, config) {
68
85
  if (!self.config.enableTime) return;
69
86
 
70
87
  var hours = parseInt(self.hourElement.value, 10) || 0,
71
- minutes = (60 + (parseInt(self.minuteElement.value, 10) || 0)) % 60,
72
- seconds = self.config.enableSeconds ? (60 + parseInt(self.secondElement.value, 10) || 0) % 60 : 0;
88
+ minutes = parseInt(self.minuteElement.value, 10) || 0,
89
+ seconds = self.config.enableSeconds ? parseInt(self.secondElement.value, 10) || 0 : 0;
73
90
 
74
91
  if (self.amPM) hours = hours % 12 + 12 * (self.amPM.innerHTML === "PM");
75
92
 
93
+ if (self.minDateHasTime && compareDates(latestSelectedDateObj(), self.config.minDate) === 0) {
94
+ hours = Math.max(hours, self.config.minDate.getHours());
95
+ if (hours === self.config.minDate.getHours()) minutes = Math.max(minutes, self.config.minDate.getMinutes());
96
+ } else if (self.maxDateHasTime && compareDates(latestSelectedDateObj(), self.config.maxDate) === 0) {
97
+ hours = Math.min(hours, self.config.maxDate.getHours());
98
+ if (hours === self.config.maxDate.getHours()) minutes = Math.min(minutes, self.config.maxDate.getMinutes());
99
+ }
100
+
76
101
  setHours(hours, minutes, seconds);
77
102
  }
78
103
 
79
104
  function setHoursFromDate(dateObj) {
80
- setHours((dateObj || latestSelectedDateObj()).getHours(), (dateObj || latestSelectedDateObj()).getMinutes(), (dateObj || latestSelectedDateObj()).getSeconds());
105
+ var date = dateObj || latestSelectedDateObj();
106
+
107
+ if (date) setHours(date.getHours(), date.getMinutes(), date.getSeconds());
81
108
  }
82
109
 
83
110
  function setHours(hours, minutes, seconds) {
84
- if (self.selectedDates.length) self.selectedDates[self.selectedDates.length - 1].setHours(hours % 24, minutes, seconds || 0, 0);
111
+ if (self.selectedDates.length) {
112
+ self.selectedDates[self.selectedDates.length - 1].setHours(hours % 24, minutes, seconds || 0, 0);
113
+ }
85
114
 
86
- if (!self.config.enableTime) return;
115
+ if (!self.config.enableTime || self.isMobile) return;
87
116
 
88
117
  self.hourElement.value = self.pad(!self.config.time_24hr ? (12 + hours) % 12 + 12 * (hours % 12 === 0) : hours);
89
118
 
@@ -112,7 +141,7 @@ function Flatpickr(element, config) {
112
141
 
113
142
  if (self.isMobile) return setupMobile();
114
143
 
115
- self.debouncedResize = debounce(onResize, 100);
144
+ self.debouncedResize = debounce(onResize, 50);
116
145
  self.triggerChange = function () {
117
146
  return triggerEvent("Change");
118
147
  };
@@ -123,7 +152,9 @@ function Flatpickr(element, config) {
123
152
  document.addEventListener("keydown", onKeyDown);
124
153
  window.addEventListener("resize", self.debouncedResize);
125
154
 
126
- document.addEventListener("click", documentClick);
155
+ var clickEvent = typeof window.ontouchstart !== "undefined" ? "touchstart" : "click";
156
+
157
+ document.addEventListener(clickEvent, documentClick);
127
158
  document.addEventListener("blur", documentClick);
128
159
 
129
160
  if (self.config.clickOpens) (self.altInput || self.input).addEventListener("focus", open);
@@ -199,6 +230,39 @@ function Flatpickr(element, config) {
199
230
  self.redraw();
200
231
  }
201
232
 
233
+ function incrementNumInput(e, delta) {
234
+ var input = e.target.parentNode.childNodes[0];
235
+ input.value = parseInt(input.value, 10) + delta * (input.step || 1);
236
+
237
+ try {
238
+ input.dispatchEvent(new Event("input", { "bubbles": true }));
239
+ } catch (e) {
240
+ var ev = document.createEvent("CustomEvent");
241
+ ev.initCustomEvent("input", true, true, {});
242
+ input.dispatchEvent(ev);
243
+ }
244
+ }
245
+
246
+ function createNumberInput(inputClassName) {
247
+ var wrapper = createElement("div", "numInputWrapper"),
248
+ numInput = createElement("input", "numInput " + inputClassName),
249
+ arrowUp = createElement("span", "arrowUp"),
250
+ arrowDown = createElement("span", "arrowDown");
251
+
252
+ numInput.type = "text";
253
+ wrapper.appendChild(numInput);
254
+ wrapper.appendChild(arrowUp);
255
+ wrapper.appendChild(arrowDown);
256
+
257
+ arrowUp.addEventListener("click", function (e) {
258
+ return incrementNumInput(e, 1);
259
+ });
260
+ arrowDown.addEventListener("click", function (e) {
261
+ return incrementNumInput(e, -1);
262
+ });
263
+ return wrapper;
264
+ }
265
+
202
266
  function build() {
203
267
  var fragment = document.createDocumentFragment();
204
268
  self.calendarContainer = createElement("div", "flatpickr-calendar");
@@ -231,6 +295,44 @@ function Flatpickr(element, config) {
231
295
  } else document.body.appendChild(self.calendarContainer);
232
296
  }
233
297
 
298
+ function createDay(className, date, dayNumber) {
299
+ var dateIsEnabled = isEnabled(date),
300
+ dayElement = createElement("span", "flatpickr-day " + className, date.getDate());
301
+
302
+ dayElement.dateObj = date;
303
+
304
+ if (compareDates(date, self.now) === 0) dayElement.classList.add("today");
305
+
306
+ if (dateIsEnabled) {
307
+ dayElement.tabIndex = 0;
308
+
309
+ if (isDateSelected(date)) {
310
+ dayElement.classList.add("selected");
311
+
312
+ if (self.config.mode === "range") {
313
+ dayElement.classList.add(compareDates(date, self.selectedDates[0]) === 0 ? "startRange" : "endRange");
314
+ } else self.selectedDateElem = dayElement;
315
+ }
316
+ } else {
317
+ dayElement.classList.add("disabled");
318
+ if (self.selectedDates[0] && date > self.minRangeDate && date < self.selectedDates[0]) self.minRangeDate = date;else if (self.selectedDates[0] && date < self.maxRangeDate && date > self.selectedDates[0]) self.maxRangeDate = date;
319
+ }
320
+
321
+ if (self.config.mode === "range") {
322
+ if (isDateInRange(date) && !isDateSelected(date)) dayElement.classList.add("inRange");
323
+
324
+ if (self.selectedDates.length === 1 && (date < self.minRangeDate || date > self.maxRangeDate)) dayElement.classList.add("notAllowed");
325
+ }
326
+
327
+ if (self.config.weekNumbers && className !== "prevMonthDay" && dayNumber % 7 === 1) {
328
+ self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='disabled flatpickr-day'>" + self.config.getWeek(date) + "</span>");
329
+ }
330
+
331
+ triggerEvent("DayCreate", dayElement);
332
+
333
+ return dayElement;
334
+ }
335
+
234
336
  function buildDays() {
235
337
  if (!self.days) {
236
338
  self.days = createElement("div", "flatpickr-days");
@@ -244,14 +346,12 @@ function Flatpickr(element, config) {
244
346
  var daysInMonth = self.utils.getDaysinMonth(),
245
347
  days = document.createDocumentFragment();
246
348
 
247
- var dayNumber = self.prevMonthDays + 1 - self.firstOfMonth,
248
- currentDate = void 0,
249
- dateIsDisabled = void 0;
349
+ var dayNumber = self.prevMonthDays + 1 - self.firstOfMonth;
250
350
 
251
351
  if (self.config.weekNumbers) self.weekNumbers.innerHTML = "";
252
352
 
253
353
  if (self.config.mode === "range") {
254
- var dateLimits = self.config.enable.length || self.config.disable.length || self.config.mixDate || self.config.maxDate;
354
+ // const dateLimits = self.config.enable.length || self.config.disable.length || self.config.mixDate || self.config.maxDate;
255
355
  self.minRangeDate = new Date(self.currentYear, self.currentMonth - 1, dayNumber);
256
356
  self.maxRangeDate = new Date(self.currentYear, self.currentMonth + 1, (42 - self.firstOfMonth) % daysInMonth);
257
357
  }
@@ -260,68 +360,19 @@ function Flatpickr(element, config) {
260
360
 
261
361
  // prepend days from the ending of previous month
262
362
  for (var i = 0; dayNumber <= self.prevMonthDays; i++, dayNumber++) {
263
- var curDate = new Date(self.currentYear, self.currentMonth - 1, dayNumber, 0, 0, 0, 0, 0),
264
- dateIsEnabled = isEnabled(curDate),
265
- dayElement = createElement("span", "flatpickr-day prevMonthDay" + (!dateIsEnabled ? " disabled" : "") + (isDateInRange(curDate) ? " inRange" : "") + (self.selectedDates.length === 1 && (curDate < self.minRangeDate || curDate > self.maxRangeDate) ? " notAllowed" : "") + (isDateSelected(curDate) !== false ? " selected" : ""), dayNumber);
266
-
267
- dayElement.dateObj = curDate;
268
-
269
- if (dateIsEnabled) dayElement.tabIndex = 0;else if (self.selectedDates[0] && curDate > self.minRangeDate && curDate < self.selectedDates[0]) self.minRangeDate = curDate;else if (self.selectedDates[0] && curDate < self.maxRangeDate && curDate > self.selectedDates[0]) self.maxRangeDate = curDate;
270
-
271
- triggerEvent("DayCreate", dayElement);
272
- days.appendChild(dayElement);
363
+ days.appendChild(createDay("prevMonthDay", new Date(self.currentYear, self.currentMonth - 1, dayNumber), dayNumber));
273
364
  }
274
365
 
275
366
  // Start at 1 since there is no 0th day
276
367
  for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++) {
277
- currentDate = new Date(self.currentYear, self.currentMonth, dayNumber, 0, 0, 0, 0, 0);
278
-
279
- if (self.config.weekNumbers && dayNumber % 7 === 1) {
280
- self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='disabled flatpickr-day'>" + self.config.getWeek(currentDate) + "</span>");
281
- }
282
-
283
- dateIsDisabled = !isEnabled(currentDate);
284
-
285
- var _dayElement = createElement("span", dateIsDisabled ? "flatpickr-day disabled" : "flatpickr-day" + (isDateInRange(currentDate) ? " inRange" : "") + (self.selectedDates.length === 1 && (currentDate < self.minRangeDate || currentDate > self.maxRangeDate) ? " notAllowed" : ""), dayNumber);
286
-
287
- _dayElement.dateObj = currentDate;
288
-
289
- if (equalDates(currentDate, self.now)) _dayElement.classList.add("today");
290
-
291
- if (!dateIsDisabled) {
292
- _dayElement.tabIndex = 0;
293
-
294
- if (isDateSelected(currentDate)) {
295
- _dayElement.classList.add("selected");
296
- self.selectedDateElem = _dayElement;
297
-
298
- if (self.config.mode === "range") {
299
- _dayElement.className += equalDates(currentDate, self.selectedDates[0]) ? " startRange" : self.selectedDates.length > 1 ? " endRange" : "";
300
- }
301
- }
302
- } else if (self.selectedDates[0] && currentDate > self.minRangeDate && currentDate < self.selectedDates[0]) self.minRangeDate = currentDate;else if (self.selectedDates[0] && currentDate < self.maxRangeDate && currentDate > self.selectedDates[0]) self.maxRangeDate = currentDate;
303
-
304
- triggerEvent("DayCreate", _dayElement);
305
- days.appendChild(_dayElement);
368
+ days.appendChild(createDay("", new Date(self.currentYear, self.currentMonth, dayNumber), dayNumber));
306
369
  }
307
370
 
308
371
  // append days from the next month
309
372
  for (var dayNum = daysInMonth + 1; dayNum <= 42 - self.firstOfMonth; dayNum++) {
310
- var _curDate = new Date(self.currentYear, self.currentMonth + 1, dayNum % daysInMonth, 0, 0, 0, 0, 0),
311
- _dateIsEnabled = isEnabled(_curDate),
312
- _dayElement2 = createElement("span", "flatpickr-day nextMonthDay" + (!_dateIsEnabled ? " disabled" : "") + (isDateInRange(_curDate) ? " inRange" : "") + (self.selectedDates.length === 1 && (_curDate < self.minRangeDate || _curDate > self.maxRangeDate) ? " notAllowed" : "") + (isDateSelected(_curDate) !== false ? " selected" : ""), dayNum % daysInMonth);
313
-
314
- _dayElement2.dateObj = _curDate;
315
-
316
- if (self.config.weekNumbers && dayNum % 7 === 1) {
317
- self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='disabled flatpickr-day'>" + self.config.getWeek(_curDate) + "</span>");
318
- }
319
-
320
- if (_dateIsEnabled) _dayElement2.tabIndex = 0;else if (self.selectedDates[0] && _curDate > self.minRangeDate && _curDate < self.selectedDates[0]) self.minRangeDate = _curDate;else if (self.selectedDates[0] && _curDate < self.maxRangeDate && _curDate > self.selectedDates[0]) self.maxRangeDate = _curDate;
321
-
322
- triggerEvent("DayCreate", _dayElement2);
323
- days.appendChild(_dayElement2);
373
+ days.appendChild(createDay("nextMonthDay", new Date(self.currentYear, self.currentMonth + 1, dayNum % daysInMonth), dayNum));
324
374
  }
375
+
325
376
  self.days.appendChild(days);
326
377
  return self.days;
327
378
  }
@@ -335,8 +386,8 @@ function Flatpickr(element, config) {
335
386
 
336
387
  self.currentMonthElement = createElement("span", "cur-month");
337
388
 
338
- self.currentYearElement = createElement("input", "cur-year");
339
- self.currentYearElement.type = self.numInputType;
389
+ var yearInput = createNumberInput("cur-year");
390
+ self.currentYearElement = yearInput.childNodes[0];
340
391
  self.currentYearElement.title = self.l10n.scrollTitle;
341
392
 
342
393
  if (self.config.minDate) self.currentYearElement.min = self.config.minDate.getFullYear();
@@ -352,7 +403,7 @@ function Flatpickr(element, config) {
352
403
 
353
404
  self.navigationCurrentMonth = createElement("span", "flatpickr-current-month");
354
405
  self.navigationCurrentMonth.appendChild(self.currentMonthElement);
355
- self.navigationCurrentMonth.appendChild(self.currentYearElement);
406
+ self.navigationCurrentMonth.appendChild(yearInput);
356
407
 
357
408
  monthNavFragment.appendChild(self.prevMonthNav);
358
409
  monthNavFragment.appendChild(self.navigationCurrentMonth);
@@ -370,11 +421,13 @@ function Flatpickr(element, config) {
370
421
  self.timeContainer.tabIndex = -1;
371
422
  var separator = createElement("span", "flatpickr-time-separator", ":");
372
423
 
373
- self.hourElement = createElement("input", "flatpickr-hour");
374
- self.minuteElement = createElement("input", "flatpickr-minute");
424
+ var hourInput = createNumberInput("flatpickr-hour");
425
+ self.hourElement = hourInput.childNodes[0];
426
+
427
+ var minuteInput = createNumberInput("flatpickr-minute");
428
+ self.minuteElement = minuteInput.childNodes[0];
375
429
 
376
430
  self.hourElement.tabIndex = self.minuteElement.tabIndex = 0;
377
- self.hourElement.type = self.minuteElement.type = self.numInputType;
378
431
  self.hourElement.pattern = self.minuteElement.pattern = "\d*";
379
432
 
380
433
  self.hourElement.value = self.pad(latestSelectedDateObj() ? latestSelectedDateObj().getHours() : self.config.defaultHour);
@@ -384,23 +437,26 @@ function Flatpickr(element, config) {
384
437
  self.hourElement.step = self.config.hourIncrement;
385
438
  self.minuteElement.step = self.config.minuteIncrement;
386
439
 
387
- self.hourElement.min = -(self.config.time_24hr ? 1 : 0);
388
- self.hourElement.max = self.config.time_24hr ? 24 : 13;
440
+ self.hourElement.min = self.config.time_24hr ? 0 : 1;
441
+ self.hourElement.max = self.config.time_24hr ? 23 : 12;
389
442
 
390
- self.minuteElement.min = -self.minuteElement.step;
391
- self.minuteElement.max = 60;
443
+ self.minuteElement.min = 0;
444
+ self.minuteElement.max = 59;
392
445
 
393
446
  self.hourElement.title = self.minuteElement.title = self.l10n.scrollTitle;
394
447
 
395
- self.timeContainer.appendChild(self.hourElement);
448
+ self.timeContainer.appendChild(hourInput);
396
449
  self.timeContainer.appendChild(separator);
397
- self.timeContainer.appendChild(self.minuteElement);
450
+ self.timeContainer.appendChild(minuteInput);
451
+
452
+ if (self.config.time_24hr) self.timeContainer.classList.add("time24hr");
398
453
 
399
454
  if (self.config.enableSeconds) {
400
- self.timeContainer.classList.add("has-seconds");
455
+ self.timeContainer.classList.add("hasSeconds");
456
+
457
+ var secondInput = createNumberInput("flatpickr-second");
458
+ self.secondElement = secondInput.childNodes[0];
401
459
 
402
- self.secondElement = createElement("input", "flatpickr-second");
403
- self.secondElement.type = self.numInputType;
404
460
  self.secondElement.pattern = self.hourElement.pattern;
405
461
  self.secondElement.value = latestSelectedDateObj() ? self.pad(latestSelectedDateObj().getSeconds()) : "00";
406
462
 
@@ -409,7 +465,7 @@ function Flatpickr(element, config) {
409
465
  self.secondElement.max = self.minuteElement.max;
410
466
 
411
467
  self.timeContainer.appendChild(createElement("span", "flatpickr-time-separator", ":"));
412
- self.timeContainer.appendChild(self.secondElement);
468
+ self.timeContainer.appendChild(secondInput);
413
469
  }
414
470
 
415
471
  if (!self.config.time_24hr) {
@@ -444,6 +500,7 @@ function Flatpickr(element, config) {
444
500
  self.weekWrapper.appendChild(createElement("span", "flatpickr-weekday", self.l10n.weekAbbreviation));
445
501
  self.weekNumbers = createElement("div", "flatpickr-weeks");
446
502
  self.weekWrapper.appendChild(self.weekNumbers);
503
+
447
504
  return self.weekWrapper;
448
505
  }
449
506
 
@@ -460,6 +517,8 @@ function Flatpickr(element, config) {
460
517
  }
461
518
 
462
519
  function clear() {
520
+ var triggerChangeEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
521
+
463
522
  self.input.value = "";
464
523
 
465
524
  if (self.altInput) self.altInput.value = "";
@@ -467,21 +526,29 @@ function Flatpickr(element, config) {
467
526
  if (self.mobileInput) self.mobileInput.value = "";
468
527
 
469
528
  self.selectedDates = [];
529
+ self.dateIsPicked = false;
470
530
 
471
- triggerEvent("Change");
531
+ self.redraw();
532
+
533
+ if (triggerChangeEvent !== false)
534
+ // triggerChangeEvent is true (default) or an Event
535
+ triggerEvent("Change");
472
536
  }
473
537
 
474
538
  function close() {
475
539
  self.isOpen = false;
476
- self.calendarContainer.classList.remove("open");
477
- (self.altInput || self.input).classList.remove("active");
540
+
541
+ if (!self.isMobile) {
542
+ self.calendarContainer.classList.remove("open");
543
+ (self.altInput || self.input).classList.remove("active");
544
+ }
478
545
 
479
546
  triggerEvent("Close");
480
547
  }
481
548
 
482
549
  function destroy(instance) {
483
550
  instance = instance || self;
484
- instance.clear();
551
+ instance.clear(false);
485
552
 
486
553
  document.removeEventListener("keydown", onKeyDown);
487
554
  window.removeEventListener("resize", instance.debouncedResize);
@@ -525,6 +592,8 @@ function Flatpickr(element, config) {
525
592
  }
526
593
 
527
594
  function formatDate(frmt, dateObj) {
595
+ if (self.config.formatDate) return self.config.formatDate(frmt, dateObj);
596
+
528
597
  var chars = frmt.split("");
529
598
  return chars.map(function (c, i) {
530
599
  return self.formats[c] && chars[i - 1] !== "\\" ? self.formats[c](dateObj) : c !== "\\" ? c : "";
@@ -539,7 +608,11 @@ function Flatpickr(element, config) {
539
608
  } else if (newYear && (!self.currentYearElement.min || newYear >= self.currentYearElement.min) && (!self.currentYearElement.max || newYear <= self.currentYearElement.max)) {
540
609
  self.currentYear = parseInt(newYear, 10) || self.currentYear;
541
610
 
542
- if (self.config.maxDate && self.currentYear === self.config.maxDate.getFullYear()) self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);else if (self.config.minDate && self.currentYear === self.config.minDate.getFullYear()) self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);
611
+ if (self.config.maxDate && self.currentYear === self.config.maxDate.getFullYear()) {
612
+ self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);
613
+ } else if (self.config.minDate && self.currentYear === self.config.minDate.getFullYear()) {
614
+ self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);
615
+ }
543
616
 
544
617
  self.redraw();
545
618
  triggerEvent("YearChange");
@@ -547,7 +620,7 @@ function Flatpickr(element, config) {
547
620
  }
548
621
 
549
622
  function isEnabled(dateToCheck) {
550
- if (self.config.minDate && dateToCheck < self.config.minDate || self.config.maxDate && dateToCheck > self.config.maxDate) return false;
623
+ if (self.config.minDate && compareDates(dateToCheck, self.config.minDate) < 0 || self.config.maxDate && compareDates(dateToCheck, self.config.maxDate) > 0) return false;
551
624
 
552
625
  if (!self.config.enable.length && !self.config.disable.length) return true;
553
626
 
@@ -621,6 +694,7 @@ function Flatpickr(element, config) {
621
694
  if (self.selectedDates.length !== 1 || !e.target.classList.contains("flatpickr-day")) return;
622
695
 
623
696
  var hoverDate = e.target.dateObj,
697
+ initialDate = parseDate(self.selectedDates[0], true),
624
698
  rangeStartDate = Math.min(hoverDate.getTime(), self.selectedDates[0].getTime()),
625
699
  rangeEndDate = Math.max(hoverDate.getTime(), self.selectedDates[0].getTime()),
626
700
  containsDisabled = false;
@@ -633,21 +707,35 @@ function Flatpickr(element, config) {
633
707
  }
634
708
 
635
709
  for (var timestamp = self.days.childNodes[0].dateObj.getTime(), i = 0; i < 42; i++, timestamp += self.utils.duration.DAY) {
636
- if (timestamp < self.minRangeDate.getTime() || timestamp > self.maxRangeDate.getTime()) {
710
+ var outOfRange = timestamp < self.minRangeDate.getTime() || timestamp > self.maxRangeDate.getTime();
711
+
712
+ if (outOfRange) {
637
713
  self.days.childNodes[i].classList.add("notAllowed");
638
- self.days.childNodes[i].classList.remove("inRange");
639
- } else if (!containsDisabled && timestamp > Math.max(self.minRangeDate.getTime(), rangeStartDate) && timestamp < Math.min(self.maxRangeDate.getTime(), rangeEndDate)) self.days.childNodes[i].classList.add("inRange");else self.days.childNodes[i].classList.remove("inRange");
714
+ self.days.childNodes[i].classList.remove("inRange", "startRange", "endRange");
715
+ continue;
716
+ } else if (containsDisabled && !outOfRange) continue;
717
+
718
+ self.days.childNodes[i].classList.remove("startRange", "inRange", "endRange", "notAllowed");
719
+
720
+ var minRangeDate = Math.max(self.minRangeDate.getTime(), rangeStartDate),
721
+ maxRangeDate = Math.min(self.maxRangeDate.getTime(), rangeEndDate);
722
+
723
+ e.target.classList.add(hoverDate < self.selectedDates[0] ? "startRange" : "endRange");
724
+
725
+ if (initialDate > hoverDate && timestamp === initialDate.getTime()) self.days.childNodes[i].classList.add("endRange");else if (initialDate < hoverDate && timestamp === initialDate.getTime()) self.days.childNodes[i].classList.add("startRange");else if (timestamp > minRangeDate && timestamp < maxRangeDate) self.days.childNodes[i].classList.add("inRange");
640
726
  }
641
727
  }
642
728
 
643
729
  function onResize() {
644
- if (self.isOpen && !self.config.inline && !self.config.static) positionCalendar();
730
+ if (self.isOpen && !self.config.static && !self.config.inline) positionCalendar();
645
731
  }
646
732
 
647
733
  function open(e) {
648
734
  if (self.isMobile) {
649
- e.preventDefault();
650
- e.target.blur();
735
+ if (e) {
736
+ e.preventDefault();
737
+ e.target.blur();
738
+ }
651
739
 
652
740
  setTimeout(function () {
653
741
  self.mobileInput.click();
@@ -659,7 +747,7 @@ function Flatpickr(element, config) {
659
747
 
660
748
  self.calendarContainer.classList.add("open");
661
749
 
662
- if (!self.config.static) positionCalendar();
750
+ if (!self.config.static && !self.config.inline) positionCalendar();
663
751
 
664
752
  self.isOpen = true;
665
753
 
@@ -682,14 +770,17 @@ function Flatpickr(element, config) {
682
770
  return this._minDate;
683
771
  },
684
772
  set: function set(date) {
685
- this._minDate = parseDate(date, true);
773
+ this._minDate = parseDate(date);
774
+
686
775
  if (self.days) redraw();
687
776
 
688
777
  if (!self.currentYearElement) return;
689
778
 
690
- if (date && this._minDate instanceof Date) self.currentYearElement.min = this._minDate.getFullYear();else {
691
- self.currentYearElement.removeAttribute("min");
692
- }
779
+ if (date && this._minDate instanceof Date) {
780
+ self.minDateHasTime = this._minDate.getHours() || this._minDate.getMinutes() || this._minDate.getSeconds();
781
+
782
+ self.currentYearElement.min = this._minDate.getFullYear();
783
+ } else self.currentYearElement.removeAttribute("min");
693
784
 
694
785
  self.currentYearElement.disabled = this._maxDate && this._minDate && this._maxDate.getFullYear() === this._minDate.getFullYear();
695
786
  }
@@ -701,12 +792,14 @@ function Flatpickr(element, config) {
701
792
  },
702
793
  set: function set(date) {
703
794
  this._maxDate = parseDate(date);
704
- this._maxDate instanceof Date && this._maxDate.setHours(23, 59, 59, 999);
705
795
  if (self.days) redraw();
706
796
 
707
797
  if (!self.currentYearElement) return;
708
798
 
709
- if (date && this._maxDate instanceof Date) self.currentYearElement.max = this._maxDate.getFullYear();else self.currentYearElement.removeAttribute("max");
799
+ if (date && this._maxDate instanceof Date) {
800
+ self.currentYearElement.max = this._maxDate.getFullYear();
801
+ self.maxDateHasTime = this._maxDate.getHours() || this._maxDate.getMinutes() || this._maxDate.getSeconds();
802
+ } else self.currentYearElement.removeAttribute("max");
710
803
 
711
804
  self.currentYearElement.disabled = this._maxDate && this._minDate && this._maxDate.getFullYear() === this._minDate.getFullYear();
712
805
  }
@@ -796,7 +889,7 @@ function Flatpickr(element, config) {
796
889
  self.calendarContainer.classList.add("arrowTop");
797
890
  }
798
891
 
799
- if (!self.config.inline && !self.config.static) {
892
+ if (!self.config.static && !self.config.inline) {
800
893
  self.calendarContainer.style.top = top + "px";
801
894
  self.calendarContainer.style.left = left + "px";
802
895
  }
@@ -842,11 +935,19 @@ function Flatpickr(element, config) {
842
935
  updateNavigationCurrentMonth();
843
936
  }
844
937
 
845
- updateValue();
846
938
  buildDays();
847
- triggerEvent("Change");
939
+
940
+ if (self.minDateHasTime && self.config.enableTime && compareDates(selectedDate, self.config.minDate) === 0) setHoursFromDate(self.config.minDate);
941
+
942
+ updateValue();
943
+
944
+ setTimeout(function () {
945
+ return self.dateIsPicked = true;
946
+ }, 50);
848
947
 
849
948
  if (self.config.mode === "range" && self.selectedDates.length === 1) onMouseOver(e);
949
+
950
+ triggerEvent("Change");
850
951
  }
851
952
 
852
953
  function set(option, value) {
@@ -859,7 +960,7 @@ function Flatpickr(element, config) {
859
960
  if (!date) return self.clear();
860
961
 
861
962
  self.selectedDates = (Array.isArray(date) ? date.map(parseDate) : [parseDate(date)]).filter(function (d) {
862
- return d instanceof Date;
963
+ return d instanceof Date && isEnabled(d);
863
964
  });
864
965
  self.redraw();
865
966
  jumpToDate();
@@ -867,6 +968,8 @@ function Flatpickr(element, config) {
867
968
  setHoursFromDate();
868
969
  updateValue();
869
970
 
971
+ self.dateIsPicked = self.selectedDates.length > 0;
972
+
870
973
  if (triggerChange) triggerEvent("Change");
871
974
  }
872
975
 
@@ -886,7 +989,7 @@ function Flatpickr(element, config) {
886
989
  break;
887
990
 
888
991
  case "range":
889
- self.selectedDates = inputDate.split(" to ").map(parseDate);
992
+ self.selectedDates = inputDate.split(self.l10n.rangeSeparator).map(parseDate);
890
993
  break;
891
994
 
892
995
  default:
@@ -913,7 +1016,7 @@ function Flatpickr(element, config) {
913
1016
  var month = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : self.currentMonth;
914
1017
  var yr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : self.currentYear;
915
1018
 
916
- if (month === 1 && yr % 4 === 0 && yr % 100 !== 0 || yr % 400 === 0) return 29;
1019
+ if (month === 1 && (yr % 4 === 0 && yr % 100 !== 0 || yr % 400 === 0)) return 29;
917
1020
  return self.l10n.daysInMonth[month];
918
1021
  },
919
1022
 
@@ -1109,7 +1212,7 @@ function Flatpickr(element, config) {
1109
1212
 
1110
1213
  function isDateSelected(date) {
1111
1214
  for (var i = 0; i < self.selectedDates.length; i++) {
1112
- if (equalDates(self.selectedDates[i], date)) return "" + i;
1215
+ if (compareDates(self.selectedDates[i], date) === 0) return "" + i;
1113
1216
  }
1114
1217
 
1115
1218
  return false;
@@ -1117,7 +1220,7 @@ function Flatpickr(element, config) {
1117
1220
 
1118
1221
  function isDateInRange(date) {
1119
1222
  if (self.config.mode !== "range" || self.selectedDates.length < 2) return false;
1120
- return date > self.selectedDates[0] && date < self.selectedDates[1];
1223
+ return compareDates(date, self.selectedDates[0]) >= 0 && compareDates(date, self.selectedDates[1]) <= 0;
1121
1224
  }
1122
1225
 
1123
1226
  function updateNavigationCurrentMonth() {
@@ -1146,7 +1249,7 @@ function Flatpickr(element, config) {
1146
1249
  self.mobileInput.value = self.selectedDates.length ? formatDate(self.mobileFormatStr, latestSelectedDateObj()) : "";
1147
1250
  }
1148
1251
 
1149
- var joinChar = self.config.mode !== "range" ? "; " : " to ";
1252
+ var joinChar = self.config.mode !== "range" ? "; " : self.l10n.rangeSeparator;
1150
1253
 
1151
1254
  self.input.value = self.selectedDates.map(function (dObj) {
1152
1255
  return formatDate(self.config.dateFormat, dObj);
@@ -1178,7 +1281,7 @@ function Flatpickr(element, config) {
1178
1281
  var e = document.createElement(tag);
1179
1282
  e.className = className;
1180
1283
 
1181
- if (content) e.textContent = content;
1284
+ if (content) e.innerHTML = content;
1182
1285
 
1183
1286
  return e;
1184
1287
  }
@@ -1202,32 +1305,37 @@ function Flatpickr(element, config) {
1202
1305
  };
1203
1306
  }
1204
1307
 
1205
- function equalDates(date1, date2) {
1308
+ function compareDates(date1, date2) {
1206
1309
  if (!(date1 instanceof Date) || !(date2 instanceof Date)) return false;
1207
- return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
1310
+
1311
+ return new Date(date1.getTime()).setHours(0, 0, 0, 0) - new Date(date2.getTime()).setHours(0, 0, 0, 0);
1208
1312
  }
1209
1313
 
1210
1314
  function timeWrapper(e) {
1211
1315
  e.preventDefault();
1212
- if (e && ((e.target.value || e.target.textContent).length >= 2 || e.type !== "keydown" && e.type !== "input")) e.target.blur();
1316
+ if (e && ((e.target.value || e.target.textContent).length >= 2 || // typed two digits
1317
+ e.type !== "keydown" && e.type !== "input" // scroll event
1318
+ )) e.target.blur();
1213
1319
 
1214
- if (e.target.className === "flatpickr-am-pm") {
1215
- e.target.textContent = ["AM", "PM"][e.target.textContent === "AM" | 0];
1216
- return;
1217
- }
1320
+ if (self.amPM && e.target === self.amPM) return e.target.textContent = ["AM", "PM"][e.target.textContent === "AM" | 0];
1218
1321
 
1219
- var min = parseInt(e.target.min, 10),
1220
- max = parseInt(e.target.max, 10),
1221
- step = parseInt(e.target.step, 10),
1222
- value = parseInt(e.target.value, 10);
1322
+ var min = Number(e.target.min),
1323
+ max = Number(e.target.max),
1324
+ step = Number(e.target.step),
1325
+ curValue = parseInt(e.target.value, 10),
1326
+ delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.deltaY));
1223
1327
 
1224
- var newValue = value;
1328
+ var newValue = Number(curValue);
1225
1329
 
1226
- if (e.type === "wheel") newValue = value + step * Math.max(-1, Math.min(1, e.wheelDelta || -e.deltaY));else if (e.type === "keydown") newValue = value + step * (e.which === 38 ? 1 : -1);
1330
+ if (e.type === "wheel") newValue = curValue + step * delta;else if (e.type === "keydown") newValue = curValue + step * (e.which === 38 ? 1 : -1);
1227
1331
 
1228
- if (newValue <= min) newValue = max - step;else if (newValue >= max) newValue = min + step;
1332
+ if (newValue < min) {
1333
+ newValue = max + newValue + (e.target !== self.hourElement) + (e.target === self.hourElement && !self.amPM);
1334
+ } else if (newValue > max) {
1335
+ newValue = e.target === self.hourElement ? newValue - max - !self.amPM : min;
1336
+ }
1229
1337
 
1230
- if (self.amPM && (value === 11 && newValue === 12 || value === 12 && newValue === 11)) self.amPM.textContent = self.amPM.innerHTML === "PM" ? "AM" : "PM";
1338
+ if (self.amPM && e.target === self.hourElement && (step === 1 ? newValue + curValue === 23 : Math.abs(newValue - curValue) > step)) self.amPM.textContent = self.amPM.innerHTML === "PM" ? "AM" : "PM";
1231
1339
 
1232
1340
  e.target.value = self.pad(newValue);
1233
1341
  }
@@ -1292,6 +1400,9 @@ Flatpickr.defaultConfig = {
1292
1400
  // dateparser that transforms a given string to a date object
1293
1401
  parseDate: null,
1294
1402
 
1403
+ // dateformatter that transforms a given date object to a string, according to passed format
1404
+ formatDate: null,
1405
+
1295
1406
  getWeek: function getWeek(givenDate) {
1296
1407
  var date = new Date(givenDate.getTime());
1297
1408
  date.setHours(0, 0, 0, 0);
@@ -1391,6 +1502,7 @@ Flatpickr.l10ns = {
1391
1502
  return "th";
1392
1503
  }
1393
1504
  },
1505
+ rangeSeparator: " to ",
1394
1506
  weekAbbreviation: "Wk",
1395
1507
  scrollTitle: "Scroll to increment",
1396
1508
  toggleTitle: "Click to toggle"