@wernfried/daterangepicker 4.19.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,13 @@
1
1
  import { DateTime, Duration, Info, Settings } from "luxon";
2
- import { $ } from "jquery";
3
2
  class DateRangePicker {
4
3
  #startDate = null;
5
4
  #endDate = null;
6
5
  constructor(element, options, cb) {
6
+ if (typeof element === "string" && document.querySelectorAll(element).length > 1)
7
+ throw new RangeError(`Option 'element' must match to one element only`);
7
8
  this.parentEl = "body";
8
- this.element = $(element);
9
+ this.element = element instanceof HTMLElement ? element : document.querySelector(element);
10
+ this.isInputText = this.element instanceof HTMLInputElement && this.element.type === "text";
9
11
  this.#startDate = DateTime.now().startOf("day");
10
12
  this.#endDate = DateTime.now().plus({ day: 1 }).startOf("day");
11
13
  this.minDate = null;
@@ -23,7 +25,7 @@ class DateRangePicker {
23
25
  this.showWeekNumbers = false;
24
26
  this.showISOWeekNumbers = false;
25
27
  this.showCustomRangeLabel = true;
26
- this.showLabel = !$(this.element).is("input:text");
28
+ this.showLabel = !this.isInputText;
27
29
  this.timePicker = false;
28
30
  const usesMeridiems = new Intl.DateTimeFormat(DateTime.now().locale, { hour: "numeric" }).resolvedOptions();
29
31
  this.timePicker24Hour = !usesMeridiems.hour12;
@@ -35,8 +37,8 @@ class DateRangePicker {
35
37
  this.isInvalidTime = null;
36
38
  this.isCustomDate = null;
37
39
  this.onOutsideClick = "apply";
38
- this.opens = this.element.hasClass("pull-right") ? "left" : "right";
39
- this.drops = this.element.hasClass("dropup") ? "up" : "down";
40
+ this.opens = this.element?.classList.contains("pull-right") ? "left" : "right";
41
+ this.drops = this.element?.classList.contains("dropup") ? "up" : "down";
40
42
  this.buttonClasses = "btn btn-sm";
41
43
  this.applyButtonClasses = "btn-primary";
42
44
  this.cancelButtonClasses = "btn-default";
@@ -61,6 +63,8 @@ class DateRangePicker {
61
63
  firstDay: Info.getStartOfWeek(),
62
64
  durationFormat: null
63
65
  };
66
+ if (this.element == null)
67
+ return;
64
68
  this.callback = function() {
65
69
  };
66
70
  this.isShowing = false;
@@ -68,7 +72,17 @@ class DateRangePicker {
68
72
  this.rightCalendar = {};
69
73
  if (typeof options !== "object" || options === null)
70
74
  options = {};
71
- options = $.extend(this.element.data(), options);
75
+ let dataOptions = {};
76
+ const data = Array.from(this.element.attributes).filter((x) => x.name.startsWith("data-"));
77
+ for (let item of data) {
78
+ const name = item.name.replace(/^data-/g, "").replace(/-([a-z])/g, function(str) {
79
+ return str[1].toUpperCase();
80
+ });
81
+ let ts = DateTime.fromISO(item.value);
82
+ const isDate = ["startDate", "endDate", "minDate", "maxDate", "initalMonth"].includes(name);
83
+ dataOptions[name] = ts.isValid && isDate ? ts : JSON.parse(item.value);
84
+ }
85
+ options = { ...dataOptions, ...options };
72
86
  if (typeof options.singleDatePicker === "boolean")
73
87
  this.singleDatePicker = options.singleDatePicker;
74
88
  if (!this.singleDatePicker && typeof options.singleMonthView === "boolean") {
@@ -76,9 +90,14 @@ class DateRangePicker {
76
90
  } else {
77
91
  this.singleMonthView = false;
78
92
  }
79
- if (typeof options.externalStyle === "string" && ["bulma"].includes(options.externalStyle))
80
- this.externalStyle = options.externalStyle;
81
- if (typeof options.template !== "string" && !(options.template instanceof $)) {
93
+ if (!(options.externalStyle === null)) {
94
+ const bodyStyle = window.getComputedStyle(document.body);
95
+ if (bodyStyle && typeof bodyStyle[Symbol.iterator] === "function" && [...bodyStyle].some((x) => x.startsWith("--bulma-")))
96
+ this.externalStyle = "bulma";
97
+ }
98
+ if (typeof options.template === "string" || options.template instanceof HTMLElement) {
99
+ this.container = typeof options.template === "string" ? createElementFromHTML(options.template) : options.template;
100
+ } else {
82
101
  let template = [
83
102
  '<div class="daterangepicker">',
84
103
  '<div class="ranges"></div>',
@@ -87,22 +106,19 @@ class DateRangePicker {
87
106
  "<thead></thead>",
88
107
  "<tbody></tbody>",
89
108
  "<tfoot>",
90
- '<tr class="calendar-time start-time"></tr>'
91
- ];
92
- if (this.singleMonthView)
93
- template.push('<tr class="calendar-time end-time"></tr>');
94
- template.push(...[
109
+ '<tr class="calendar-time start-time"></tr>',
110
+ this.singleMonthView ? '<tr class="calendar-time end-time"></tr>' : "",
95
111
  "</tfoot>",
96
112
  "</table>",
97
113
  "</div>"
98
- ]);
114
+ ];
99
115
  template.push(...[
100
116
  '<div class="drp-calendar right">',
101
117
  '<table class="calendar-table">',
102
118
  "<thead></thead>",
103
119
  "<tbody></tbody>",
104
120
  "<tfoot>",
105
- '<tr class="calendar-time end-time"></tr>',
121
+ this.singleMonthView ? "" : '<tr class="calendar-time end-time"></tr>',
106
122
  "</tfoot>",
107
123
  "</table>",
108
124
  "</div>"
@@ -129,9 +145,10 @@ class DateRangePicker {
129
145
  }
130
146
  template.push("</div></div>");
131
147
  options.template = template.join("");
148
+ this.container = createElementFromHTML(options.template);
132
149
  }
133
- this.parentEl = options.parentEl && $(options.parentEl).length ? $(options.parentEl) : $(this.parentEl);
134
- this.container = $(options.template).appendTo(this.parentEl);
150
+ this.parentEl = document.querySelector(typeof options.parentEl === "string" ? options.parentEl : this.parentEl);
151
+ this.parentEl.appendChild(this.container);
135
152
  if (typeof options.timePicker === "boolean")
136
153
  this.timePicker = options.timePicker;
137
154
  if (this.timePicker)
@@ -172,7 +189,7 @@ class DateRangePicker {
172
189
  if (["string", "object", "function"].includes(typeof options.locale.durationFormat) && options.locale.durationFormat != null)
173
190
  this.locale.durationFormat = options.locale.durationFormat;
174
191
  }
175
- this.container.addClass(this.locale.direction);
192
+ this.container.classList.add(this.locale.direction);
176
193
  for (let key2 of [
177
194
  "timePicker24Hour",
178
195
  "showWeekNumbers",
@@ -238,10 +255,6 @@ class DateRangePicker {
238
255
  }
239
256
  }
240
257
  if (this.timePicker) {
241
- if (typeof options.timePickerSeconds === "boolean")
242
- this.timePickerStepSize = Duration.fromObject({ [options.timePickerSeconds ? "seconds" : "minutes"]: 1 });
243
- if (typeof options.timePickerIncrement === "number")
244
- this.timePickerStepSize = Duration.fromObject({ minutes: options.timePickerIncrement });
245
258
  if (["string", "object", "number"].includes(typeof options.timePickerStepSize)) {
246
259
  let duration;
247
260
  if (Duration.isDuration(options.timePickerStepSize) && options.timePickerStepSize.isValid) {
@@ -308,19 +321,18 @@ class DateRangePicker {
308
321
  }
309
322
  }
310
323
  }
311
- if ($(this.element).is("input:text")) {
312
- const val = $(this.element).val();
313
- if (val != "") {
324
+ if (this.isInputText) {
325
+ if (this.element.value != "") {
314
326
  const format = typeof this.locale.format === "string" ? this.locale.format : DateTime.parseFormatForOpts(this.locale.format);
315
327
  if (this.singleDatePicker && typeof options.startDate === "undefined") {
316
- const start = DateTime.fromFormat(val, format, { locale: DateTime.now().locale });
328
+ const start = DateTime.fromFormat(this.element.value, format, { locale: DateTime.now().locale });
317
329
  if (start.isValid) {
318
330
  this.#startDate = start;
319
331
  } else {
320
- console.error(`Value "${val}" in <input> is not a valid string: ${start.invalidExplanation}`);
332
+ console.error(`Value "${this.element.value}" in <input> is not a valid string: ${start.invalidExplanation}`);
321
333
  }
322
334
  } else if (!this.singleDatePicker && typeof options.startDate === "undefined" && typeof options.endDate === "undefined") {
323
- const split = val.split(this.locale.separator);
335
+ const split = this.element.value.split(this.locale.separator);
324
336
  if (split.length === 2) {
325
337
  const start = DateTime.fromFormat(split[0], format, { locale: DateTime.now().locale });
326
338
  const end = DateTime.fromFormat(split[1], format, { locale: DateTime.now().locale });
@@ -331,7 +343,7 @@ class DateRangePicker {
331
343
  console.error(`Value in <input> is not a valid string: ${start.invalidExplanation} - ${end.invalidExplanation}`);
332
344
  }
333
345
  } else {
334
- console.error(`Value "${val}" in <input> is not a valid string`);
346
+ console.error(`Value "${this.element.value}" in <input> is not a valid string`);
335
347
  }
336
348
  }
337
349
  }
@@ -347,8 +359,6 @@ class DateRangePicker {
347
359
  this.#startDate = this.#startDate.startOf("day");
348
360
  this.#endDate = this.#endDate.endOf("day");
349
361
  }
350
- if (options.warnings !== void 0)
351
- console.warn(`Option 'warnings' not used anymore. Listen to event 'violated.daterangepicker'`);
352
362
  if (!this.#startDate && this.initalMonth) {
353
363
  this.#endDate = null;
354
364
  if (this.timePicker)
@@ -356,7 +366,7 @@ class DateRangePicker {
356
366
  } else {
357
367
  const violations = this.validateInput(null, false);
358
368
  if (violations != null) {
359
- let vio = violations.startDate.violations;
369
+ let vio = violations.startDate;
360
370
  if (vio.length > 0) {
361
371
  if (vio.some((x) => x.reason.startsWith("isInvalid"))) {
362
372
  console.error(`Value of startDate "${this.#startDate}" violates ${vio.find((x) => x.reason.startsWith("isInvalid")).reason}`);
@@ -368,7 +378,7 @@ class DateRangePicker {
368
378
  }
369
379
  }
370
380
  if (!this.singleDatePicker) {
371
- vio = violations.endDate.violations.filter((x) => x.new != null);
381
+ vio = violations.endDate.filter((x) => x.new != null);
372
382
  if (vio.length > 0) {
373
383
  if (vio.some((x) => x.reason.startsWith("isInvalid"))) {
374
384
  console.error(`Value of endDate "${this.#endDate}" violates ${vio.find((x) => x.reason.startsWith("isInvalid")).reason}`);
@@ -382,19 +392,27 @@ class DateRangePicker {
382
392
  }
383
393
  }
384
394
  }
385
- if (["function", "string"].includes(typeof options.altFormat))
395
+ if (this.singleDatePicker) {
396
+ if (typeof options.altInput === "string") {
397
+ const el = document.querySelector(options.altInput);
398
+ this.altInput = el instanceof HTMLInputElement && el.type === "text" ? el : null;
399
+ } else if (options.altInput instanceof HTMLElement) {
400
+ this.altInput = options.altInput instanceof HTMLInputElement && options.altInput.type === "text" ? options.altInput : null;
401
+ }
402
+ } else if (!this.singleDatePicker && Array.isArray(options.altInput) && options.altInput.length === 2) {
403
+ this.altInput = [];
404
+ for (let item of options.altInput) {
405
+ const el = typeof item === "string" ? document.querySelector(item) : item;
406
+ if (el instanceof HTMLInputElement && el.type === "text")
407
+ this.altInput.push(el);
408
+ }
409
+ if (this.altInput.length !== 2)
410
+ this.altInput = null;
411
+ } else if (options.altInput != null) {
412
+ console.warn(`Option 'altInput' ${JSON.stringify(options.altInput)} is not valid`);
413
+ }
414
+ if (options.altInput && ["function", "string"].includes(typeof options.altFormat))
386
415
  this.altFormat = options.altFormat;
387
- if (typeof options.altInput === "string" || Array.isArray(options.altInput)) {
388
- if (this.singleDatePicker && typeof options.altInput === "string") {
389
- this.altInput = $(options.altInput).is("input:text") ? options.altInput : null;
390
- } else if (!this.singleDatePicker && Array.isArray(options.altInput) && options.altInput.length === 2) {
391
- this.altInput = options.altInput.every((x) => typeof x === "string" && $(x).is("input:text")) ? options.altInput : null;
392
- } else {
393
- const note = `Value of "altInput" must be ` + (this.singleDatePicker ? "a string" : "an array of two string elements");
394
- console.error(`Option 'altInput' ${JSON.stringify(options.altInput)} is not valid
395
- `, note);
396
- }
397
- }
398
416
  if (typeof options.opens === "string") {
399
417
  if (["left", "right", "center"].includes(options.opens))
400
418
  this.opens = options.opens;
@@ -402,10 +420,10 @@ class DateRangePicker {
402
420
  console.error(`Option 'options.opens' must be 'left', 'right' or 'center'`);
403
421
  }
404
422
  if (typeof options.drops === "string") {
405
- if (["drop", "down", "auto"].includes(options.drops))
423
+ if (["up", "down", "auto"].includes(options.drops))
406
424
  this.drops = options.drops;
407
425
  else
408
- console.error(`Option 'options.drops' must be 'drop', 'down' or 'auto'`);
426
+ console.error(`Option 'options.drops' must be 'up', 'down' or 'auto'`);
409
427
  }
410
428
  if (Array.isArray(options.buttonClasses)) {
411
429
  this.buttonClasses = options.buttonClasses.join(" ");
@@ -452,63 +470,68 @@ class DateRangePicker {
452
470
  }
453
471
  if (start == null || end == null)
454
472
  continue;
455
- options.ranges[range] = [start, end];
456
473
  var elem = document.createElement("textarea");
457
474
  elem.innerHTML = range;
458
475
  this.ranges[elem.value] = [start, end];
459
476
  }
460
477
  var list = "<ul>";
461
- for (let range in this.ranges) {
462
- list += '<li data-range-key="' + range + '">' + range + "</li>";
463
- }
464
- if (this.showCustomRangeLabel) {
465
- list += '<li data-range-key="' + this.locale.customRangeLabel + '">' + this.locale.customRangeLabel + "</li>";
466
- }
478
+ for (let range in this.ranges)
479
+ list += `<li data-range-key="${range}">${range}</li>`;
480
+ if (this.showCustomRangeLabel)
481
+ list += `<li data-range-key="${this.locale.customRangeLabel}">${this.locale.customRangeLabel}</li>`;
467
482
  list += "</ul>";
468
- this.container.find(".ranges").prepend(list);
469
- this.container.addClass("show-ranges");
483
+ this.container.querySelector(".ranges").prepend(createElementFromHTML(list));
484
+ this.container.classList.add("show-ranges");
470
485
  }
471
486
  if (typeof cb === "function")
472
487
  this.callback = cb;
473
- if (!this.timePicker) {
474
- this.container.find(".calendar-time").hide();
475
- }
488
+ if (!this.timePicker)
489
+ this.container.querySelectorAll(".calendar-time").forEach((el) => {
490
+ el.style.display = "none";
491
+ });
476
492
  if (this.timePicker && this.autoApply)
477
493
  this.autoApply = false;
478
494
  if (this.autoApply)
479
- this.container.addClass("auto-apply");
495
+ this.container.classList.add("auto-apply");
480
496
  if (this.singleDatePicker || this.singleMonthView) {
481
- this.container.addClass("single");
482
- this.container.find(".drp-calendar.left").addClass("single");
483
- this.container.find(".drp-calendar.left").show();
484
- this.container.find(".drp-calendar.right").hide();
497
+ this.container.classList.add("single");
498
+ this.container.querySelector(".drp-calendar.left").classList.add("single");
499
+ this.container.querySelector(".drp-calendar.left").style.display = "";
500
+ this.container.querySelector(".drp-calendar.right").style.display = "none";
485
501
  if (!this.timePicker && this.autoApply)
486
- this.container.addClass("auto-apply");
502
+ this.container.classList.add("auto-apply");
487
503
  }
488
- if (typeof options.ranges === "undefined" && !this.singleDatePicker || this.alwaysShowCalendars)
489
- this.container.addClass("show-calendar");
490
- this.container.addClass("opens" + this.opens);
491
- this.container.find(".applyBtn, .cancelBtn").addClass(this.buttonClasses);
504
+ if (this.singleDatePicker || !Object.keys(this.ranges).length || this.alwaysShowCalendars)
505
+ this.container.classList.add("show-calendar");
506
+ this.container.classList.add(`opens${this.opens}`);
507
+ this.container.querySelectorAll(".applyBtn, .cancelBtn").forEach((el) => {
508
+ el.classList.add(...this.buttonClasses.split(" "));
509
+ });
492
510
  if (this.applyButtonClasses.length)
493
- this.container.find(".applyBtn").addClass(this.applyButtonClasses);
511
+ this.container.querySelector(".applyBtn").classList.add(...this.applyButtonClasses.split(" "));
494
512
  if (this.cancelButtonClasses.length)
495
- this.container.find(".cancelBtn").addClass(this.cancelButtonClasses);
496
- this.container.find(".applyBtn").html(this.locale.applyLabel);
497
- this.container.find(".cancelBtn").html(this.locale.cancelLabel);
498
- this.container.find(".drp-calendar").on("click.daterangepicker", ".prev", this.clickPrev.bind(this)).on("click.daterangepicker", ".next", this.clickNext.bind(this)).on("mousedown.daterangepicker", "td.available", this.clickDate.bind(this)).on("mouseenter.daterangepicker", "td.available", this.hoverDate.bind(this)).on("change.daterangepicker", "select.yearselect", this.monthOrYearChanged.bind(this)).on("change.daterangepicker", "select.monthselect", this.monthOrYearChanged.bind(this)).on("change.daterangepicker", "select.hourselect,select.minuteselect,select.secondselect,select.ampmselect", this.timeChanged.bind(this));
499
- this.container.find(".ranges").on("click.daterangepicker", "li", this.clickRange.bind(this)).on("mouseenter.daterangepicker", "li", this.hoverRange.bind(this)).on("mouseleave.daterangepicker", "li", this.leaveRange.bind(this));
500
- this.container.find(".drp-buttons").on("click.daterangepicker", "button.applyBtn", this.clickApply.bind(this)).on("click.daterangepicker", "button.cancelBtn", this.clickCancel.bind(this));
501
- if (this.element.is("input") || this.element.is("button")) {
502
- this.element.on({
503
- "click.daterangepicker": this.show.bind(this),
504
- "focus.daterangepicker": this.show.bind(this),
505
- "keyup.daterangepicker": this.elementChanged.bind(this),
506
- "keydown.daterangepicker": this.keydown.bind(this)
507
- //IE 11 compatibility
508
- });
513
+ this.container.querySelector(".cancelBtn").classList.add(...this.cancelButtonClasses.split(" "));
514
+ this.container.querySelector(".applyBtn").innerHTML = this.locale.applyLabel;
515
+ this.container.querySelector(".cancelBtn").innerHTML = this.locale.cancelLabel;
516
+ this.addListener(".drp-calendar", "click", ".prev", this.clickPrev.bind(this));
517
+ this.addListener(".drp-calendar", "click", ".next", this.clickNext.bind(this));
518
+ this.addListener(".drp-calendar", "mousedown", "td.available", this.clickDate.bind(this));
519
+ this.addListener(".drp-calendar", "mouseenter", "td.available", this.hoverDate.bind(this));
520
+ this.addListener(".drp-calendar", "change", "select.yearselect,select.monthselect", this.monthOrYearChanged.bind(this));
521
+ this.addListener(".drp-calendar", "change", "select.hourselect,select.minuteselect,select.secondselect,select.ampmselect", this.timeChanged.bind(this));
522
+ this.addListener(".ranges", "click", "li", this.clickRange.bind(this));
523
+ this.addListener(".ranges", "mouseenter", "li", this.hoverRange.bind(this));
524
+ this.addListener(".ranges", "mouseleave", "li", this.leaveRange.bind(this));
525
+ this.addListener(".drp-buttons", "click", "button.applyBtn", this.clickApply.bind(this));
526
+ this.addListener(".drp-buttons", "click", "button.cancelBtn", this.clickCancel.bind(this));
527
+ if (this.element.matches("input") || this.element.matches("button")) {
528
+ this.element.addEventListener("click", this.#showProxy);
529
+ this.element.addEventListener("focus", this.#showProxy);
530
+ this.element.addEventListener("keyup", this.#elementChangedProxy);
531
+ this.element.addEventListener("keydown", this.#keydownProxy);
509
532
  } else {
510
- this.element.on("click.daterangepicker", this.toggle.bind(this));
511
- this.element.on("keydown.daterangepicker", this.toggle.bind(this));
533
+ this.element.addEventListener("click", this.#toggleProxy);
534
+ this.element.addEventListener("keydown", this.#toggleProxy);
512
535
  }
513
536
  this.updateElement();
514
537
  }
@@ -542,14 +565,14 @@ class DateRangePicker {
542
565
  * `minDate`, `maxDate`, `minSpan`, `maxSpan`, `invalidDate` and `invalidTime` constraints.<br>
543
566
  * Event is only triggered when date string is valid and date value is changing<br>
544
567
  * @event
545
- * @name "violate.daterangepicker"
546
- * @param {DateRangePicker} picker - The daterangepicker object
547
- * @param {InputViolation} result - The violation object, see example of `validateInput()`
548
- * @param {Object} newDate - Object of {startDate, endDate}
549
- * @return {boolean}=undefined - If handler returns `true`, then values from `newDate` object are used
568
+ * @name "violate"
569
+ * @property {DateRangePickerEvent} event - The Event object
570
+ * @property {DateRangePicker} event.picker - The daterangepicker object
571
+ * @property {InputViolation} event.violation - The daterangepicker object
572
+ * @property {NewDate} event.newDate - Object of corrected date values
573
+ * @property {boolean} event.cancelable=true - By calling `event.preventDefault()` the `newDate` values will apply
550
574
  * @example
551
- *
552
- * $('#picker').daterangepicker({
575
+ * daterangepicker('#picker', {
553
576
  * startDate: DateTime.now(),
554
577
  * // allow only dates from current year
555
578
  * minDate: DateTime.now().startOf('year'),
@@ -558,126 +581,154 @@ class DateRangePicker {
558
581
  * locale: {
559
582
  * format: DateTime.DATETIME_SHORT
560
583
  * }
561
- * }).on('violate.daterangepicker', (ev, picker, result, newDate) => {
562
- * newDate.startDate = DateTime.now().minus({ days: 3 }).startOf('day');
563
- * return true;
584
+ * }).addEventListener('violate', (ev) => {
585
+ * ev.newDate.startDate = DateTime.now().minus({ days: 3 }).startOf('day');
586
+ * ev.preventDefault();
564
587
  * });
565
588
  *
566
589
  * // Try to set date outside permitted range at <input> elemet
567
- * $('#picker').val(DateTime.now().minus({ years: 10 })).toLocaleString(DateTime.DATETIME_SHORT).trigger('keyup');
590
+ * const input = document.querySelector('#picker');
591
+ * input.value = DateTime.now().minus({ years: 10 })).toLocaleString(DateTime.DATETIME_SHORT)
592
+ * input.dispatchEvent(new Event('keyup'));
568
593
 
569
594
  * // Try to set date outside permitted range by code
570
- * const drp = $('#picker').data('daterangepicker').setStartDate(DateTime.now().minus({ years: 10 })
595
+ * const drp = getDateRangePicker('#picker');
596
+ * drp.setStartDate(DateTime.now().minus({ years: 10 });
571
597
  *
572
598
  * // -> Calendar selects and shows "today - 3 days"
573
599
  */
574
- onViolate: { type: "violate.daterangepicker", param: (...args) => [this, ...args] },
600
+ onViolate: { type: "violate", param: (violation, newDate) => {
601
+ return { ...violation, ...{ cancelable: true } };
602
+ } },
575
603
  /**
576
604
  * Emitted before the calendar time picker is rendered.
577
605
  * @event
578
- * @name "beforeRenderCalendar.daterangepicker"
579
- * @param {DateRangePicker} this - The daterangepicker object
606
+ * @name "beforeRenderCalendar"
607
+ * @property {DateRangePickerEvent} event - The Event object
608
+ * @property {DateRangePicker} event.picker - The daterangepicker object
580
609
  */
581
- onBeforeRenderTimePicker: { type: "beforeRenderTimePicker.daterangepicker", param: this },
610
+ onBeforeRenderTimePicker: { type: "beforeRenderTimePicker" },
582
611
  /**
583
612
  * Emitted before the calendar is rendered. Useful to remove any manually added elements.
584
613
  * @event
585
- * @name "beforeRenderCalendar.daterangepicker"
586
- * @param {DateRangePicker} this - The daterangepicker object
614
+ * @name "beforeRenderCalendar"
615
+ * @property {DateRangePickerEvent} event - The Event object
616
+ * @property {DateRangePicker} event.picker - The daterangepicker object
587
617
  */
588
- onBeforeRenderCalendar: { type: "beforeRenderCalendar.daterangepicker", param: this },
618
+ onBeforeRenderCalendar: { type: "beforeRenderCalendar" },
589
619
  /**
590
620
  * Emitted when the picker is shown
591
621
  * @event
592
- * @name "show.daterangepicker"
593
- * @param {DateRangePicker} this - The daterangepicker object
622
+ * @name "show"
623
+ * @property {DateRangePickerEvent} event - The Event object
624
+ * @property {DateRangePicker} event.picker - The daterangepicker object
594
625
  */
595
- onShow: { type: "show.daterangepicker", param: this },
626
+ onShow: { type: "show" },
596
627
  /**
597
- * Emitted before the picker will hide. When EventHandler returns `true`, then picker remains visible
628
+ * Emitted before the picker will hide.
598
629
  * @event
599
- * @name "beforeHide.daterangepicker"
600
- * @param {DateRangePicker} this - The daterangepicker object
601
- * @return {boolean} cancel - If `true`, then the picker remains visible
630
+ * @name "beforeHide"
631
+ * @property {DateRangePickerEvent} event - The Event object
632
+ * @property {DateRangePicker} event.picker - The daterangepicker object
633
+ * @property {boolean} event.cancelable=true - Hide is canceled by calling `event.preventDefault()`
602
634
  */
603
- onBeforeHide: { type: "beforeHide.daterangepicker", param: this },
635
+ onBeforeHide: { type: "beforeHide", param: { cancelable: true } },
604
636
  /**
605
637
  * Emitted when the picker is hidden
606
638
  * @event
607
- * @name "hide.daterangepicker"
608
- * @param {DateRangePicker} this - The daterangepicker object
639
+ * @name "hide"
640
+ * @property {DateRangePickerEvent} event - The Event object
641
+ * @property {DateRangePicker} event.picker - The daterangepicker object
609
642
  */
610
- onHide: { type: "hide.daterangepicker", param: this },
643
+ onHide: { type: "hide" },
611
644
  /**
612
645
  * Emitted when the calendar(s) are shown.
613
646
  * Only useful when {@link #Ranges|Ranges} are used.
614
647
  * @event
615
- * @name "showCalendar.daterangepicker"
616
- * @param {DateRangePicker} this - The daterangepicker object
648
+ * @name "showCalendar"
649
+ * @property {DateRangePickerEvent} event - The Event object
650
+ * @property {DateRangePicker} event.picker - The daterangepicker object
617
651
  */
618
- onShowCalendar: { type: "showCalendar.daterangepicker", param: this },
652
+ onShowCalendar: { type: "showCalendar" },
619
653
  /**
620
654
  * Emitted when the calendar(s) are hidden. Only used when {@link #Ranges|Ranges} are used.
621
655
  * @event
622
- * @name "hideCalendar.daterangepicker"
623
- * @param {DateRangePicker} this - The daterangepicker object
656
+ * @name "hideCalendar"
657
+ * @property {DateRangePickerEvent} event - The Event object
658
+ * @property {DateRangePicker} event.picker - The daterangepicker object
624
659
  */
625
- onHideCalendar: { type: "hideCalendar.daterangepicker", param: this },
660
+ onHideCalendar: { type: "hideCalendar" },
626
661
  /**
627
662
  * Emitted when user clicks outside the picker. Use option `onOutsideClick` to define the default action, then you may not need to handle this event.
628
663
  * @event
629
- * @name "outsideClick.daterangepicker"
630
- * @param {DateRangePicker} this - The daterangepicker object
664
+ * @name "outsideClick"
665
+ * @property {DateRangePickerEvent} event - The Event object
666
+ * @property {DateRangePicker} event.picker - The daterangepicker object
631
667
  */
632
- onOutsideClick: { type: "outsideClick.daterangepicker", param: this },
668
+ onOutsideClick: { type: "outsideClick" },
633
669
  /**
634
- * Emitted when the date changed. Does not trigger when time is changed, use {@link #event_timeChange.daterangepicker|"timeChange.daterangepicker"} to handle it
670
+ * Emitted when the date changed. Does not trigger when time is changed, use {@link #event_timeChange|"timeChange"} to handle it
635
671
  * @event
636
- * @name "dateChange.daterangepicker"
637
- * @param {DateRangePicker} this - The daterangepicker object
638
- * @param {string} side - Either `'start'` or `'end'` indicating whether startDate or endDate was changed. `null` when `singleDatePicker: true`
672
+ * @name "dateChange"
673
+ * @property {DateRangePickerEvent} event - The Event object
674
+ * @property {DateRangePicker} event.picker - The daterangepicker object
675
+ * @property {string} side - Either `'start'` or `'end'` indicating whether `startDate` or `endDate` was changed. `null` for singleDatePicker
639
676
  */
640
- onDateChange: { type: "dateChange.daterangepicker", param: (side) => [this, side] },
677
+ onDateChange: { type: "dateChange", param: (side) => {
678
+ return side;
679
+ } },
641
680
  /**
642
681
  * Emitted when the time changed. Does not trigger when date is changed
643
682
  * @event
644
- * @name "timeChange.daterangepicker"
645
- * @param {DateRangePicker} this - The daterangepicker object
646
- * @param {string} side - Either `'start'` or `'end'` indicating whether startDate or endDate was changed
683
+ * @name "timeChange"
684
+ * @property {DateRangePickerEvent} event - The Event object
685
+ * @property {DateRangePicker} event.picker - The daterangepicker object
686
+ * @property {string} side - Either `'start'` or `'end'` indicating whether `startDate` or `endDate` was changed. `null` for singleDatePicker
647
687
  */
648
- onTimeChange: { type: "timeChange.daterangepicker", param: (side) => [this, side] },
688
+ onTimeChange: { type: "timeChange", param: (side) => {
689
+ return side;
690
+ } },
649
691
  /**
650
692
  * Emitted when the `Apply` button is clicked, or when a predefined {@link #Ranges|Ranges} is clicked
651
693
  * @event
652
- * @name "apply.daterangepicker"
653
- * @param {DateRangePicker} this - The daterangepicker object
694
+ * @name "apply"
695
+ * @property {DateRangePickerEvent} event - The Event object
696
+ * @property {DateRangePicker} event.picker - The daterangepicker object
654
697
  */
655
- onApply: { type: "apply.daterangepicker", param: this },
698
+ onApply: { type: "apply" },
656
699
  /**
657
700
  * Emitted when the `Cancel` button is clicked
658
701
  * @event
659
- * @name "cancel.daterangepicker"
660
- * @param {DateRangePicker} this - The daterangepicker object
702
+ * @name "cancel"
703
+ * @property {DateRangePickerEvent} event - The Event object
704
+ * @property {DateRangePicker} event.picker - The daterangepicker object
661
705
  */
662
- onCancel: { type: "cancel.daterangepicker", param: this },
706
+ onCancel: { type: "cancel" },
663
707
  /**
664
708
  * Emitted when the date is changed through `<input>` element. Event is only triggered when date string is valid and date value has changed
665
709
  * @event
666
- * @name "inputChange.daterangepicker"
667
- * @param {DateRangePicker} this - The daterangepicker object
710
+ * @name "inputChange"
711
+ * @property {DateRangePickerEvent} event - The Event object
712
+ * @property {DateRangePicker} event.picker - The daterangepicker object
668
713
  */
669
- onInputChange: { type: "inputChange.daterangepicker", param: this },
714
+ onInputChange: { type: "inputChange" },
670
715
  /**
671
716
  * Emitted after month view changed, for example by click on 'prev' or 'next'
672
717
  * @event
673
- * @name "monthViewChange.daterangepicker"
674
- * @param {DateRangePicker} this - The daterangepicker object
675
- * @param {external:DateTime} left - For day of left-hand calendar
676
- * @param {external:DateTime|null} right - For day of right-hand calendar
718
+ * @name "monthViewChange"
719
+ * @property {DateRangePickerEvent} event - The Event object
720
+ * @property {DateRangePicker} event.picker - The daterangepicker object
721
+ * @property {external:DateTime} left - The first day of month in left-hand calendar
722
+ * @property {external:DateTime} right - The first day of month in left-hand calendar or `null` for singleDatePicker
677
723
  */
678
724
  onMonthViewChange: {
679
- type: "monthViewChange.daterangepicker",
680
- param: (left, right) => [this, left.startOf("month"), right ? right.startOf("month") : null]
725
+ type: "monthViewChange",
726
+ param: (left, right) => {
727
+ return {
728
+ left: this.leftCalendar.month.startOf("month"),
729
+ right: this.singleMonthView || this.singleDatePicker ? null : this.rightCalendar.month.startOf("month")
730
+ };
731
+ }
681
732
  }
682
733
  };
683
734
  /**
@@ -686,16 +737,27 @@ class DateRangePicker {
686
737
  get events() {
687
738
  return this.#events;
688
739
  }
740
+ #outsideClickProxy = this.outsideClick.bind(this);
741
+ #onResizeProxy = this.move.bind(this);
742
+ #dropdownClickWrapper = (e) => {
743
+ const match = e.target.closest('[data-toggle="dropdown"]');
744
+ if (match && document.contains(match))
745
+ this.#outsideClickProxy(e);
746
+ };
747
+ #showProxy = this.show.bind(this);
748
+ #elementChangedProxy = this.elementChanged.bind(this);
749
+ #keydownProxy = this.keydown.bind(this);
750
+ #toggleProxy = this.toggle.bind(this);
689
751
  /* #region Set startDate/endDate */
690
752
  /**
691
753
  * Sets the date range picker's currently selected start date to the provided date.<br>
692
754
  * `startDate` must be a `luxon.DateTime` or `Date` or `string` according to {@link ISO-8601} or a string matching `locale.format`.<br>
693
- * Invalid date values are handled by {@link #DateRangePicker+violated|violated} Event
755
+ * Invalid date values are handled by {@link #DateRangePicker+violate|violate} Event
694
756
  * @param {external:DateTime|external:Date|string} startDate - startDate to be set. In case of ranges, the current `endDate` is used.
695
757
  * @param {boolean} updateView=true - If `true`, then calendar UI is updated to new value. Otherwise only internal values are set.
696
758
  * @returns {InputViolation} - Object of violations or `null` if no violation have been found
697
759
  * @example
698
- * const drp = $('#picker').data('daterangepicker');
760
+ * const drp = getDateRangePicker('#picker');
699
761
  * drp.setStartDate(DateTime.now().startOf('hour'));
700
762
  */
701
763
  setStartDate(startDate, updateView = true) {
@@ -728,12 +790,12 @@ class DateRangePicker {
728
790
  /**
729
791
  * Sets the date range picker's currently selected start date to the provided date.<br>
730
792
  * `endDate` must be a `luxon.DateTime` or `Date` or `string` according to {@link ISO-8601} or a string matching `locale.format`.<br>
731
- * Invalid date values are handled by {@link #DateRangePicker+violated|violated} Event
793
+ * Invalid date values are handled by {@link #DateRangePicker+violate|violate} Event
732
794
  * @param {external:DateTime|external:Date|string} endDate - endDate to be set. In case of ranges, the current `startDate` is used.
733
795
  * @param {boolean} updateView=true - If `true`, then calendar UI is updated to new value. Otherwise only internal values are set.
734
796
  * @returns {InputViolation} - Object of violations or `null` if no violation have been found
735
797
  * @example
736
- * const drp = $('#picker').data('daterangepicker');
798
+ * const drp = getDateRangePicker('#picker');
737
799
  * drp.setEndDate(DateTime.now().startOf('hour'));
738
800
  */
739
801
  setEndDate(endDate, updateView = true) {
@@ -742,13 +804,13 @@ class DateRangePicker {
742
804
  /**
743
805
  * Sets the date range picker's currently selected start date to the provided date.<br>
744
806
  * `startDate` and `endDate` must be a `luxon.DateTime` or `Date` or `string` according to {@link ISO-8601} or a string matching `locale.format`.<br>
745
- * Invalid date values are handled by {@link #DateRangePicker+violated|violated} Event
807
+ * Invalid date values are handled by {@link #DateRangePicker+violate|violate} Event
746
808
  * @param {external:DateTime|external:Date|string} startDate - startDate to be set
747
809
  * @param {external:DateTime|external:Date|string} endDate - endDate to be set
748
810
  * @param {boolean} updateView=true - If `true`, then calendar UI is updated to new value. Otherwise only internal values are set.
749
811
  * @returns {InputViolation} - Object of violations or `null` if no violation have been found
750
812
  * @example
751
- * const drp = $('#picker').data('daterangepicker');
813
+ * const drp = getDateRangePicker('#picker');
752
814
  * drp.setRange(DateTime.now().startOf('hour'), DateTime.now().endOf('day'));
753
815
  */
754
816
  setRange(startDate, endDate, updateView = true) {
@@ -841,45 +903,49 @@ class DateRangePicker {
841
903
  if (this.#endDate)
842
904
  text += this.formatDate(this.#endDate);
843
905
  }
844
- this.container.find(".drp-selected").html(text);
906
+ this.container.querySelector(".drp-selected").innerHTML = text;
845
907
  }
846
908
  if (this.singleDatePicker || this.locale.durationFormat == null)
847
909
  return;
848
910
  if (!this.#endDate) {
849
- this.container.find(".drp-duration-label").html("");
911
+ this.container.querySelector(".drp-duration-label").innerHTML = "";
850
912
  return;
851
913
  }
852
914
  if (typeof this.locale.durationFormat === "function") {
853
- this.container.find(".drp-duration-label").html(this.locale.durationFormat(this.#startDate, this.#endDate));
915
+ this.container.querySelector(".drp-duration-label").innerHTML = this.locale.durationFormat(this.#startDate, this.#endDate);
854
916
  } else {
855
917
  let duration = this.#endDate.plus({ milliseconds: 1 }).diff(this.#startDate).rescale().set({ milliseconds: 0 });
856
918
  if (!this.timePicker)
857
919
  duration = duration.set({ seconds: 0, minutes: 0, hours: 0 });
858
920
  duration = duration.removeZeros();
859
921
  if (typeof this.locale.durationFormat === "object") {
860
- this.container.find(".drp-duration-label").html(duration.toHuman(this.locale.durationFormat));
922
+ this.container.querySelector(".drp-duration-label").innerHTML = duration.toHuman(this.locale.durationFormat);
861
923
  } else {
862
- this.container.find(".drp-duration-label").html(duration.toFormat(this.locale.durationFormat));
924
+ this.container.querySelector(".drp-duration-label").innerHTML = duration.toFormat(this.locale.durationFormat);
863
925
  }
864
926
  }
865
927
  }
866
928
  /**
867
929
  * @typedef InputViolation
868
930
  * @type {Object}
869
- * @property {external:DateTime} startDate - Violation of startDate
870
- * @property {external:DateTime|undefined} endDate? - Violation of endDate, if existing
871
- * @property {Array} violations - The constraints which violates the input
872
- * @property {Array} reason - The type/reson of violation
931
+ * @typedef {object} Violation
932
+ * @property {string} reason - The type/reason of violation
873
933
  * @property {external:DateTime} old - Old value startDate/endDate
874
934
  * @property {external:DateTime} new? - Corrected value of startDate/endDate if existing
935
+ * @typedef {object} NewDate
936
+ * @property {external:DateTime} newDate.startDate- Object with corrected values
937
+ * @property {external:DateTime} newDate.endDate - Object with corrected values
938
+ * @property {Violation[]} startDate - The constraints which violates the input
939
+ * @property {Violation[]?} endDate - The constraints which violates the input or `null` for singleDatePicker
940
+ * @property {NewDate} newDate - Object with corrected values
875
941
  */
876
942
  /**
877
943
  * Validate `startDate` and `endDate` against `timePickerStepSize`, `minDate`, `maxDate`,
878
944
  * `minSpan`, `maxSpan`, `invalidDate` and `invalidTime`.
879
945
  * @param {Array} range - `[startDate, endDate]`<br>Range to be checked, defaults to current `startDate` and `endDate`
880
- * @param {boolean} dipatch=false - If `true` then event "violated.daterangepicker" is dispated.<br>
946
+ * @param {boolean} dipatch=false - If `true` then event "violate" is dispated.<br>
881
947
  * If eventHandler returns `true`, then `null` is returned, otherwiese the object of violations.
882
- * @emits "violated.daterangepicker"
948
+ * @emits "violate"
883
949
  * @returns {InputViolation|null} - Object of violations and corrected values or `null` if no violation have been found
884
950
  * @example
885
951
  * options => {
@@ -892,18 +958,18 @@ class DateRangePicker {
892
958
  * const result = validateInput(DateTime.now(), DateTime.now().plus({day: 3}));
893
959
  *
894
960
  * result => {
895
- * startDate: {
896
- * violations: [
897
- * { old: "2026-03-13T10:35:52", reason: "timePickerStepSize", new: "2026-03-13T11:00:00" },
898
- * { old: "2026-03-13T11:00:00", reason: "maxDate", new: "2026-03-10T00:00:00" }
899
- * ]
900
- * },
961
+ * startDate: [
962
+ * { old: "2026-03-13T10:35:52", reason: "timePickerStepSize", new: "2026-03-13T11:00:00" },
963
+ * { old: "2026-03-13T11:00:00", reason: "maxDate", new: "2026-03-10T00:00:00" }
964
+ * ],
901
965
  * endDate: {
902
- * violations: [
903
- * { old: "2026-03-16T10:35:52", reason: "stepSize", new: "2026-03-16T11:00:00" },
904
- * { old: "2026-03-16T11:00:00", reason: "maxDate", new: "2026-03-10T00:00:00" },
905
- * { old: "2026-03-10T00:00:00", reason: "minSpan", new: "2026-03-17T00:00:00" }
906
- * ]
966
+ * { old: "2026-03-16T10:35:52", reason: "stepSize", new: "2026-03-16T11:00:00" },
967
+ * { old: "2026-03-16T11:00:00", reason: "maxDate", new: "2026-03-10T00:00:00" },
968
+ * { old: "2026-03-10T00:00:00", reason: "minSpan", new: "2026-03-17T00:00:00" }
969
+ * ],
970
+ * newDate: {
971
+ * startDate: "2026-03-10T00:00:00",
972
+ * endDate: "2026-03-17T00:00:00"
907
973
  * }
908
974
  * }
909
975
  */
@@ -912,14 +978,14 @@ class DateRangePicker {
912
978
  let endDate = range == null ? this.#endDate : range[1];
913
979
  if (startDate == null)
914
980
  return null;
915
- let result = { startDate: { violations: [] } };
981
+ let result = { startDate: [] };
916
982
  let violation = { old: startDate, reason: this.timePicker ? "timePickerStepSize" : "timePicker" };
917
983
  if (this.timePicker) {
918
984
  const secs = this.timePickerStepSize.as("seconds");
919
985
  startDate = DateTime.fromSeconds(secs * Math.round(startDate.toSeconds() / secs));
920
986
  violation.new = startDate;
921
987
  if (!violation.new.equals(violation.old))
922
- result.startDate.violations.push(violation);
988
+ result.startDate.push(violation);
923
989
  } else {
924
990
  startDate = startDate.startOf("day");
925
991
  }
@@ -931,7 +997,7 @@ class DateRangePicker {
931
997
  startDate = startDate.plus(this.timePicker ? this.timePickerStepSize : { days: 1 });
932
998
  violation.new = startDate;
933
999
  if (!violation.new.equals(violation.old))
934
- result.startDate.violations.push(violation);
1000
+ result.startDate.push(violation);
935
1001
  } else if (this.maxDate && startDate > this.maxDate) {
936
1002
  violation = { old: startDate, reason: "maxDate" };
937
1003
  startDate = startDate.minus({ seconds: Math.trunc(startDate.diff(this.maxDate).as("seconds") / shiftStep) * shiftStep });
@@ -939,7 +1005,7 @@ class DateRangePicker {
939
1005
  startDate = startDate.minus(this.timePicker ? this.timePickerStepSize : { days: 1 });
940
1006
  violation.new = startDate;
941
1007
  if (!violation.new.equals(violation.old))
942
- result.startDate.violations.push(violation);
1008
+ result.startDate.push(violation);
943
1009
  }
944
1010
  let units = ["hour"];
945
1011
  if (this.timePicker) {
@@ -951,21 +1017,21 @@ class DateRangePicker {
951
1017
  units.push("ampm");
952
1018
  }
953
1019
  if (this.isInvalidDate(startDate))
954
- result.startDate.violations.push({ old: startDate, reason: "isInvalidDate" });
1020
+ result.startDate.push({ old: startDate, reason: "isInvalidDate" });
955
1021
  if (this.timePicker) {
956
1022
  for (let unit of units) {
957
1023
  if (this.isInvalidTime(startDate, unit, "start"))
958
- result.startDate.violations.push({ old: startDate, reason: "isInvalidTime", unit });
1024
+ result.startDate.push({ old: startDate, reason: "isInvalidTime", unit });
959
1025
  }
960
1026
  }
961
1027
  if (this.singleDatePicker) {
962
- if (result.startDate.violations.length == 0)
1028
+ if (result.startDate.length == 0)
963
1029
  return null;
964
1030
  if (dipatch) {
965
1031
  let newValues = { startDate };
966
- const ret = this.triggerHandler(this.#events.onViolate, result, newValues);
967
- if (ret) {
968
- result.newDate = newValues;
1032
+ const event = this.triggerEvent(this.#events.onViolate, { violation: result, newDate: newValues });
1033
+ if (event.defaultPrevented) {
1034
+ result.newDate = event.newDate;
969
1035
  return result;
970
1036
  }
971
1037
  return result;
@@ -975,14 +1041,14 @@ class DateRangePicker {
975
1041
  }
976
1042
  if (endDate == null)
977
1043
  return null;
978
- result.endDate = { violations: [] };
1044
+ result.endDate = [];
979
1045
  violation = { old: endDate, reason: this.timePicker ? "stepSize" : "timePicker" };
980
1046
  if (this.timePicker) {
981
1047
  const secs = this.timePickerStepSize.as("seconds");
982
1048
  endDate = DateTime.fromSeconds(secs * Math.round(endDate.toSeconds() / secs));
983
1049
  violation.new = endDate;
984
1050
  if (!violation.new.equals(violation.old))
985
- result.endDate.violations.push(violation);
1051
+ result.endDate.push(violation);
986
1052
  } else {
987
1053
  endDate = endDate.endOf("day");
988
1054
  }
@@ -993,7 +1059,7 @@ class DateRangePicker {
993
1059
  endDate = endDate.minus(this.timePicker ? this.timePickerStepSize : { days: 1 });
994
1060
  violation.new = endDate;
995
1061
  if (!violation.new.equals(violation.old))
996
- result.endDate.violations.push(violation);
1062
+ result.endDate.push(violation);
997
1063
  } else if (this.minDate && endDate < this.minDate) {
998
1064
  violation = { old: endDate, reason: "minDate" };
999
1065
  endDate = endDate.plus({ seconds: Math.trunc(this.minDate.diff(endDate).as("seconds") / shiftStep) * shiftStep });
@@ -1001,7 +1067,7 @@ class DateRangePicker {
1001
1067
  endDate = endDate.plus(this.timePicker ? this.timePickerStepSize : { days: 1 });
1002
1068
  violation.new = endDate;
1003
1069
  if (!violation.new.equals(violation.old))
1004
- result.endDate.violations.push(violation);
1070
+ result.endDate.push(violation);
1005
1071
  }
1006
1072
  if (this.maxSpan) {
1007
1073
  const maxDate = startDate.plus(this.maxSpan);
@@ -1012,7 +1078,7 @@ class DateRangePicker {
1012
1078
  endDate = endDate.minus(this.timePicker ? this.timePickerStepSize : { days: 1 });
1013
1079
  violation.new = endDate;
1014
1080
  if (!violation.new.equals(violation.old))
1015
- result.endDate.violations.push(violation);
1081
+ result.endDate.push(violation);
1016
1082
  }
1017
1083
  }
1018
1084
  if (this.minSpan) {
@@ -1024,24 +1090,24 @@ class DateRangePicker {
1024
1090
  endDate = endDate.plus(this.timePicker ? this.timePickerStepSize : { days: 1 });
1025
1091
  violation.new = endDate;
1026
1092
  if (!violation.new.equals(violation.old))
1027
- result.endDate.violations.push(violation);
1093
+ result.endDate.push(violation);
1028
1094
  }
1029
1095
  }
1030
1096
  if (this.isInvalidDate(endDate))
1031
- result.endDate.violations.push({ old: endDate, reason: "isInvalidDate" });
1097
+ result.endDate.push({ old: endDate, reason: "isInvalidDate" });
1032
1098
  if (this.timePicker) {
1033
1099
  for (let unit of units) {
1034
1100
  if (this.isInvalidTime(endDate, unit, "end"))
1035
- result.endDate.violations.push({ old: endDate, reason: "isInvalidTime", unit });
1101
+ result.endDate.push({ old: endDate, reason: "isInvalidTime", unit });
1036
1102
  }
1037
1103
  }
1038
- if (result.startDate.violations.length == 0 && result.endDate.violations.length == 0)
1104
+ if (result.startDate.length == 0 && result.endDate.length == 0)
1039
1105
  return null;
1040
1106
  if (dipatch) {
1041
1107
  let newValues = { startDate, endDate };
1042
- const ret = this.triggerHandler(this.#events.onViolate, result, newValues);
1043
- if (ret) {
1044
- result.newDate = newValues;
1108
+ const event = this.triggerEvent(this.#events.onViolate, { violation: result, newDate: newValues });
1109
+ if (event.defaultPrevented) {
1110
+ result.newDate = event.newDate;
1045
1111
  return result;
1046
1112
  }
1047
1113
  return result;
@@ -1054,18 +1120,15 @@ class DateRangePicker {
1054
1120
  * Updates the picker when calendar is initiated or any date has been selected.
1055
1121
  * Could be useful after running {@link #DateRangePicker+setStartDate|setStartDate} or {@link #DateRangePicker+setEndDate|setRange}
1056
1122
  * @param {boolean} monthChange - If `true` then monthView changed
1057
- * @emits "beforeRenderTimePicker.daterangepicker"
1123
+ * @emits "beforeRenderTimePicker"
1058
1124
  */
1059
1125
  updateView(monthChange) {
1060
1126
  if (this.timePicker) {
1061
1127
  this.triggerEvent(this.#events.onBeforeRenderTimePicker);
1062
1128
  this.renderTimePicker("start");
1063
1129
  this.renderTimePicker("end");
1064
- if (!this.#endDate) {
1065
- this.container.find(".calendar-time.end-time select").prop("disabled", true).addClass("disabled");
1066
- } else {
1067
- this.container.find(".calendar-time.end-time select").prop("disabled", false).removeClass("disabled");
1068
- }
1130
+ this.container.querySelector(".calendar-time.end-time select").disabled = !this.#endDate;
1131
+ this.container.querySelector(".calendar-time.end-time select").classList.toggle("disabled", !this.#endDate);
1069
1132
  }
1070
1133
  this.updateLabel();
1071
1134
  this.updateMonthsInView();
@@ -1107,8 +1170,8 @@ class DateRangePicker {
1107
1170
  }
1108
1171
  /**
1109
1172
  * Updates the selected day value from calendar with selected time values
1110
- * @emits "beforeRenderCalendar.daterangepicker"
1111
- * @emits "monthViewChange.daterangepicker"
1173
+ * @emits "beforeRenderCalendar"
1174
+ * @emits "monthViewChange"
1112
1175
  * @param {boolean} monthChange - If `true` then monthView changed
1113
1176
  * @private
1114
1177
  */
@@ -1116,36 +1179,36 @@ class DateRangePicker {
1116
1179
  if (this.timePicker) {
1117
1180
  var hour, minute, second;
1118
1181
  if (this.#endDate) {
1119
- hour = parseInt(this.container.find(".start-time .hourselect").val(), 10);
1182
+ hour = parseInt(this.container.querySelector(".start-time .hourselect").value, 10);
1120
1183
  if (isNaN(hour))
1121
- hour = parseInt(this.container.find(".start-time .hourselect option:last").val(), 10);
1184
+ hour = parseInt(this.container.querySelector(".start-time .hourselect option:last-child").value, 10);
1122
1185
  minute = 0;
1123
1186
  if (this.timePickerOpts.showMinutes) {
1124
- minute = parseInt(this.container.find(".start-time .minuteselect").val(), 10);
1187
+ minute = parseInt(this.container.querySelector(".start-time .minuteselect").value, 10);
1125
1188
  if (isNaN(minute))
1126
- minute = parseInt(this.container.find(".start-time .minuteselect option:last").val(), 10);
1189
+ minute = parseInt(this.container.querySelector(".start-time .minuteselect option:last-child").value, 10);
1127
1190
  }
1128
1191
  second = 0;
1129
1192
  if (this.timePickerOpts.showSeconds) {
1130
- second = parseInt(this.container.find(".start-time .secondselect").val(), 10);
1193
+ second = parseInt(this.container.querySelector(".start-time .secondselect").value, 10);
1131
1194
  if (isNaN(second))
1132
- second = parseInt(this.container.find(".start-time .secondselect option:last").val(), 10);
1195
+ second = parseInt(this.container.querySelector(".start-time .secondselect option:last-child").value, 10);
1133
1196
  }
1134
1197
  } else {
1135
- hour = parseInt(this.container.find(".end-time .hourselect").val(), 10);
1198
+ hour = parseInt(this.container.querySelector(".end-time .hourselect").value, 10);
1136
1199
  if (isNaN(hour))
1137
- hour = parseInt(this.container.find(".end-time .hourselect option:last").val(), 10);
1200
+ hour = parseInt(this.container.querySelector(".end-time .hourselect option:last-child").value, 10);
1138
1201
  minute = 0;
1139
1202
  if (this.timePickerOpts.showMinutes) {
1140
- minute = parseInt(this.container.find(".end-time .minuteselect").val(), 10);
1203
+ minute = parseInt(this.container.querySelector(".end-time .minuteselect").value, 10);
1141
1204
  if (isNaN(minute))
1142
- minute = parseInt(this.container.find(".end-time .minuteselect option:last").val(), 10);
1205
+ minute = parseInt(this.container.querySelector(".end-time .minuteselect option:last-child").value, 10);
1143
1206
  }
1144
1207
  second = 0;
1145
1208
  if (this.timePickerOpts.showSeconds) {
1146
- second = parseInt(this.container.find(".end-time .secondselect").val(), 10);
1209
+ second = parseInt(this.container.querySelector(".end-time .secondselect").value, 10);
1147
1210
  if (isNaN(second))
1148
- second = parseInt(this.container.find(".end-time .secondselect option:last").val(), 10);
1211
+ second = parseInt(this.container.querySelector(".end-time .secondselect option:last-child").value, 10);
1149
1212
  }
1150
1213
  }
1151
1214
  this.leftCalendar.month = this.leftCalendar.month.set({ hour, minute, second });
@@ -1160,12 +1223,10 @@ class DateRangePicker {
1160
1223
  this.renderCalendar("left");
1161
1224
  this.renderCalendar("right");
1162
1225
  if (monthChange)
1163
- this.triggerEvent(
1164
- this.#events.onMonthViewChange,
1165
- this.leftCalendar.month,
1166
- this.singleMonthView || this.singleDatePicker ? null : this.rightCalendar.month
1167
- );
1168
- this.container.find(".ranges li").removeClass("active");
1226
+ this.triggerEvent(this.#events.onMonthViewChange);
1227
+ this.container.querySelectorAll(".ranges li").forEach((el) => {
1228
+ el.classList.remove("active");
1229
+ });
1169
1230
  if (this.#endDate == null) return;
1170
1231
  this.calculateChosenLabel();
1171
1232
  }
@@ -1252,7 +1313,7 @@ class DateRangePicker {
1252
1313
  }
1253
1314
  ;
1254
1315
  html += "</tr>";
1255
- this.container.find(".drp-calendar." + side + " .calendar-table thead").html(html);
1316
+ this.container.querySelector(`.drp-calendar.${side} .calendar-table thead`).innerHTML = html;
1256
1317
  html = "";
1257
1318
  if (this.#endDate == null && this.maxSpan) {
1258
1319
  var maxLimit = this.#startDate.plus(this.maxSpan).endOf("day");
@@ -1266,9 +1327,9 @@ class DateRangePicker {
1266
1327
  for (let row = 0; row < 6; row++) {
1267
1328
  html += "<tr>";
1268
1329
  if (this.showISOWeekNumbers)
1269
- html += '<td class="week">' + calendar[row][0].weekNumber + "</td>";
1330
+ html += `<td class="week">${calendar[row][0].weekNumber}</td>`;
1270
1331
  else if (this.showWeekNumbers)
1271
- html += '<td class="week">' + calendar[row][0].localWeekNumber + "</td>";
1332
+ html += `<td class="week">${calendar[row][0].localWeekNumber}</td>`;
1272
1333
  for (let col = 0; col < 7; col++) {
1273
1334
  var classes = [];
1274
1335
  if (this.todayClasses && this.todayClasses.length && calendar[row][col].hasSame(DateTime.now(), "day"))
@@ -1292,31 +1353,27 @@ class DateRangePicker {
1292
1353
  if (this.#endDate != null && calendar[row][col] > this.#startDate && calendar[row][col] < this.#endDate)
1293
1354
  classes.push("in-range");
1294
1355
  var isCustom = this.isCustomDate(calendar[row][col]);
1295
- if (isCustom !== false) {
1296
- if (typeof isCustom === "string")
1297
- classes.push(isCustom);
1298
- else
1299
- Array.prototype.push.apply(classes, isCustom);
1300
- }
1356
+ if (isCustom !== false)
1357
+ typeof isCustom === "string" ? classes.push(isCustom) : classes.push(...isCustom);
1301
1358
  if (!classes.includes("disabled"))
1302
1359
  classes.push("available");
1303
1360
  html += `<td class="${classes.join(" ")}" data-title="r${row}c${col}">${calendar[row][col].day}</td>`;
1304
1361
  }
1305
1362
  html += "</tr>";
1306
1363
  }
1307
- this.container.find(".drp-calendar." + side + " .calendar-table tbody").html(html);
1364
+ this.container.querySelector(`.drp-calendar.${side} .calendar-table tbody`).innerHTML = html;
1308
1365
  }
1309
1366
  /**
1310
1367
  * Emitted before the TimePicker is rendered.
1311
1368
  * Useful to remove any manually added elements.
1312
1369
  * @event
1313
- * @name "beforeRenderTimePicker.daterangepicker"
1370
+ * @name "beforeRenderTimePicker"
1314
1371
  * @param {DateRangePicker} this - The daterangepicker object
1315
1372
  */
1316
1373
  /**
1317
1374
  * Renders the time pickers
1318
1375
  * @private
1319
- * @emits "beforeRenderTimePicker.daterangepicker"
1376
+ * @emits "beforeRenderTimePicker"
1320
1377
  */
1321
1378
  renderTimePicker(side) {
1322
1379
  if (side === "end" && !this.#endDate) return;
@@ -1334,12 +1391,12 @@ class DateRangePicker {
1334
1391
  } else if (side === "end") {
1335
1392
  selected = this.#endDate;
1336
1393
  minDate = this.#startDate;
1337
- var timeSelector = this.container.find(".drp-calendar .calendar-time.end-time");
1338
- if (timeSelector.html() != "") {
1394
+ let timeSelector = this.container.querySelector(".drp-calendar .calendar-time.end-time");
1395
+ if (timeSelector.innerHTML != "") {
1339
1396
  selected = selected.set({
1340
- hour: !isNaN(selected.hour) ? selected.hour : timeSelector.find(".hourselect option:selected").val(),
1341
- minute: !isNaN(selected.minute) ? selected.minute : timeSelector.find(".minuteselect option:selected").val(),
1342
- second: !isNaN(selected.second) ? selected.second : timeSelector.find(".secondselect option:selected").val()
1397
+ hour: !isNaN(selected.hour) ? selected.hour : timeSelector.querySelector(".hourselect option:selected").value,
1398
+ minute: !isNaN(selected.minute) ? selected.minute : timeSelector.querySelector(".minuteselect option:selected").value,
1399
+ second: !isNaN(selected.second) ? selected.second : timeSelector.querySelector(".secondselect option:selected").value
1343
1400
  });
1344
1401
  }
1345
1402
  if (selected < this.#startDate)
@@ -1488,18 +1545,15 @@ class DateRangePicker {
1488
1545
  html += "</div>";
1489
1546
  }
1490
1547
  html += "</div></th>";
1491
- this.container.find(`.drp-calendar .calendar-time.${side}-time`).html(html);
1548
+ this.container.querySelector(`.drp-calendar .calendar-time.${side}-time`).innerHTML = html;
1492
1549
  }
1493
1550
  /**
1494
1551
  * Disable the `Apply` button if no date value is selected
1495
1552
  * @private
1496
1553
  */
1497
1554
  setApplyBtnState() {
1498
- if (this.singleDatePicker || this.#endDate && this.#startDate <= this.#endDate) {
1499
- this.container.find("button.applyBtn").prop("disabled", false);
1500
- } else {
1501
- this.container.find("button.applyBtn").prop("disabled", true);
1502
- }
1555
+ const state = this.singleDatePicker || this.#endDate && this.#startDate <= this.#endDate;
1556
+ this.container.querySelector("button.applyBtn").disabled = !state;
1503
1557
  }
1504
1558
  /* #endregion */
1505
1559
  /* #region Move/Show/Hide */
@@ -1508,115 +1562,102 @@ class DateRangePicker {
1508
1562
  * @private
1509
1563
  */
1510
1564
  move() {
1511
- var parentOffset = { top: 0, left: 0 }, containerTop, drops = this.drops;
1512
- var parentRightEdge = $(window).width();
1513
- if (!this.parentEl.is("body")) {
1565
+ let parentOffset = { top: 0, left: 0 };
1566
+ let containerTop;
1567
+ let containerLeft;
1568
+ let drops = this.drops;
1569
+ let parentRightEdge = window.innerWidth;
1570
+ if (!this.parentEl.matches("body")) {
1514
1571
  parentOffset = {
1515
- top: this.parentEl.offset().top - this.parentEl.scrollTop(),
1516
- left: this.parentEl.offset().left - this.parentEl.scrollLeft()
1572
+ top: offset(this.parentEl).top - this.parentEl.scrollTop(),
1573
+ left: offset(this.parentEl).left - this.parentEl.scrollLeft()
1517
1574
  };
1518
- parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;
1575
+ parentRightEdge = this.parentEl[0].clientWidth + offset(this.parentEl).left;
1519
1576
  }
1520
- switch (drops) {
1577
+ switch (this.drops) {
1521
1578
  case "auto":
1522
- containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
1523
- if (containerTop + this.container.outerHeight() >= this.parentEl[0].scrollHeight) {
1524
- containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
1579
+ containerTop = offset(this.element).top + outerHeight(this.element) - parentOffset.top;
1580
+ if (containerTop + outerHeight(this.container) >= this.parentEl.scrollHeight) {
1581
+ containerTop = offset(this.element).top - outerHeight(this.container) - parentOffset.top;
1525
1582
  drops = "up";
1526
1583
  }
1527
1584
  break;
1528
1585
  case "up":
1529
- containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
1586
+ containerTop = offset(this.element).top - outerHeight(this.container) - parentOffset.top;
1587
+ break;
1588
+ case "down":
1589
+ containerTop = offset(this.element).top + outerHeight(this.element) - parentOffset.top;
1530
1590
  break;
1531
1591
  default:
1532
- containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
1592
+ console.error(`Option drops '${drops}' not defined`);
1533
1593
  break;
1534
1594
  }
1535
- this.container.css({
1536
- top: 0,
1537
- left: 0,
1538
- right: "auto"
1539
- });
1540
- var containerWidth = this.container.outerWidth();
1541
- this.container.toggleClass("drop-up", drops === "up");
1542
- if (this.opens === "left") {
1543
- var containerRight = parentRightEdge - this.element.offset().left - this.element.outerWidth();
1544
- if (containerWidth + containerRight > $(window).width()) {
1545
- this.container.css({
1546
- top: containerTop,
1547
- right: "auto",
1548
- left: 9
1549
- });
1550
- } else {
1551
- this.container.css({
1552
- top: containerTop,
1553
- right: containerRight,
1554
- left: "auto"
1555
- });
1556
- }
1557
- } else if (this.opens === "center") {
1558
- var containerLeft = this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2 - containerWidth / 2;
1559
- if (containerLeft < 0) {
1560
- this.container.css({
1561
- top: containerTop,
1562
- right: "auto",
1563
- left: 9
1564
- });
1565
- } else if (containerLeft + containerWidth > $(window).width()) {
1566
- this.container.css({
1567
- top: containerTop,
1568
- left: "auto",
1569
- right: 0
1570
- });
1571
- } else {
1572
- this.container.css({
1573
- top: containerTop,
1574
- left: containerLeft,
1575
- right: "auto"
1576
- });
1577
- }
1578
- } else {
1579
- var containerLeft = this.element.offset().left - parentOffset.left;
1580
- if (containerLeft + containerWidth > $(window).width()) {
1581
- this.container.css({
1582
- top: containerTop,
1583
- left: "auto",
1584
- right: 0
1585
- });
1586
- } else {
1587
- this.container.css({
1588
- top: containerTop,
1589
- left: containerLeft,
1590
- right: "auto"
1591
- });
1592
- }
1595
+ for (const [key2, value] of Object.entries({ top: 0, left: 0, right: "auto" }))
1596
+ this.container.style[key2] = typeof value === "number" && value > 0 ? `${value}px` : value;
1597
+ const containerWidth = outerWidth(this.container);
1598
+ this.container.classList.toggle("drop-up", drops === "up");
1599
+ switch (this.opens) {
1600
+ case "left":
1601
+ const containerRight = parentRightEdge - offset(this.element).left - outerWidth(this.element);
1602
+ if (containerWidth + containerRight > window.innerWidth) {
1603
+ for (const [key2, value] of Object.entries({ top: containerTop, right: "auto", left: 9 }))
1604
+ this.container.style[key2] = typeof value === "number" && value > 0 ? `${value}px` : value;
1605
+ } else {
1606
+ for (const [key2, value] of Object.entries({ top: containerTop, right: containerRight, left: "auto" }))
1607
+ this.container.style[key2] = typeof value === "number" && value > 0 ? `${value}px` : value;
1608
+ }
1609
+ break;
1610
+ case "center":
1611
+ containerLeft = offset(this.element).left - parentOffset.left + outerWidth(this.element) / 2 - containerWidth / 2;
1612
+ if (containerLeft < 0) {
1613
+ for (const [key2, value] of Object.entries({ top: containerTop, right: "auto", left: 9 }))
1614
+ this.container.style[key2] = typeof value === "number" && value > 0 ? `${value}px` : value;
1615
+ } else if (containerLeft + containerWidth > window.innerWidth) {
1616
+ for (const [key2, value] of Object.entries({ top: containerTop, left: "auto", right: 0 }))
1617
+ this.container.style[key2] = typeof value === "number" && value > 0 ? `${value}px` : value;
1618
+ } else {
1619
+ for (const [key2, value] of Object.entries({ top: containerTop, left: containerLeft, right: "auto" }))
1620
+ this.container.style[key2] = typeof value === "number" && value > 0 ? `${value}px` : value;
1621
+ }
1622
+ break;
1623
+ case "right":
1624
+ containerLeft = offset(this.element).left - parentOffset.left;
1625
+ if (containerLeft + containerWidth > window.innerWidth) {
1626
+ for (const [key2, value] of Object.entries({ top: containerTop, left: "auto", right: 0 }))
1627
+ this.container.style[key2] = typeof value === "number" && value > 0 ? `${value}px` : value;
1628
+ } else {
1629
+ for (const [key2, value] of Object.entries({ top: `${containerTop}px`, left: containerLeft, right: "auto" }))
1630
+ this.container.style[key2] = typeof value === "number" && value > 0 ? `${value}px` : value;
1631
+ }
1632
+ break;
1633
+ default:
1634
+ console.error(`Option opens '${this.opens}' not defined`);
1635
+ break;
1593
1636
  }
1594
1637
  }
1595
1638
  /**
1596
1639
  * Shows the picker
1597
- * @emits "show.daterangepicker"
1640
+ * @emits "show"
1598
1641
  */
1599
1642
  show() {
1600
1643
  if (this.isShowing) return;
1601
- this._outsideClickProxy = function(e) {
1602
- this.outsideClick(e);
1603
- }.bind(this);
1604
- $(document).on("mousedown.daterangepicker", this._outsideClickProxy).on("touchend.daterangepicker", this._outsideClickProxy).on("click.daterangepicker", "[data-toggle=dropdown]", this._outsideClickProxy).on("focusin.daterangepicker", this._outsideClickProxy);
1605
- $(window).on("resize.daterangepicker", function(e) {
1606
- this.move(e);
1607
- }.bind(this));
1644
+ document.addEventListener("mousedown", this.#outsideClickProxy);
1645
+ document.addEventListener("touchend", this.#outsideClickProxy);
1646
+ document.addEventListener("click", this.#dropdownClickWrapper);
1647
+ document.addEventListener("focusin", this.#outsideClickProxy);
1648
+ window.addEventListener("resize", this.#onResizeProxy);
1608
1649
  this.oldStartDate = this.#startDate;
1609
1650
  this.oldEndDate = this.#endDate;
1610
1651
  this.updateView(false);
1611
- this.container.show();
1652
+ this.container.style.display = "block";
1612
1653
  this.move();
1613
1654
  this.triggerEvent(this.#events.onShow);
1614
1655
  this.isShowing = true;
1615
1656
  }
1616
1657
  /**
1617
1658
  * Hides the picker
1618
- * @emits "beforeHide.daterangepicker"
1619
- * @emits "hide.daterangepicker"
1659
+ * @emits "beforeHide"
1660
+ * @emits "hide"
1620
1661
  */
1621
1662
  hide() {
1622
1663
  if (!this.isShowing) return;
@@ -1627,11 +1668,15 @@ class DateRangePicker {
1627
1668
  if (!this.#startDate.equals(this.oldStartDate) || !this.#endDate.equals(this.oldEndDate))
1628
1669
  this.callback(this.startDate, this.endDate, this.chosenLabel);
1629
1670
  this.updateElement();
1630
- if (this.triggerHandler(this.#events.onBeforeHide))
1671
+ const event = this.triggerEvent(this.#events.onBeforeHide);
1672
+ if (event.defaultPrevented)
1631
1673
  return;
1632
- $(document).off(".daterangepicker");
1633
- $(window).off(".daterangepicker");
1634
- this.container.hide();
1674
+ document.removeEventListener("mousedown", this.#outsideClickProxy);
1675
+ document.removeEventListener("touchend", this.#outsideClickProxy);
1676
+ document.removeEventListener("focusin", this.#outsideClickProxy);
1677
+ document.removeEventListener("click", this.#dropdownClickWrapper);
1678
+ window.removeEventListener("resize", this.#onResizeProxy);
1679
+ this.container.style.display = "none";
1635
1680
  this.triggerEvent(this.#events.onHide);
1636
1681
  this.isShowing = false;
1637
1682
  }
@@ -1647,34 +1692,43 @@ class DateRangePicker {
1647
1692
  }
1648
1693
  /**
1649
1694
  * Shows calendar when user selects "Custom Ranges"
1650
- * @emits "showCalendar.daterangepicker"
1695
+ * @emits "showCalendar"
1651
1696
  */
1652
1697
  showCalendars() {
1653
- this.container.addClass("show-calendar");
1698
+ this.container.classList.add("show-calendar");
1654
1699
  this.move();
1655
1700
  this.triggerEvent(this.#events.onShowCalendar);
1656
1701
  }
1657
1702
  /**
1658
1703
  * Hides calendar when user selects a predefined range
1659
- * @emits "hideCalendar.daterangepicker"
1704
+ * @emits "hideCalendar"
1660
1705
  */
1661
1706
  hideCalendars() {
1662
- this.container.removeClass("show-calendar");
1707
+ this.container.classList.remove("show-calendar");
1663
1708
  this.triggerEvent(this.#events.onHideCalendar);
1664
1709
  }
1665
1710
  /* #endregion */
1666
1711
  /* #region Handle mouse related events */
1667
1712
  /**
1668
1713
  * Closes the picker when user clicks outside
1669
- * @param {external:jQuery} e - The Event target
1670
- * @emits "outsideClick.daterangepicker"
1714
+ * @param {external:Event} e - The Event target
1715
+ * @emits "outsideClick"
1671
1716
  * @private
1672
1717
  */
1673
1718
  outsideClick(e) {
1674
- var target = $(e.target);
1719
+ const target = e.target;
1720
+ function closest2(el, selector) {
1721
+ let parent = el.parentElement;
1722
+ while (parent) {
1723
+ if (parent == selector)
1724
+ return parent;
1725
+ parent = parent.parentElement;
1726
+ }
1727
+ return null;
1728
+ }
1675
1729
  if (
1676
1730
  // ie modal dialog fix
1677
- e.type === "focusin" || target.closest(this.element).length || target.closest(this.container).length || target.closest(".calendar-table").length
1731
+ e.type === "focusin" || closest2(target, this.element) || closest2(target, this.container) || target.closest(".calendar-table")
1678
1732
  ) return;
1679
1733
  if (this.onOutsideClick === "cancel") {
1680
1734
  this.#startDate = this.oldStartDate;
@@ -1685,12 +1739,12 @@ class DateRangePicker {
1685
1739
  }
1686
1740
  /**
1687
1741
  * Move calendar to previous month
1688
- * @param {external:jQuery} e - The Event target
1742
+ * @param {external:Event} e - The Event target
1689
1743
  * @private
1690
1744
  */
1691
1745
  clickPrev(e) {
1692
- var cal = $(e.target).parents(".drp-calendar");
1693
- if (cal.hasClass("left")) {
1746
+ let cal = e.target.closest(".drp-calendar");
1747
+ if (cal.classList.contains("left")) {
1694
1748
  this.leftCalendar.month = this.leftCalendar.month.minus({ month: 1 });
1695
1749
  if (this.linkedCalendars && !this.singleMonthView)
1696
1750
  this.rightCalendar.month = this.rightCalendar.month.minus({ month: 1 });
@@ -1701,12 +1755,12 @@ class DateRangePicker {
1701
1755
  }
1702
1756
  /**
1703
1757
  * Move calendar to next month
1704
- * @param {external:jQuery} e - The Event target
1758
+ * @param {external:Event} e - The Event target
1705
1759
  * @private
1706
1760
  */
1707
1761
  clickNext(e) {
1708
- var cal = $(e.target).parents(".drp-calendar");
1709
- if (cal.hasClass("left")) {
1762
+ let cal = e.target.closest(".drp-calendar");
1763
+ if (cal.classList.contains("left")) {
1710
1764
  this.leftCalendar.month = this.leftCalendar.month.plus({ month: 1 });
1711
1765
  } else {
1712
1766
  this.rightCalendar.month = this.rightCalendar.month.plus({ month: 1 });
@@ -1717,108 +1771,88 @@ class DateRangePicker {
1717
1771
  }
1718
1772
  /**
1719
1773
  * User hovers over date values
1720
- * @param {external:jQuery} e - The Event target
1774
+ * @param {external:Event} e - The Event target
1721
1775
  * @private
1722
1776
  */
1723
1777
  hoverDate(e) {
1724
- if (!$(e.target).hasClass("available")) return;
1725
- let title = $(e.target).attr("data-title");
1778
+ if (!e.target.classList.contains("available")) return;
1779
+ let title = e.target.dataset.title;
1726
1780
  const row = title.substring(1, 2);
1727
1781
  const col = title.substring(3, 4);
1728
- const cal = $(e.target).parents(".drp-calendar");
1729
- var date = cal.hasClass("left") ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1782
+ const cal = e.target(closest, ".drp-calendar");
1783
+ var date = cal.classList.contains("left") ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1730
1784
  const leftCalendar = this.leftCalendar;
1731
1785
  const rightCalendar = this.rightCalendar;
1732
1786
  const startDate = this.#startDate;
1733
1787
  const initalMonth = this.initalMonth;
1734
1788
  if (!this.#endDate) {
1735
- this.container.find(".drp-calendar tbody td").each(function(index, el) {
1736
- if ($(el).hasClass("week")) return;
1737
- const title2 = $(el).attr("data-title");
1789
+ this.container.querySelectorAll(".drp-calendar tbody td").forEach((el) => {
1790
+ if (el.classList.contains("week")) return;
1791
+ const title2 = el.dataset.title;
1738
1792
  const row2 = title2.substring(1, 2);
1739
1793
  const col2 = title2.substring(3, 4);
1740
- const cal2 = $(el).parents(".drp-calendar");
1741
- const dt = cal2.hasClass("left") ? leftCalendar.calendar[row2][col2] : rightCalendar.calendar[row2][col2];
1794
+ const cal2 = el.closest(".drp-calendar");
1795
+ const dt = cal2.classList.contains("left") ? leftCalendar.calendar[row2][col2] : rightCalendar.calendar[row2][col2];
1742
1796
  if (!startDate && initalMonth) {
1743
- $(el).removeClass("in-range");
1797
+ el.classList.remove("in-range");
1744
1798
  } else {
1745
- if (dt > startDate && dt < date || dt.hasSame(date, "day")) {
1746
- $(el).addClass("in-range");
1747
- } else {
1748
- $(el).removeClass("in-range");
1749
- }
1799
+ el.classList.toggle("in-range", dt > startDate && dt < date || dt.hasSame(date, "day"));
1750
1800
  }
1751
1801
  });
1752
1802
  }
1753
1803
  }
1754
1804
  /**
1755
1805
  * User hovers over ranges
1756
- * @param {external:jQuery} e - The Event target
1806
+ * @param {external:Event} e - The Event target
1757
1807
  * @private
1758
1808
  */
1759
1809
  hoverRange(e) {
1760
- const label = e.target.getAttribute("data-range-key");
1810
+ const label = e.target.dataset.rangeKey;
1761
1811
  const previousDates = [this.#startDate, this.#endDate];
1762
1812
  const dates = this.ranges[label] ?? [this.#startDate, this.#endDate];
1763
1813
  const leftCalendar = this.leftCalendar;
1764
1814
  const rightCalendar = this.rightCalendar;
1765
- this.container.find(".drp-calendar tbody td").each(function(index, el) {
1766
- if ($(el).hasClass("week")) return;
1767
- const title = $(el).attr("data-title");
1815
+ this.container.querySelectorAll(".drp-calendar tbody td").forEach((el) => {
1816
+ if (el.classList.contains("week")) return;
1817
+ const title = el.dataset.ttitle;
1768
1818
  const row = title.substring(1, 2);
1769
1819
  const col = title.substring(3, 4);
1770
- const cal = $(el).parents(".drp-calendar");
1771
- const dt = cal.hasClass("left") ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
1772
- let classAdded = false;
1773
- if (dt.hasSame(dates[0], "day"))
1774
- classAdded = $(el).addClass("start-hover").length > 0;
1775
- if (dt.hasSame(previousDates[0], "day"))
1776
- classAdded = $(el).addClass("start-date").length > 0;
1777
- if (dt.hasSame(dates[1], "day"))
1778
- classAdded = $(el).addClass("end-hover").length > 0;
1779
- if (previousDates[1] != null && dt.hasSame(previousDates[1], "day"))
1780
- classAdded = $(el).addClass("end-date").length > 0;
1781
- if (dt.startOf("day") >= dates[0].startOf("day") && dt.startOf("day") <= dates[1].startOf("day"))
1782
- classAdded = $(el).addClass("range-hover").length > 0;
1783
- if (dt.startOf("day") >= previousDates[0].startOf("day") && previousDates[1] != null && dt.startOf("day") <= previousDates[1].startOf("day"))
1784
- classAdded = $(el).addClass("in-range").length > 0;
1785
- if (!classAdded) {
1786
- $(el).removeClass("start-hover");
1787
- $(el).removeClass("end-hover");
1788
- $(el).removeClass("start-date");
1789
- $(el).removeClass("end-date");
1790
- $(el).removeClass("in-range");
1791
- $(el).removeClass("range-hover");
1792
- }
1820
+ const cal = el.closest(".drp-calendar");
1821
+ const dt = cal.classList.contains("left") ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
1822
+ el.classList.toggle("start-hover", dt.hasSame(dates[0], "day"));
1823
+ el.classList.toggle("start-date", dt.hasSame(previousDates[0], "day"));
1824
+ el.classList.toggle("end-hover", dt.hasSame(dates[1], "day"));
1825
+ el.classList.toggle("end-date", previousDates[1] != null && dt.hasSame(previousDates[1], "day"));
1826
+ el.classList.toggle("range-hover", dt.startOf("day") >= dates[0].startOf("day") && dt.startOf("day") <= dates[1].startOf("day"));
1827
+ el.classList.toggle("in-range", dt.startOf("day") >= previousDates[0].startOf("day") && previousDates[1] != null && dt.startOf("day") <= previousDates[1].startOf("day"));
1793
1828
  });
1794
1829
  }
1795
1830
  /**
1796
1831
  * User leave ranges, remove hightlight from dates
1797
- * @param {external:jQuery} e - The Event target
1798
1832
  * @private
1799
1833
  */
1800
- leaveRange(e) {
1801
- this.container.find(".drp-calendar tbody td").each(function(index, el) {
1802
- if ($(el).hasClass("week")) return;
1803
- $(el).removeClass("start-hover");
1804
- $(el).removeClass("end-hover");
1805
- $(el).removeClass("range-hover");
1834
+ leaveRange() {
1835
+ this.container.querySelectorAll(".drp-calendar tbody td").forEach((el) => {
1836
+ if (el.classList.contains("week")) return;
1837
+ el.classList.remove("start-hover");
1838
+ el.classList.remove("end-hover");
1839
+ el.classList.remove("range-hover");
1806
1840
  });
1807
1841
  }
1808
1842
  /* #endregion */
1809
1843
  /* #region Select values by Mouse */
1810
1844
  /**
1811
1845
  * Set date values after user selected a date
1812
- * @param {external:jQuery} e - The Event target
1846
+ * @param {external:Event} e - The Event target
1813
1847
  * @private
1814
1848
  */
1815
1849
  clickRange(e) {
1816
- var label = e.target.getAttribute("data-range-key");
1850
+ let label = e.target.getAttribute("data-range-key");
1817
1851
  this.chosenLabel = label;
1818
1852
  if (label == this.locale.customRangeLabel) {
1819
1853
  this.showCalendars();
1820
1854
  } else {
1821
- var newDate = this.ranges[label];
1855
+ let newDate = this.ranges[label];
1822
1856
  const monthChange = !this.#startDate.hasSame(newDate[0], "month") || !this.#endDate.hasSame(newDate[1], "month");
1823
1857
  this.#startDate = newDate[0];
1824
1858
  this.#endDate = newDate[1];
@@ -1828,41 +1862,42 @@ class DateRangePicker {
1828
1862
  }
1829
1863
  if (!this.alwaysShowCalendars)
1830
1864
  this.hideCalendars();
1831
- if (this.triggerHandler(this.#events.onBeforeHide))
1865
+ const event = this.triggerEvent(this.#events.onBeforeHide);
1866
+ if (event.defaultPrevented)
1832
1867
  this.updateView(monthChange);
1833
1868
  this.clickApply();
1834
1869
  }
1835
1870
  }
1836
1871
  /**
1837
1872
  * User clicked a date
1838
- * @param {external:jQuery} e - The Event target
1839
- * @emits "dateChange.daterangepicker"
1873
+ * @param {external:Event} e - The Event target
1874
+ * @emits "dateChange"
1840
1875
  * @private
1841
1876
  */
1842
1877
  clickDate(e) {
1843
- if (!$(e.target).hasClass("available")) return;
1844
- var title = $(e.target).attr("data-title");
1845
- var row = title.substring(1, 2);
1846
- var col = title.substring(3, 4);
1847
- var cal = $(e.target).parents(".drp-calendar");
1848
- var date = cal.hasClass("left") ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1878
+ if (!e.target.classList.contains("available")) return;
1879
+ let title = e.target.dataset.title;
1880
+ let row = title.substring(1, 2);
1881
+ let col = title.substring(3, 4);
1882
+ let cal = e.target.closest(".drp-calendar");
1883
+ let date = cal.classList.contains("left") ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1849
1884
  let side;
1850
1885
  if (this.#endDate || !this.#startDate || date < this.#startDate.startOf("day")) {
1851
1886
  if (this.timePicker) {
1852
- let hour = parseInt(this.container.find(".start-time .hourselect").val(), 10);
1887
+ let hour = parseInt(this.container.querySelector(".start-time .hourselect").value, 10);
1853
1888
  if (isNaN(hour))
1854
- hour = parseInt(this.container.find(".start-time .hourselect option:last").val(), 10);
1889
+ hour = parseInt(this.container.querySelector(".start-time .hourselect option:last-child").value, 10);
1855
1890
  let minute = 0;
1856
1891
  if (this.timePickerOpts.showMinutes) {
1857
- minute = parseInt(this.container.find(".start-time .minuteselect").val(), 10);
1892
+ minute = parseInt(this.container.querySelector(".start-time .minuteselect").value, 10);
1858
1893
  if (isNaN(minute))
1859
- minute = parseInt(this.container.find(".start-time .minuteselect option:last").val(), 10);
1894
+ minute = parseInt(this.container.querySelector(".start-time .minuteselect option:last-child").value, 10);
1860
1895
  }
1861
1896
  let second = 0;
1862
1897
  if (this.timePickerOpts.showSeconds) {
1863
- second = parseInt(this.container.find(".start-time .secondselect").val(), 10);
1898
+ second = parseInt(this.container.querySelector(".start-time .secondselect").value, 10);
1864
1899
  if (isNaN(second))
1865
- second = parseInt(this.container.find(".start-time .secondselect option:last").val(), 10);
1900
+ second = parseInt(this.container.querySelector(".start-time .secondselect option:last-child").value, 10);
1866
1901
  }
1867
1902
  date = date.set({ hour, minute, second });
1868
1903
  } else {
@@ -1876,20 +1911,20 @@ class DateRangePicker {
1876
1911
  side = "end";
1877
1912
  } else {
1878
1913
  if (this.timePicker) {
1879
- let hour = parseInt(this.container.find(".end-time .hourselect").val(), 10);
1914
+ let hour = parseInt(this.container.querySelector(".end-time .hourselect").value, 10);
1880
1915
  if (isNaN(hour))
1881
- hour = parseInt(this.container.find(".end-time .hourselect option:last").val(), 10);
1916
+ hour = parseInt(this.container.querySelector(".end-time .hourselect option:last-child").value, 10);
1882
1917
  let minute = 0;
1883
1918
  if (this.timePickerOpts.showMinutes) {
1884
- minute = parseInt(this.container.find(".end-time .minuteselect").val(), 10);
1919
+ minute = parseInt(this.container.querySelector(".end-time .minuteselect").value, 10);
1885
1920
  if (isNaN(minute))
1886
- minute = parseInt(this.container.find(".end-time .minuteselect option:last").val(), 10);
1921
+ minute = parseInt(this.container.querySelector(".end-time .minuteselect option:last-child").value, 10);
1887
1922
  }
1888
1923
  let second = 0;
1889
1924
  if (this.timePickerOpts.showSeconds) {
1890
- second = parseInt(this.container.find(".end-time .secondselect").val(), 10);
1925
+ second = parseInt(this.container.querySelector(".end-time .secondselect").value, 10);
1891
1926
  if (isNaN(second))
1892
- second = parseInt(this.container.find(".end-time .secondselect option:last").val(), 10);
1927
+ second = parseInt(this.container.querySelector(".end-time .secondselect option:last-child").value, 10);
1893
1928
  }
1894
1929
  date = date.set({ hour, minute, second });
1895
1930
  } else {
@@ -1912,13 +1947,15 @@ class DateRangePicker {
1912
1947
  e.stopPropagation();
1913
1948
  if (this.autoUpdateInput)
1914
1949
  this.updateElement();
1915
- this.triggerEvent(this.#events.onDateChange, side);
1950
+ this.triggerEvent(this.#events.onDateChange, { side });
1916
1951
  }
1917
1952
  /**
1918
1953
  * Hightlight selected predefined range in calendar
1919
1954
  * @private
1920
1955
  */
1921
1956
  calculateChosenLabel() {
1957
+ if (Object.keys(this.ranges).length === 0)
1958
+ return;
1922
1959
  var customRange = true;
1923
1960
  var i = 0;
1924
1961
  for (var range in this.ranges) {
@@ -1932,14 +1969,18 @@ class DateRangePicker {
1932
1969
  }
1933
1970
  if (this.#startDate.startOf(unit).equals(this.ranges[range][0].startOf(unit)) && this.#endDate.startOf(unit).equals(this.ranges[range][1].startOf(unit))) {
1934
1971
  customRange = false;
1935
- this.chosenLabel = this.container.find(".ranges li:eq(" + i + ")").addClass("active").attr("data-range-key");
1972
+ const range2 = this.container.querySelector(`.ranges li:eq(${i})`);
1973
+ this.chosenLabel = range2.dataset.rangeKey;
1974
+ range2.classList.add("active");
1936
1975
  break;
1937
1976
  }
1938
1977
  i++;
1939
1978
  }
1940
1979
  if (customRange) {
1941
1980
  if (this.showCustomRangeLabel) {
1942
- this.chosenLabel = this.container.find(".ranges li:last").addClass("active").attr("data-range-key");
1981
+ const range2 = this.container.querySelector(".ranges li:last-child");
1982
+ this.chosenLabel = range2.dataset.rangeKey;
1983
+ range2.classList.add("active");
1943
1984
  } else {
1944
1985
  this.chosenLabel = null;
1945
1986
  }
@@ -1948,25 +1989,23 @@ class DateRangePicker {
1948
1989
  }
1949
1990
  /**
1950
1991
  * User clicked a time
1951
- * @param {external:jQuery} e - The Event target
1952
- * @emits "timeChange.daterangepicker"
1992
+ * @param {external:Event} e - The Event target
1993
+ * @emits "timeChange"
1953
1994
  * @private
1954
1995
  */
1955
1996
  timeChanged(e) {
1956
- const time = $(e.target).closest(".calendar-time");
1957
- ;
1958
- const side = time.hasClass("start-time") ? "start" : "end";
1959
- var hour = parseInt(time.find(".hourselect").val(), 10);
1997
+ const time = e.target.closest(".calendar-time");
1998
+ const side = time.classList.contains("start-time") ? "start" : "end";
1999
+ var hour = parseInt(time.querySelector(".hourselect").value, 10);
1960
2000
  if (isNaN(hour))
1961
- hour = parseInt(time.find(".hourselect option:last").val(), 10);
2001
+ hour = parseInt(time.querySelector(".hourselect option:last-child").value, 10);
1962
2002
  if (!this.timePicker24Hour) {
1963
- const ampm = time.find(".ampmselect").val();
2003
+ const ampm = time.querySelector(".ampmselect").value;
1964
2004
  if (ampm == null)
1965
- time.find(".ampmselect option:last").val();
2005
+ time.querySelector(".ampmselect option:last-child").value;
1966
2006
  if (ampm != DateTime.fromFormat(`${hour}`, "H").toFormat("a", { locale: "en-US" })) {
1967
- time.find(".hourselect > option").each(function() {
1968
- const hidden = $(this).attr("hidden") || false;
1969
- $(this).attr("hidden", hidden);
2007
+ time.querySelectorAll(".hourselect > option").forEach((el) => {
2008
+ el.hidden = !el.hidden;
1970
2009
  });
1971
2010
  const h = DateTime.fromFormat(`${hour}`, "H").toFormat("h");
1972
2011
  hour = DateTime.fromFormat(`${h}${ampm}`, "ha", { locale: "en-US" }).hour;
@@ -1974,15 +2013,15 @@ class DateRangePicker {
1974
2013
  }
1975
2014
  var minute = 0;
1976
2015
  if (this.timePickerOpts.showMinutes) {
1977
- minute = parseInt(time.find(".minuteselect").val(), 10);
2016
+ minute = parseInt(time.querySelector(".minuteselect").value, 10);
1978
2017
  if (isNaN(minute))
1979
- minute = parseInt(time.find(".minuteselect option:last").val(), 10);
2018
+ minute = parseInt(time.querySelector(".minuteselect option:last-child").value, 10);
1980
2019
  }
1981
2020
  var second = 0;
1982
2021
  if (this.timePickerOpts.showSeconds) {
1983
- second = parseInt(time.find(".secondselect").val(), 10);
2022
+ second = parseInt(time.querySelector(".secondselect").value, 10);
1984
2023
  if (isNaN(second))
1985
- second = parseInt(time.find(".secondselect option:last").val(), 10);
2024
+ second = parseInt(time.querySelector(".secondselect option:last-child").value, 10);
1986
2025
  }
1987
2026
  if (side === "start") {
1988
2027
  if (this.#startDate)
@@ -2002,17 +2041,19 @@ class DateRangePicker {
2002
2041
  this.renderTimePicker("end");
2003
2042
  if (this.autoUpdateInput)
2004
2043
  this.updateElement();
2005
- this.triggerEvent(this.#events.onTimeChange, this.singleDatePicker ? null : side);
2044
+ this.triggerEvent(this.#events.onTimeChange, { side: this.singleDatePicker ? null : side });
2006
2045
  }
2007
2046
  /**
2008
2047
  * Calender month moved
2009
- * @param {external:jQuery} e - The Event target
2048
+ * @param {external:Event} e - The Event target
2010
2049
  * @private
2011
2050
  */
2012
2051
  monthOrYearChanged(e) {
2013
- var isLeft = $(e.target).closest(".drp-calendar").hasClass("left"), leftOrRight = isLeft ? "left" : "right", cal = this.container.find(".drp-calendar." + leftOrRight);
2014
- var month = parseInt(cal.find(".monthselect").val(), 10);
2015
- var year = cal.find(".yearselect").val();
2052
+ const isLeft = e.target.closest(".drp-calendar").classList.contains("left");
2053
+ const leftOrRight = isLeft ? "left" : "right";
2054
+ const cal = this.container.querySelector(`.drp-calendar.${leftOrRight}`);
2055
+ let month = parseInt(cal.querySelector(".monthselect").value, 10);
2056
+ let year = cal.querySelector(".yearselect").value;
2016
2057
  let monthChange = false;
2017
2058
  if (!isLeft) {
2018
2059
  if (year < this.#startDate.year || year == this.#startDate.year && month < this.#startDate.month) {
@@ -2047,7 +2088,7 @@ class DateRangePicker {
2047
2088
  }
2048
2089
  /**
2049
2090
  * User clicked `Apply` button
2050
- * @emits "apply.daterangepicker"
2091
+ * @emits "apply"
2051
2092
  * @private
2052
2093
  */
2053
2094
  clickApply() {
@@ -2056,7 +2097,7 @@ class DateRangePicker {
2056
2097
  }
2057
2098
  /**
2058
2099
  * User clicked `Cancel` button
2059
- * @emits "cancel.daterangepicker"
2100
+ * @emits "cancel"
2060
2101
  * @private
2061
2102
  */
2062
2103
  clickCancel() {
@@ -2068,18 +2109,18 @@ class DateRangePicker {
2068
2109
  /* #endregion */
2069
2110
  /**
2070
2111
  * Update the picker with value from `<input>` element.<br>
2071
- * Input values must be given in format of `locale.format`. Invalid values are handles by `violated.daterangepicker` Event
2072
- * @emits "inputChange.daterangepicker"
2112
+ * Input values must be given in format of `locale.format`. Invalid values are handles by `violate` Event
2113
+ * @emits "inputChange"
2073
2114
  * @private
2074
2115
  */
2075
2116
  elementChanged() {
2076
- if (!this.element.is("input:text")) return;
2077
- if (!this.element.val().length) return;
2117
+ if (!this.isInputText) return;
2118
+ if (!this.element.value.length) return;
2078
2119
  const format = typeof this.locale.format === "string" ? this.locale.format : DateTime.parseFormatForOpts(this.locale.format);
2079
- const dateString = this.element.val().split(this.locale.separator);
2120
+ const dateString = this.element.value.split(this.locale.separator);
2080
2121
  let monthChange = false;
2081
2122
  if (this.singleDatePicker) {
2082
- let newDate = DateTime.fromFormat(this.element.val(), format, { locale: DateTime.now().locale });
2123
+ let newDate = DateTime.fromFormat(this.element.value, format, { locale: DateTime.now().locale });
2083
2124
  const oldDate = this.#startDate;
2084
2125
  if (!newDate.isValid || oldDate.equals(newDate))
2085
2126
  return;
@@ -2128,13 +2169,12 @@ class DateRangePicker {
2128
2169
  }
2129
2170
  /**
2130
2171
  * Handles key press, IE 11 compatibility
2131
- * @param {external:jQuery} e - The Event target
2172
+ * @param {external:Event} e - The Event target
2132
2173
  * @private
2133
2174
  */
2134
2175
  keydown(e) {
2135
- if (e.keyCode === 9 || e.keyCode === 13) {
2176
+ if ([9, 11].includes(e.keyCode))
2136
2177
  this.hide();
2137
- }
2138
2178
  if (e.keyCode === 27) {
2139
2179
  e.preventDefault();
2140
2180
  e.stopPropagation();
@@ -2148,7 +2188,7 @@ class DateRangePicker {
2148
2188
  updateElement() {
2149
2189
  if (this.#startDate == null && this.initalMonth)
2150
2190
  return;
2151
- if (this.element.is("input:text")) {
2191
+ if (this.isInputText) {
2152
2192
  let newValue = this.formatDate(this.#startDate);
2153
2193
  if (!this.singleDatePicker) {
2154
2194
  newValue += this.locale.separator;
@@ -2156,8 +2196,10 @@ class DateRangePicker {
2156
2196
  newValue += this.formatDate(this.#endDate);
2157
2197
  }
2158
2198
  this.updateAltInput();
2159
- if (newValue !== this.element.val())
2160
- this.element.val(newValue).trigger("change");
2199
+ if (newValue !== this.element.value) {
2200
+ this.element.value = newValue;
2201
+ this.element.dispatchEvent(new Event("change", { bubbles: true }));
2202
+ }
2161
2203
  } else {
2162
2204
  this.updateAltInput();
2163
2205
  }
@@ -2168,8 +2210,6 @@ class DateRangePicker {
2168
2210
  updateAltInput() {
2169
2211
  if (this.altInput == null)
2170
2212
  return;
2171
- if (this.singleDatePicker)
2172
- $(this.altInput[1]).val(null);
2173
2213
  if (this.altFormat == null) {
2174
2214
  let precision = "day";
2175
2215
  if (this.timePicker) {
@@ -2182,17 +2222,17 @@ class DateRangePicker {
2182
2222
  }
2183
2223
  }
2184
2224
  const startDate = this.#startDate.toISO({ format: "basic", precision, includeOffset: false });
2185
- $(this.singleDatePicker ? this.altInput : this.altInput[0]).val(startDate);
2225
+ (this.singleDatePicker ? this.altInput : this.altInput[0]).value = startDate;
2186
2226
  if (!this.singleDatePicker && this.#endDate) {
2187
2227
  const endDate = this.#endDate.toISO({ format: "basic", precision, includeOffset: false });
2188
- $(this.altInput[1]).val(endDate);
2228
+ this.altInput[1].value = endDate;
2189
2229
  }
2190
2230
  } else {
2191
2231
  const startDate = typeof this.altFormat === "function" ? this.altFormat(this.#startDate) : this.formatDate(this.#startDate, this.altFormat);
2192
- $(this.singleDatePicker ? this.altInput : this.altInput[0]).val(startDate);
2232
+ (this.singleDatePicker ? this.altInput : this.altInput[0]).value = startDate;
2193
2233
  if (!this.singleDatePicker && this.#endDate) {
2194
2234
  const endDate = typeof this.altFormat === "function" ? this.altFormat(this.#endDate) : this.formatDate(this.#endDate, this.altFormat);
2195
- $(this.altInput[1]).val(endDate);
2235
+ this.altInput[1].value = endDate;
2196
2236
  }
2197
2237
  }
2198
2238
  }
@@ -2200,52 +2240,140 @@ class DateRangePicker {
2200
2240
  * Removes the picker from document
2201
2241
  */
2202
2242
  remove() {
2243
+ this.element.removeEventListener("click", this.#showProxy);
2244
+ this.element.removeEventListener("focus", this.#showProxy);
2245
+ this.element.removeEventListener("keyup", this.#elementChangedProxy);
2246
+ this.element.removeEventListener("keydown", this.#keydownProxy);
2247
+ this.element.removeEventListener("click", this.#toggleProxy);
2248
+ this.element.removeEventListener("keydown", this.#toggleProxy);
2203
2249
  this.container.remove();
2204
- this.element.off(".daterangepicker");
2205
- this.element.removeData();
2206
2250
  }
2207
2251
  /**
2208
- * Helper function to trigger events
2252
+ * Helper function to dispatch events
2209
2253
  * @param {Event} ev - From this.#events
2210
- * @param {...any} args - Argument spread
2254
+ * @param {...any?} args - Additional parameters if needed
2211
2255
  * @private
2212
2256
  */
2213
2257
  triggerEvent(ev, ...args) {
2214
2258
  if (args.length === 0) {
2215
- this.element.trigger(ev.type, ev.param);
2259
+ const event = new DateRangePickerEvent(this, ev);
2260
+ this.element.dispatchEvent(event);
2261
+ return event;
2216
2262
  } else {
2217
- const params = ev.param(...args);
2218
- this.element.trigger(ev.type, params);
2263
+ const event = new DateRangePickerEvent(this, ev, ...args);
2264
+ this.element.dispatchEvent(event);
2265
+ return event;
2219
2266
  }
2220
2267
  }
2221
2268
  /**
2222
- * Helper function to trigger events
2223
- * @param {Event} ev - From this.#events
2224
- * @param {...any} args - Argument spread
2225
- * @private
2269
+ * Helper function to add eventListener similar to jQuery .on( events [, selector ] [, data ] )
2270
+ * @param {string} element - Query selector of element where listener is added
2271
+ * @param {string} eventName - Name of the event
2272
+ * @param {string} selector - Query selector string to filter the descendants of the element
2273
+ * @param {any} delegate - Handler data
2226
2274
  */
2227
- triggerHandler(ev, ...args) {
2228
- if (args.length === 0) {
2229
- return this.element.triggerHandler(ev.type, ev.param);
2230
- } else {
2231
- const params = ev.param(...args);
2232
- return this.element.triggerHandler(ev.type, params);
2275
+ addListener(element, eventName, selector, delegate) {
2276
+ this.container.querySelectorAll(element).forEach((el) => {
2277
+ el.addEventListener(eventName, function(event) {
2278
+ const target = event.target.closest(selector);
2279
+ if (target && el.contains(target))
2280
+ delegate.call(target, event);
2281
+ });
2282
+ });
2283
+ }
2284
+ }
2285
+ function createElementFromHTML(html) {
2286
+ const template = document.createElement("template");
2287
+ template.innerHTML = html.trim();
2288
+ return template.content.firstElementChild;
2289
+ }
2290
+ class DateRangePickerEvent extends Event {
2291
+ #picker;
2292
+ constructor(drp, ev, args = {}) {
2293
+ let param = {};
2294
+ if (ev.param)
2295
+ param = typeof ev.param === "function" ? ev.param() : ev.param;
2296
+ param = { ...param, ...args };
2297
+ super(ev.type, param);
2298
+ this.#picker = drp;
2299
+ for (const [key2, value] of Object.entries(param)) {
2300
+ if (Object.getOwnPropertyNames(Event.prototype).includes(key2)) continue;
2301
+ this[key2] = value;
2233
2302
  }
2234
2303
  }
2304
+ get picker() {
2305
+ return this.#picker;
2306
+ }
2307
+ }
2308
+ function offset(el) {
2309
+ const rect = el.getBoundingClientRect();
2310
+ return {
2311
+ top: rect.top + window.scrollY,
2312
+ left: rect.left + window.scrollX
2313
+ };
2314
+ }
2315
+ function outerWidth(el, withMargin = false) {
2316
+ if (!withMargin)
2317
+ return el.offsetWidth;
2318
+ const style = getComputedStyle(el);
2319
+ return el.offsetWidth + parseFloat(style.marginLeft) + parseFloat(style.marginRight);
2320
+ }
2321
+ function outerHeight(el, withMargin = false) {
2322
+ if (!withMargin)
2323
+ return el.offsetHeight;
2324
+ const style = getComputedStyle(el);
2325
+ return el.offsetHeight + parseFloat(style.marginTop) + parseFloat(style.marginBottom);
2326
+ }
2327
+ function daterangepicker(elements, options, callback) {
2328
+ if (typeof elements === "string")
2329
+ return daterangepicker(document.querySelectorAll(elements), options, callback);
2330
+ if (elements instanceof HTMLElement)
2331
+ elements = [elements];
2332
+ if (elements instanceof NodeList || elements instanceof HTMLCollection)
2333
+ elements = Array.from(elements);
2334
+ if (elements == null)
2335
+ return new DateRangePicker(null, options || {}, callback);
2336
+ elements.forEach((el) => {
2337
+ if (el._daterangepicker && typeof el._daterangepicker.remove === "function")
2338
+ el._daterangepicker.remove();
2339
+ el._daterangepicker = new DateRangePicker(el, options || {}, callback);
2340
+ });
2341
+ return elements.length === 1 ? elements[0] : elements;
2235
2342
  }
2236
- if (!$.fn.daterangepicker) {
2237
- $.fn.daterangepicker = function(options, callback) {
2238
- const implementOptions = $.extend(true, {}, $.fn.daterangepicker.defaultOptions, options);
2239
- this.each(function() {
2240
- const el = $(this);
2241
- if (el.data("daterangepicker"))
2242
- el.data("daterangepicker").remove();
2243
- el.data("daterangepicker", new DateRangePicker(el, implementOptions, callback));
2343
+ function getDateRangePicker(target) {
2344
+ if (typeof target === "string")
2345
+ target = document.querySelector(target);
2346
+ return target instanceof HTMLElement ? target._daterangepicker : void 0;
2347
+ }
2348
+ if (window.jQuery?.fn) {
2349
+ jQuery.fn.daterangepicker = function(options, callback) {
2350
+ return this.each(function() {
2351
+ daterangepicker(this, options, callback);
2244
2352
  });
2245
- return this;
2246
2353
  };
2247
2354
  }
2248
- var daterangepicker_default = DateRangePicker;
2355
+ function registerJqueryPlugin(jq) {
2356
+ if (!jq?.fn) return;
2357
+ jq.fn.daterangepicker = function(options, callback) {
2358
+ return this.each(function() {
2359
+ daterangepicker(this, options, callback);
2360
+ });
2361
+ };
2362
+ }
2363
+ Object.defineProperty(window, "jQuery", {
2364
+ configurable: true,
2365
+ set(value) {
2366
+ this._jQuery = value;
2367
+ registerJqueryPlugin(value);
2368
+ },
2369
+ get() {
2370
+ return this._jQuery;
2371
+ }
2372
+ });
2373
+ var daterangepicker_default = daterangepicker;
2249
2374
  export {
2250
- daterangepicker_default as default
2375
+ DateRangePicker,
2376
+ daterangepicker,
2377
+ daterangepicker_default as default,
2378
+ getDateRangePicker
2251
2379
  };