@wernfried/daterangepicker 4.0.0 → 4.16.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.
@@ -0,0 +1,2055 @@
1
+ var DateRangePicker = (() => {
2
+ const DateTime = luxon.DateTime;
3
+ const Duration = luxon.Duration;
4
+ const Info = luxon.Info;
5
+ const Settings = luxon.Settings;
6
+ class DateRangePicker {
7
+ #startDate = null;
8
+ #endDate = null;
9
+ #setRange = false;
10
+ constructor(element, options, cb) {
11
+ this.parentEl = "body";
12
+ this.element = $(element);
13
+ this.#startDate = DateTime.now().startOf("day");
14
+ this.#endDate = DateTime.now().plus({ day: 1 }).startOf("day");
15
+ this.minDate = null;
16
+ this.maxDate = null;
17
+ this.maxSpan = null;
18
+ this.minSpan = null;
19
+ this.defaultSpan = null;
20
+ this.initalMonth = DateTime.now().startOf("month");
21
+ this.autoApply = false;
22
+ this.singleDatePicker = false;
23
+ this.singleMonthView = false;
24
+ this.showDropdowns = false;
25
+ this.minYear = DateTime.now().minus({ year: 100 }).year;
26
+ this.maxYear = DateTime.now().plus({ year: 100 }).year;
27
+ this.showWeekNumbers = false;
28
+ this.showISOWeekNumbers = false;
29
+ this.showCustomRangeLabel = true;
30
+ this.showLabel = !$(this.element).is("input:text");
31
+ this.timePicker = false;
32
+ const usesMeridiems = new Intl.DateTimeFormat(DateTime.now().locale, { hour: "numeric" }).resolvedOptions();
33
+ this.timePicker24Hour = !usesMeridiems.hour12;
34
+ this.timePickerStepSize = Duration.fromObject({ minutes: 1 });
35
+ this.linkedCalendars = true;
36
+ this.autoUpdateInput = true;
37
+ this.alwaysShowCalendars = false;
38
+ this.isInvalidDate = null;
39
+ this.isInvalidTime = null;
40
+ this.isCustomDate = null;
41
+ this.onOutsideClick = "apply";
42
+ this.opens = this.element.hasClass("pull-right") ? "left" : "right";
43
+ this.drops = this.element.hasClass("dropup") ? "up" : "down";
44
+ this.buttonClasses = "btn btn-sm";
45
+ this.applyButtonClasses = "btn-primary";
46
+ this.cancelButtonClasses = "btn-default";
47
+ this.weekendClasses = "weekend";
48
+ this.weekendDayClasses = "weekend-day";
49
+ this.todayClasses = "today";
50
+ this.altInput = null;
51
+ this.altFormat = null;
52
+ this.externalStyle = null;
53
+ this.ranges = {};
54
+ this.locale = {
55
+ direction: "ltr",
56
+ format: DateTime.DATE_SHORT,
57
+ // or DateTime.DATETIME_SHORT when timePicker: true
58
+ separator: " - ",
59
+ applyLabel: "Apply",
60
+ cancelLabel: "Cancel",
61
+ weekLabel: "W",
62
+ customRangeLabel: "Custom Range",
63
+ daysOfWeek: Info.weekdays("short"),
64
+ monthNames: Info.months("long"),
65
+ firstDay: Info.getStartOfWeek(),
66
+ durationFormat: null
67
+ };
68
+ this.callback = function() {
69
+ };
70
+ this.isShowing = false;
71
+ this.leftCalendar = {};
72
+ this.rightCalendar = {};
73
+ if (typeof options !== "object" || options === null)
74
+ options = {};
75
+ options = $.extend(this.element.data(), options);
76
+ if (typeof options.singleDatePicker === "boolean")
77
+ this.singleDatePicker = options.singleDatePicker;
78
+ if (!this.singleDatePicker && typeof options.singleMonthView === "boolean") {
79
+ this.singleMonthView = options.singleMonthView;
80
+ } else {
81
+ this.singleMonthView = false;
82
+ }
83
+ if (typeof options.externalStyle === "string" && ["bulma"].includes(options.externalStyle))
84
+ this.externalStyle = options.externalStyle;
85
+ if (typeof options.template !== "string" && !(options.template instanceof $)) {
86
+ let template = [
87
+ '<div class="daterangepicker">',
88
+ '<div class="ranges"></div>',
89
+ '<div class="drp-calendar left">',
90
+ '<table class="calendar-table">',
91
+ "<thead></thead>",
92
+ "<tbody></tbody>",
93
+ "<tfoot>",
94
+ '<tr class="calendar-time start-time"></tr>'
95
+ ];
96
+ if (this.singleMonthView)
97
+ template.push('<tr class="calendar-time end-time"></tr>');
98
+ template.push(...[
99
+ "</tfoot>",
100
+ "</table>",
101
+ "</div>"
102
+ ]);
103
+ template.push(...[
104
+ '<div class="drp-calendar right">',
105
+ '<table class="calendar-table">',
106
+ "<thead></thead>",
107
+ "<tbody></tbody>",
108
+ "<tfoot>",
109
+ '<tr class="calendar-time end-time"></tr>',
110
+ "</tfoot>",
111
+ "</table>",
112
+ "</div>"
113
+ ]);
114
+ template.push(...[
115
+ '<div class="drp-buttons">',
116
+ '<div class="drp-duration-label"></div>',
117
+ '<div class="drp-selected"></div>'
118
+ ]);
119
+ if (this.externalStyle === "bulma") {
120
+ template.push(...[
121
+ '<div class="buttons">',
122
+ '<button class="cancelBtn button is-small" type="button"></button>',
123
+ '<button class="applyBtn button is-small" disabled type="button"></button>',
124
+ "</div>"
125
+ ]);
126
+ } else {
127
+ template.push(...[
128
+ "<div>",
129
+ '<button class="cancelBtn" type="button"></button>',
130
+ '<button class="applyBtn" disabled type="button"></button>',
131
+ "</div>"
132
+ ]);
133
+ }
134
+ template.push("</div></div>");
135
+ options.template = template.join("");
136
+ }
137
+ this.parentEl = options.parentEl && $(options.parentEl).length ? $(options.parentEl) : $(this.parentEl);
138
+ this.container = $(options.template).appendTo(this.parentEl);
139
+ if (typeof options.timePicker === "boolean")
140
+ this.timePicker = options.timePicker;
141
+ if (this.timePicker)
142
+ this.locale.format = DateTime.DATETIME_SHORT;
143
+ if (typeof options.locale === "object") {
144
+ for (let key2 of ["separator", "applyLabel", "cancelLabel", "weekLabel"]) {
145
+ if (typeof options.locale[key2] === "string")
146
+ this.locale[key2] = options.locale[key2];
147
+ }
148
+ if (typeof options.locale.direction === "string") {
149
+ if (["rtl", "ltr"].includes(options.locale.direction))
150
+ this.locale.direction = options.locale.direction;
151
+ else
152
+ console.error(`Option 'options.locale.direction' must be 'rtl' or 'ltr'`);
153
+ }
154
+ if (["string", "object"].includes(typeof options.locale.format))
155
+ this.locale.format = options.locale.format;
156
+ if (Array.isArray(options.locale.daysOfWeek)) {
157
+ if (options.locale.daysOfWeek.some((x) => typeof x !== "string"))
158
+ console.error(`Option 'options.locale.daysOfWeek' must be an array of strings`);
159
+ else
160
+ this.locale.daysOfWeek = options.locale.daysOfWeek.slice();
161
+ }
162
+ if (Array.isArray(options.locale.monthNames)) {
163
+ if (options.locale.monthNames.some((x) => typeof x !== "string"))
164
+ console.error(`Option 'locale.monthNames' must be an array of strings`);
165
+ else
166
+ this.locale.monthNames = options.locale.monthNames.slice();
167
+ }
168
+ if (typeof options.locale.firstDay === "number")
169
+ this.locale.firstDay = options.locale.firstDay;
170
+ if (typeof options.locale.customRangeLabel === "string") {
171
+ var elem = document.createElement("textarea");
172
+ elem.innerHTML = options.locale.customRangeLabel;
173
+ var rangeHtml = elem.value;
174
+ this.locale.customRangeLabel = rangeHtml;
175
+ }
176
+ if (["string", "object", "function"].includes(typeof options.locale.durationFormat) && options.locale.durationFormat != null)
177
+ this.locale.durationFormat = options.locale.durationFormat;
178
+ }
179
+ this.container.addClass(this.locale.direction);
180
+ for (let key2 of [
181
+ "timePicker24Hour",
182
+ "showWeekNumbers",
183
+ "showISOWeekNumbers",
184
+ "showDropdowns",
185
+ "linkedCalendars",
186
+ "showCustomRangeLabel",
187
+ "alwaysShowCalendars",
188
+ "autoApply",
189
+ "autoUpdateInput",
190
+ "showLabel"
191
+ ]) {
192
+ if (typeof options[key2] === "boolean")
193
+ this[key2] = options[key2];
194
+ }
195
+ for (let key2 of ["applyButtonClasses", "cancelButtonClasses", "weekendClasses", "weekendDayClasses", "todayClasses"]) {
196
+ if (typeof options[key2] === "string") {
197
+ this[key2] = options[key2];
198
+ } else if (["weekendClasses", "weekendDayClasses", "todayClasses"].includes(key2) && options[key2] === null) {
199
+ this[key2] = options[key2];
200
+ }
201
+ }
202
+ for (let key2 of ["minYear", "maxYear"]) {
203
+ if (typeof options[key2] === "number")
204
+ this[key2] = options[key2];
205
+ }
206
+ for (let key2 of ["isInvalidDate", "isInvalidTime", "isCustomDate"]) {
207
+ if (typeof options[key2] === "function")
208
+ this[key2] = options[key2];
209
+ else
210
+ this[key2] = function() {
211
+ return false;
212
+ };
213
+ }
214
+ if (!this.singleDatePicker) {
215
+ for (let opt of ["minSpan", "maxSpan", "defaultSpan"]) {
216
+ if (["string", "number", "object"].includes(typeof options[opt])) {
217
+ if (Duration.isDuration(options[opt]) && options[opt].isValid) {
218
+ this[opt] = options[opt];
219
+ } else if (Duration.fromISO(options[opt]).isValid) {
220
+ this[opt] = Duration.fromISO(options[opt]);
221
+ } else if (typeof options[opt] === "number" && Duration.fromObject({ seconds: options[opt] }).isValid) {
222
+ this[opt] = Duration.fromObject({ seconds: options[opt] });
223
+ } else if (options[opt] === null) {
224
+ this[opt] = null;
225
+ } else {
226
+ console.error(`Option '${key}' is not valid`);
227
+ }
228
+ ;
229
+ }
230
+ }
231
+ if (this.minSpan && this.maxSpan && this.minSpan > this.maxSpan) {
232
+ this.minSpan = null;
233
+ this.maxSpan = null;
234
+ console.warn(`Ignore option 'minSpan' and 'maxSpan', because 'minSpan' must be smaller than 'maxSpan'`);
235
+ }
236
+ if (this.defaultSpan && this.minSpan && this.minSpan > this.defaultSpan) {
237
+ this.defaultSpan = null;
238
+ console.warn(`Ignore option 'defaultSpan', because 'defaultSpan' must be greater than 'minSpan'`);
239
+ } else if (this.defaultSpan && this.maxSpan && this.maxSpan < this.defaultSpan) {
240
+ this.defaultSpan = null;
241
+ console.warn(`Ignore option 'defaultSpan', because 'defaultSpan' must be smaller than 'maxSpan'`);
242
+ }
243
+ }
244
+ if (this.timePicker) {
245
+ if (typeof options.timePickerSeconds === "boolean")
246
+ this.timePickerStepSize = Duration.fromObject({ [options.timePickerSeconds ? "seconds" : "minutes"]: 1 });
247
+ if (typeof options.timePickerIncrement === "number")
248
+ this.timePickerStepSize = Duration.fromObject({ minutes: options.timePickerIncrement });
249
+ if (["string", "object", "number"].includes(typeof options.timePickerStepSize)) {
250
+ let duration;
251
+ if (Duration.isDuration(options.timePickerStepSize) && options.timePickerStepSize.isValid) {
252
+ duration = options.timePickerStepSize;
253
+ } else if (Duration.fromISO(options.timePickerStepSize).isValid) {
254
+ duration = Duration.fromISO(options.timePickerStepSize);
255
+ } else if (typeof options.timePickerStepSize === "number" && Duration.fromObject({ seconds: options.timePickerStepSize }).isValid) {
256
+ duration = Duration.fromObject({ seconds: options.timePickerStepSize });
257
+ } else {
258
+ console.error(`Option 'timePickerStepSize' is not valid`);
259
+ duration = this.timePickerStepSize;
260
+ }
261
+ ;
262
+ var valid = [];
263
+ for (let unit of ["minutes", "seconds"])
264
+ valid.push(...[1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30].map((x) => {
265
+ return Duration.fromObject({ [unit]: x });
266
+ }));
267
+ valid.push(...[1, 2, 3, 4, 6].map((x) => {
268
+ return Duration.fromObject({ hours: x });
269
+ }));
270
+ if (this.timePicker24Hour)
271
+ valid.push(...[8, 12].map((x) => {
272
+ return Duration.fromObject({ hours: x });
273
+ }));
274
+ if (valid.some((x) => duration.rescale().equals(x))) {
275
+ this.timePickerStepSize = duration.rescale();
276
+ } else {
277
+ console.error(`Option 'timePickerStepSize' ${JSON.stringify(duration.toObject())} is not valid`);
278
+ }
279
+ }
280
+ if (this.maxSpan && this.timePickerStepSize > this.maxSpan)
281
+ console.error(`Option 'timePickerStepSize' ${JSON.stringify(this.timePickerStepSize.toObject())} must be smaller than 'maxSpan'`);
282
+ this.timePickerOpts = {
283
+ showMinutes: this.timePickerStepSize < Duration.fromObject({ hours: 1 }),
284
+ showSeconds: this.timePickerStepSize < Duration.fromObject({ minutes: 1 }),
285
+ hourStep: this.timePickerStepSize >= Duration.fromObject({ hours: 1 }) ? this.timePickerStepSize.hours : 1,
286
+ minuteStep: this.timePickerStepSize >= Duration.fromObject({ minutes: 1 }) ? this.timePickerStepSize.minutes : 1,
287
+ secondStep: this.timePickerStepSize.seconds
288
+ };
289
+ }
290
+ for (let opt of ["startDate", "endDate", "minDate", "maxDate", "initalMonth"]) {
291
+ if (opt === "endDate" && this.singleDatePicker)
292
+ continue;
293
+ if (typeof options[opt] === "object") {
294
+ if (DateTime.isDateTime(options[opt]) && options[opt].isValid) {
295
+ this[opt] = options[opt];
296
+ } else if (options[opt] instanceof Date) {
297
+ this[opt] = DateTime.fromJSDate(options[opt]);
298
+ } else if (options[opt] === null) {
299
+ this[opt] = null;
300
+ } else {
301
+ console.error(`Option '${opt}' must be a luxon.DateTime or Date or string`);
302
+ }
303
+ } else if (typeof options[opt] === "string") {
304
+ const format = typeof this.locale.format === "string" ? this.locale.format : DateTime.parseFormatForOpts(this.locale.format);
305
+ if (DateTime.fromISO(options[opt]).isValid) {
306
+ this[opt] = DateTime.fromISO(options[opt]);
307
+ } else if (DateTime.fromFormat(options[opt], format, { locale: DateTime.now().locale }).isValid) {
308
+ this[opt] = DateTime.fromFormat(options[opt], format, { locale: DateTime.now().locale });
309
+ } else {
310
+ const invalid = DateTime.fromFormat(options[opt], format, { locale: DateTime.now().locale }).invalidExplanation;
311
+ console.error(`Option '${opt}' is not a valid string: ${invalid}`);
312
+ }
313
+ }
314
+ }
315
+ if ($(this.element).is("input:text")) {
316
+ const val = $(this.element).val();
317
+ if (val != "") {
318
+ const format = typeof this.locale.format === "string" ? this.locale.format : DateTime.parseFormatForOpts(this.locale.format);
319
+ if (this.singleDatePicker && typeof options.startDate === "undefined") {
320
+ const start = DateTime.fromFormat(val, format, { locale: DateTime.now().locale });
321
+ if (start.isValid) {
322
+ this.#startDate = start;
323
+ } else {
324
+ console.error(`Value "${val}" in <input> is not a valid string: ${start.invalidExplanation}`);
325
+ }
326
+ } else if (!this.singleDatePicker && typeof options.startDate === "undefined" && typeof options.endDate === "undefined") {
327
+ const split = val.split(this.locale.separator);
328
+ if (split.length === 2) {
329
+ const start = DateTime.fromFormat(split[0], format, { locale: DateTime.now().locale });
330
+ const end = DateTime.fromFormat(split[1], format, { locale: DateTime.now().locale });
331
+ if (start.isValid && end.isValid) {
332
+ this.#startDate = start;
333
+ this.#endDate = end;
334
+ } else {
335
+ console.error(`Value in <input> is not a valid string: ${start.invalidExplanation} - ${end.invalidExplanation}`);
336
+ }
337
+ } else {
338
+ console.error(`Value "${val}" in <input> is not a valid string`);
339
+ }
340
+ }
341
+ }
342
+ }
343
+ if (!this.timePicker) {
344
+ if (this.minDate)
345
+ this.minDate = this.minDate.startOf("day");
346
+ if (this.maxDate)
347
+ this.maxDate = this.maxDate.endOf("day");
348
+ }
349
+ if (this.singleDatePicker) {
350
+ this.#endDate = this.#startDate;
351
+ } else if (this.#endDate < this.#startDate) {
352
+ console.error(`Option 'endDate' ${this.#endDate} must not be earlier than 'startDate' ${this.#startDate}`);
353
+ }
354
+ if (["function", "string"].includes(typeof options.altFormat))
355
+ this.altFormat = options.altFormat;
356
+ if (typeof options.altInput === "string" || Array.isArray(options.altInput)) {
357
+ if (this.singleDatePicker && typeof options.altInput === "string") {
358
+ this.altInput = $(options.altInput).is("input:text") ? options.altInput : null;
359
+ } else if (!this.singleDatePicker && Array.isArray(options.altInput) && options.altInput.length === 2) {
360
+ this.altInput = options.altInput.every((x) => typeof x === "string" && $(x).is("input:text")) ? options.altInput : null;
361
+ } else {
362
+ const note = `Value of "altInput" must be ` + (this.singleDatePicker ? "a string" : "an array of two string elements");
363
+ console.error(`Option 'altInput' ${JSON.stringify(options.altInput)} is not valid
364
+ `, note);
365
+ }
366
+ }
367
+ if (options.warnings !== void 0)
368
+ console.warn(`Option 'warnings' not used anymore. Listen to event 'violated.daterangepicker'`);
369
+ if (!this.#startDate && this.initalMonth) {
370
+ this.#endDate = null;
371
+ if (this.timePicker)
372
+ console.error(`Option 'initalMonth' works only with 'timePicker: false'`);
373
+ } else {
374
+ const violations = this.validateInput(null, false);
375
+ if (violations != null) {
376
+ let vio = violations.startDate.violations;
377
+ if (vio.length > 0) {
378
+ if (vio.some((x) => x.reason.startsWith("isInvalid"))) {
379
+ console.error(`Value of startDate "${this.#startDate}" violates ${vio.find((x) => x.reason.startsWith("isInvalid")).reason}`);
380
+ } else {
381
+ const newDate = vio.filter((x) => x.new != null).at(-1).new;
382
+ this.#startDate = newDate;
383
+ }
384
+ }
385
+ if (!this.singleDatePicker) {
386
+ vio = violations.endDate.violations.filter((x) => x.new != null);
387
+ if (vio.length > 0) {
388
+ if (vio.some((x) => x.reason.startsWith("isInvalid"))) {
389
+ console.error(`Value of endDate "${this.#endDate}" violates ${vio.find((x) => x.reason.startsWith("isInvalid")).reason}`);
390
+ } else {
391
+ const newDate = vio.filter((x) => x.new != null).at(-1).new;
392
+ this.#endDate = newDate;
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ if (typeof options.opens === "string") {
399
+ if (["left", "right", "center"].includes(options.opens))
400
+ this.opens = options.opens;
401
+ else
402
+ console.error(`Option 'options.opens' must be 'left', 'right' or 'center'`);
403
+ }
404
+ if (typeof options.drops === "string") {
405
+ if (["drop", "down", "auto"].includes(options.drops))
406
+ this.drops = options.drops;
407
+ else
408
+ console.error(`Option 'options.drops' must be 'drop', 'down' or 'auto'`);
409
+ }
410
+ if (Array.isArray(options.buttonClasses)) {
411
+ this.buttonClasses = options.buttonClasses.join(" ");
412
+ } else if (typeof options.buttonClasses === "string") {
413
+ this.buttonClasses = options.buttonClasses;
414
+ }
415
+ if (typeof options.onOutsideClick === "string") {
416
+ if (["cancel", "apply"].includes(options.onOutsideClick))
417
+ this.onOutsideClick = options.onOutsideClick;
418
+ else
419
+ console.error(`Option 'options.onOutsideClick' must be 'cancel' or 'apply'`);
420
+ }
421
+ if (this.locale.firstDay != 1) {
422
+ let iterator = this.locale.firstDay;
423
+ while (iterator > 1) {
424
+ this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift());
425
+ iterator--;
426
+ }
427
+ }
428
+ if (!this.singleDatePicker && typeof options.ranges === "object") {
429
+ for (let range in options.ranges) {
430
+ let start, end;
431
+ if (["string", "object"].includes(typeof options.ranges[range][0])) {
432
+ if (DateTime.isDateTime(options.ranges[range][0]) && options.ranges[range][0].isValid) {
433
+ start = options.ranges[range][0];
434
+ } else if (options.ranges[range][0] instanceof Date) {
435
+ start = DateTime.fromJSDate(options.ranges[range][0]);
436
+ } else if (typeof options.ranges[range][0] === "string" && DateTime.fromISO(options.ranges[range][0]).isValid) {
437
+ start = DateTime.fromISO(options.ranges[range][0]);
438
+ } else {
439
+ console.error(`Option ranges['${range}'] is not am array of valid ISO-8601 string or luxon.DateTime or Date`);
440
+ }
441
+ }
442
+ if (["string", "object"].includes(typeof options.ranges[range][1])) {
443
+ if (DateTime.isDateTime(options.ranges[range][1]) && options.ranges[range][1].isValid) {
444
+ end = options.ranges[range][1];
445
+ } else if (options.ranges[range][1] instanceof Date) {
446
+ end = DateTime.fromJSDate(options.ranges[range][1]);
447
+ } else if (typeof options.ranges[range][1] === "string" && DateTime.fromISO(options.ranges[range][1]).isValid) {
448
+ end = DateTime.fromISO(options.ranges[range][1]);
449
+ } else {
450
+ console.error(`Option ranges['${range}'] is not a valid ISO-8601 string or luxon.DateTime or Date`);
451
+ }
452
+ }
453
+ if (start == null || end == null)
454
+ continue;
455
+ options.ranges[range] = [start, end];
456
+ var elem = document.createElement("textarea");
457
+ elem.innerHTML = range;
458
+ this.ranges[elem.value] = [start, end];
459
+ }
460
+ 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
+ }
467
+ list += "</ul>";
468
+ this.container.find(".ranges").prepend(list);
469
+ this.container.addClass("show-ranges");
470
+ }
471
+ if (typeof cb === "function") {
472
+ this.callback = cb;
473
+ }
474
+ if (!this.timePicker) {
475
+ if (this.#startDate)
476
+ this.#startDate = this.#startDate.startOf("day");
477
+ if (this.#endDate)
478
+ this.#endDate = this.#endDate.endOf("day");
479
+ this.container.find(".calendar-time").hide();
480
+ }
481
+ if (this.timePicker && this.autoApply)
482
+ this.autoApply = false;
483
+ if (this.autoApply)
484
+ this.container.addClass("auto-apply");
485
+ if (this.singleDatePicker || this.singleMonthView) {
486
+ this.container.addClass("single");
487
+ this.container.find(".drp-calendar.left").addClass("single");
488
+ this.container.find(".drp-calendar.left").show();
489
+ this.container.find(".drp-calendar.right").hide();
490
+ if (!this.timePicker && this.autoApply)
491
+ this.container.addClass("auto-apply");
492
+ }
493
+ if (typeof options.ranges === "undefined" && !this.singleDatePicker || this.alwaysShowCalendars)
494
+ this.container.addClass("show-calendar");
495
+ this.container.addClass("opens" + this.opens);
496
+ this.container.find(".applyBtn, .cancelBtn").addClass(this.buttonClasses);
497
+ if (this.applyButtonClasses.length)
498
+ this.container.find(".applyBtn").addClass(this.applyButtonClasses);
499
+ if (this.cancelButtonClasses.length)
500
+ this.container.find(".cancelBtn").addClass(this.cancelButtonClasses);
501
+ this.container.find(".applyBtn").html(this.locale.applyLabel);
502
+ this.container.find(".cancelBtn").html(this.locale.cancelLabel);
503
+ 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));
504
+ 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));
505
+ this.container.find(".drp-buttons").on("click.daterangepicker", "button.applyBtn", this.clickApply.bind(this)).on("click.daterangepicker", "button.cancelBtn", this.clickCancel.bind(this));
506
+ if (this.element.is("input") || this.element.is("button")) {
507
+ this.element.on({
508
+ "click.daterangepicker": this.show.bind(this),
509
+ "focus.daterangepicker": this.show.bind(this),
510
+ "keyup.daterangepicker": this.elementChanged.bind(this),
511
+ "keydown.daterangepicker": this.keydown.bind(this)
512
+ //IE 11 compatibility
513
+ });
514
+ } else {
515
+ this.element.on("click.daterangepicker", this.toggle.bind(this));
516
+ this.element.on("keydown.daterangepicker", this.toggle.bind(this));
517
+ }
518
+ this.updateElement();
519
+ }
520
+ get startDate() {
521
+ return this.#startDate;
522
+ }
523
+ get endDate() {
524
+ return this.singleDatePicker ? null : this.#endDate;
525
+ }
526
+ set startDate(val) {
527
+ this.#startDate = val;
528
+ }
529
+ set endDate(val) {
530
+ this.#endDate = val;
531
+ }
532
+ /**
533
+ * Sets the date range picker's currently selected start date to the provided date.<br>
534
+ * `startDate` must be a `luxon.DateTime` or `Date` or `string` according to {@link ISO-8601} or a string matching `locale.format`.<br>
535
+ * Invalid date values are handled by {@link #DateRangePicker+violated|violated} Event
536
+ * @param {external:DateTime|external:Date|string} startDate - startDate to be set. In case of ranges, the current `endDate` is used.
537
+ * @param {boolean} updateView=true - If `true`, then calendar UI is updated to new value. Otherwise only internal values are set.
538
+ * @returns {InputViolation} - Object of violations or `null` if no violation have been found
539
+ * @example
540
+ * const drp = $('#picker').data('daterangepicker');
541
+ * drp.setStartDate(DateTime.now().startOf('hour'));
542
+ */
543
+ setStartDate(startDate, updateView = true) {
544
+ if (!this.singleDatePicker)
545
+ return setRange(startDate, this.#endDate, updateView);
546
+ const oldDate = this.#startDate;
547
+ let newDate = this.parseDate(startDate);
548
+ if (newDate.equals(oldDate))
549
+ return null;
550
+ const violations = this.validateInput([newDate, null], true);
551
+ if (violations != null) {
552
+ if (violations.newDate != null) {
553
+ newDate = violations.newDate.startDate;
554
+ } else {
555
+ return violations;
556
+ }
557
+ }
558
+ this.#startDate = newDate;
559
+ this.#endDate = this.#startDate;
560
+ this.updateElement();
561
+ if (updateView)
562
+ this.updateView();
563
+ return violations;
564
+ }
565
+ /**
566
+ * Sets the date range picker's currently selected start date to the provided date.<br>
567
+ * `endDate` must be a `luxon.DateTime` or `Date` or `string` according to {@link ISO-8601} or a string matching `locale.format`.<br>
568
+ * Invalid date values are handled by {@link #DateRangePicker+violated|violated} Event
569
+ * @param {external:DateTime|external:Date|string} endDate - endDate to be set. In case of ranges, the current `startDate` is used.
570
+ * @param {boolean} updateView=true - If `true`, then calendar UI is updated to new value. Otherwise only internal values are set.
571
+ * @returns {InputViolation} - Object of violations or `null` if no violation have been found
572
+ * @example
573
+ * const drp = $('#picker').data('daterangepicker');
574
+ * drp.setEndDate(DateTime.now().startOf('hour'));
575
+ */
576
+ setEndDate(endDate, updateView = true) {
577
+ return this.singleDatePicker ? null : setRange(this.#startDate, endDate, updateView);
578
+ }
579
+ /**
580
+ * Sets the date range picker's currently selected start date to the provided date.<br>
581
+ * `startDate` and `endDate` must be a `luxon.DateTime` or `Date` or `string` according to {@link ISO-8601} or a string matching `locale.format`.<br>
582
+ * Invalid date values are handled by {@link #DateRangePicker+violated|violated} Event
583
+ * @param {external:DateTime|external:Date|string} startDate - startDate to be set
584
+ * @param {external:DateTime|external:Date|string} endDate - endDate to be set
585
+ * @param {boolean} updateView=true - If `true`, then calendar UI is updated to new value. Otherwise only internal values are set.
586
+ * @returns {InputViolation} - Object of violations or `null` if no violation have been found
587
+ * @example
588
+ * const drp = $('#picker').data('daterangepicker');
589
+ * drp.setRange(DateTime.now().startOf('hour'), DateTime.now().endOf('day'));
590
+ */
591
+ setRange(startDate, endDate, updateView = true) {
592
+ if (this.singleDatePicker)
593
+ return;
594
+ if (!this.#endDate)
595
+ this.#endDate = this.#startDate;
596
+ const oldDate = [this.#startDate, this.#endDate];
597
+ let newDate = [this.parseDate(startDate), this.parseDate(endDate)];
598
+ if (oldDate[0].equals(newDate[0]) && oldDate[1].equals(newDate[1]) || newDate[1] > newDate[0])
599
+ return;
600
+ const violations = this.validateInput([newDate[0], newDate[1]], true);
601
+ if (violations != null) {
602
+ if (violations.newDate != null) {
603
+ newDate[0] = violations.newDate.startDate;
604
+ newDate[1] = violations.newDate.endDate;
605
+ } else {
606
+ return violations;
607
+ }
608
+ }
609
+ this.#startDate = newDate[0];
610
+ this.#endDate = newDate[1];
611
+ this.updateElement();
612
+ if (updateView)
613
+ this.updateView();
614
+ return violations;
615
+ }
616
+ /**
617
+ * Parse date value
618
+ * @param {sting|external:DateTime|Date} value - The value to be parsed
619
+ * @returns {external:DateTime} - DateTime object
620
+ */
621
+ parseDate(value) {
622
+ if (typeof value === "object") {
623
+ if (DateTime.isDateTime(value) && value.isValid) {
624
+ return value;
625
+ } else if (value instanceof Date) {
626
+ return DateTime.fromJSDate(value);
627
+ } else {
628
+ throw RangeError(`Value must be a luxon.DateTime or Date or string`);
629
+ }
630
+ } else if (typeof value === "string") {
631
+ const format = typeof this.locale.format === "string" ? this.locale.format : DateTime.parseFormatForOpts(this.locale.format);
632
+ if (DateTime.fromISO(value).isValid) {
633
+ return DateTime.fromISO(value);
634
+ } else if (DateTime.fromFormat(value, format, { locale: DateTime.now().locale }).isValid) {
635
+ return DateTime.fromFormat(value, format, { locale: DateTime.now().locale });
636
+ } else {
637
+ const invalid = DateTime.fromFormat(value, format, { locale: DateTime.now().locale }).invalidExplanation;
638
+ throw RangeError(`Value is not a valid string: ${invalid}`);
639
+ }
640
+ }
641
+ }
642
+ logDate(date) {
643
+ return this.timePicker ? date.toISO({ suppressMilliseconds: true }) : date.toISODate();
644
+ }
645
+ /**
646
+ * Format a DateTime object
647
+ * @param {external:DateTime} date - The DateTime to format
648
+ * @param {object|string} format=this.locale.format - The format option
649
+ * @returns {string} - Formatted date string
650
+ */
651
+ formatDate(date, format = this.locale.format) {
652
+ if (typeof format === "object") {
653
+ return date.toLocaleString(format);
654
+ } else {
655
+ if (Settings.defaultLocale === null) {
656
+ const locale = DateTime.now().locale;
657
+ return date.toFormat(format, { locale });
658
+ } else {
659
+ return date.toFormat(format);
660
+ }
661
+ }
662
+ }
663
+ /**
664
+ * Set Duration Label to selected range (if used) and selected dates
665
+ * @private
666
+ */
667
+ updateLabel() {
668
+ if (this.showLabel) {
669
+ let text = this.formatDate(this.#startDate);
670
+ if (!this.singleDatePicker) {
671
+ text += this.locale.separator;
672
+ if (this.#endDate)
673
+ text += this.formatDate(this.#endDate);
674
+ }
675
+ this.container.find(".drp-selected").html(text);
676
+ }
677
+ if (this.singleDatePicker || this.locale.durationFormat == null)
678
+ return;
679
+ if (!this.#endDate) {
680
+ this.container.find(".drp-duration-label").html("");
681
+ return;
682
+ }
683
+ if (typeof this.locale.durationFormat === "function") {
684
+ this.container.find(".drp-duration-label").html(this.locale.durationFormat(this.#startDate, this.#endDate));
685
+ } else {
686
+ let duration = this.#endDate.plus({ milliseconds: 1 }).diff(this.#startDate).rescale().set({ milliseconds: 0 });
687
+ if (!this.timePicker)
688
+ duration = duration.set({ seconds: 0, minutes: 0, hours: 0 });
689
+ duration = duration.removeZeros();
690
+ if (typeof this.locale.durationFormat === "object") {
691
+ this.container.find(".drp-duration-label").html(duration.toHuman(this.locale.durationFormat));
692
+ } else {
693
+ this.container.find(".drp-duration-label").html(duration.toFormat(this.locale.durationFormat));
694
+ }
695
+ }
696
+ }
697
+ /**
698
+ * Emitted when the date is changed through `<input>` element or via {@link #DateRangePicker+setStartDate|setStartDate} or
699
+ * {@link #DateRangePicker+setRange|setRange} and date is not valid due to.<br>
700
+ * `minDate`, `maxDate`, `minSpan`, `maxSpan`, `invalidDate` and `invalidTime` constraints.<br>
701
+ * Event is only triggered when date string is valid and date value is changing<br>
702
+ * @event
703
+ * @name "violated.daterangepicker"
704
+ * @param {Object} this - The event object
705
+ * @param {DateRangePicker} picker - The daterangepicker object
706
+ * @param {InputViolation} result - The violation object, see example of `validateInput()`
707
+ * @param {Object} newDate - Object of {startDate, endDate}
708
+ * @return {boolean}=undefined - If handler returns `true`, then values from `newDate` object are used
709
+ * @example
710
+ *
711
+ * $('#picker').daterangepicker({
712
+ * startDate: DateTime.now(),
713
+ * // allow only dates from current year
714
+ * minDate: DateTime.now().startOf('year'),
715
+ * manDate: DateTime.now().endOf('year'),
716
+ * singleDatePicker: true,
717
+ * locale: {
718
+ * format: DateTime.DATETIME_SHORT
719
+ * }
720
+ * }).on('violated.daterangepicker', (ev, picker, result, newDate) => {
721
+ * newDate.startDate = DateTime.now().minus({ days: 3 }).startOf('day');
722
+ * return true;
723
+ * });
724
+ *
725
+ * // Try to set date outside permitted range at <input> elemet
726
+ * $('#picker').val(DateTime.now().minus({ years: 10 })).toLocaleString(DateTime.DATETIME_SHORT).trigger('keyup');
727
+
728
+ * // Try to set date outside permitted range by code
729
+ * const drp = $('#picker').data('daterangepicker').setStartDate(DateTime.now().minus({ years: 10 })
730
+ *
731
+ * -> Calendar selects and shows "today - 3 days"
732
+ */
733
+ /**
734
+ * @typedef InputViolation
735
+ * @type {Object}
736
+ * @property {external:DateTime} startDate - Violation of startDate
737
+ * @property {external:DateTime|undefined}? endDate - Violation of endDate, if existing
738
+ * @property {Array} violations - The constraints which violates the input
739
+ * @property {Array} reason - The type/reson of violation
740
+ * @property {external:DateTime} old - Old value startDate/endDate
741
+ * @property {external:DateTime}? new - Corrected value of startDate/endDate if existing
742
+ */
743
+ /**
744
+ * Validate `startDate` and `endDate` against `timePickerStepSize`, `minDate`, `maxDate`,
745
+ * `minSpan`, `maxSpan`, `invalidDate` and `invalidTime`.
746
+ * @param {Array} [startDate, endDate] - Range to be checked, defaults to current `startDate` and `endDate`
747
+ * @param {boolean} dipatch=false - If 'true' then event "violated.daterangepicker" is dispated.<br>
748
+ * If eventHandler returns `true`, then `null` is returned, otherwiese the object of violations.
749
+ * @emits "violated.daterangepicker"
750
+ * @returns {InputViolation|null} - Object of violations and corrected values or `null` if no violation have been found
751
+ * @example
752
+ * options => {
753
+ * minDate: DateTime.now().minus({months: 3}).startOf('day'),
754
+ * maxDate: DateTime.now().minus({day: 3}).startOf('day'),
755
+ * minSpan: Duration.fromObject({days: 7}),
756
+ * maxSpan: Duration.fromObject({days: 70}),
757
+ * timePickerStepSize: Duration.fromObject({hours: 1})
758
+ * }
759
+ * const result = validateInput(DateTime.now(), DateTime.now().plus({day: 3}));
760
+ *
761
+ * result => {
762
+ * startDate: {
763
+ * violations: [
764
+ * { old: "2026-03-13T10:35:52", reason: "timePickerStepSize", new: "2026-03-13T11:00:00" },
765
+ * { old: "2026-03-13T11:00:00", reason: "maxDate", new: "2026-03-10T00:00:00" }
766
+ * ]
767
+ * },
768
+ * endDate: {
769
+ * violations: [
770
+ * { old: "2026-03-16T10:35:52", reason: "stepSize", new: "2026-03-16T11:00:00" },
771
+ * { old: "2026-03-16T11:00:00", reason: "maxDate", new: "2026-03-10T00:00:00" },
772
+ * { old: "2026-03-10T00:00:00", reason: "minSpan", new: "2026-03-17T00:00:00" }
773
+ * ]
774
+ * }
775
+ * }
776
+ */
777
+ validateInput(range, dipatch = false) {
778
+ let startDate = range == null ? this.#startDate : range[0];
779
+ let endDate = range == null ? this.#endDate : range[1];
780
+ if (startDate == null)
781
+ return null;
782
+ let result = { startDate: { violations: [] } };
783
+ let violation = { old: startDate, reason: this.timePicker ? "timePickerStepSize" : "timePicker" };
784
+ if (this.timePicker) {
785
+ const secs = this.timePickerStepSize.as("seconds");
786
+ startDate = DateTime.fromSeconds(secs * Math.round(startDate.toSeconds() / secs));
787
+ } else {
788
+ startDate = startDate.startOf("day");
789
+ }
790
+ violation.new = startDate;
791
+ if (!violation.new.equals(violation.old))
792
+ result.startDate.violations.push(violation);
793
+ const shiftStep = this.timePicker ? this.timePickerStepSize.as("seconds") : Duration.fromObject({ days: 1 }).as("seconds");
794
+ if (this.minDate && startDate < this.minDate) {
795
+ violation = { old: startDate, reason: "minDate" };
796
+ startDate = startDate.plus({ seconds: Math.trunc(this.minDate.diff(startDate).as("seconds") / shiftStep) * shiftStep });
797
+ if (startDate < this.minDate)
798
+ startDate = startDate.plus(this.timePicker ? this.timePickerStepSize : { days: 1 });
799
+ violation.new = startDate;
800
+ if (!violation.new.equals(violation.old))
801
+ result.startDate.violations.push(violation);
802
+ } else if (this.maxDate && startDate > this.maxDate) {
803
+ violation = { old: startDate, reason: "maxDate" };
804
+ startDate = startDate.minus({ seconds: Math.trunc(startDate.diff(this.maxDate).as("seconds") / shiftStep) * shiftStep });
805
+ if (startDate > this.maxDate)
806
+ startDate = startDate.minus(this.timePicker ? this.timePickerStepSize : { days: 1 });
807
+ violation.new = startDate;
808
+ if (!violation.new.equals(violation.old))
809
+ result.startDate.violations.push(violation);
810
+ }
811
+ let units = ["hour"];
812
+ if (this.timePicker) {
813
+ if (this.timePickerOpts.showMinutes)
814
+ units.push("minute");
815
+ if (this.timePickerOpts.showSeconds)
816
+ units.push("second");
817
+ if (!this.timePicker24Hour)
818
+ units.push("ampm");
819
+ }
820
+ if (this.isInvalidDate(startDate))
821
+ result.startDate.violations.push({ old: startDate, reason: "isInvalidDate" });
822
+ if (this.timePicker) {
823
+ for (let unit of units) {
824
+ if (this.isInvalidTime(startDate, unit, "start"))
825
+ result.startDate.violations.push({ old: startDate, reason: "isInvalidTime", unit });
826
+ }
827
+ }
828
+ if (this.singleDatePicker) {
829
+ if (result.startDate.violations.length == 0)
830
+ return null;
831
+ if (dipatch) {
832
+ let newValues = { startDate };
833
+ const ret = this.element.triggerHandler("violated.daterangepicker", [this, result, newValues]);
834
+ if (ret) {
835
+ result.newDate = newValues;
836
+ return result;
837
+ }
838
+ return result;
839
+ } else {
840
+ return result;
841
+ }
842
+ }
843
+ if (endDate == null)
844
+ return null;
845
+ result.endDate = { violations: [] };
846
+ violation = { old: endDate, reason: this.timePicker ? "stepSize" : "timePicker" };
847
+ if (this.timePicker) {
848
+ const secs = this.timePickerStepSize.as("seconds");
849
+ endDate = DateTime.fromSeconds(secs * Math.round(endDate.toSeconds() / secs));
850
+ } else {
851
+ endDate = endDate.endOf("day");
852
+ }
853
+ violation.new = endDate;
854
+ if (!violation.new.equals(violation.old))
855
+ result.endDate.violations.push(violation);
856
+ if (this.maxDate && endDate > this.maxDate) {
857
+ violation = { old: endDate, reason: "maxDate" };
858
+ endDate = endDate.minus({ seconds: Math.trunc(endDate.diff(this.maxDate).as("seconds") / shiftStep) * shiftStep });
859
+ if (endDate > this.maxDate)
860
+ endDate = endDate.minus(this.timePicker ? this.timePickerStepSize : { days: 1 });
861
+ violation.new = endDate;
862
+ if (!violation.new.equals(violation.old))
863
+ result.endDate.violations.push(violation);
864
+ } else if (this.minDate && endDate < this.minDate) {
865
+ violation = { old: endDate, reason: "minDate" };
866
+ endDate = endDate.plus({ seconds: Math.trunc(this.minDate.diff(endDate).as("seconds") / shiftStep) * shiftStep });
867
+ if (endDate < this.minDate)
868
+ endDate = endDate.plus(this.timePicker ? this.timePickerStepSize : { days: 1 });
869
+ violation.new = endDate;
870
+ if (!violation.new.equals(violation.old))
871
+ result.endDate.violations.push(violation);
872
+ }
873
+ if (this.maxSpan) {
874
+ const maxDate = startDate.plus(this.maxSpan);
875
+ if (endDate > maxDate) {
876
+ violation = { old: endDate, reason: "maxSpan" };
877
+ endDate = endDate.minus({ seconds: Math.trunc(maxDate.diff(endDate).as("seconds") / shiftStep) * shiftStep });
878
+ if (endDate > maxDate)
879
+ endDate = endDate.minus(this.timePicker ? this.timePickerStepSize : { days: 1 });
880
+ violation.new = endDate;
881
+ if (!violation.new.equals(violation.old))
882
+ result.endDate.violations.push(violation);
883
+ }
884
+ }
885
+ if (this.minSpan) {
886
+ const minDate = startDate.plus(this.defaultSpan ?? this.minSpan);
887
+ if (endDate < minDate) {
888
+ violation = { old: endDate, reason: "minSpan" };
889
+ endDate = endDate.plus({ seconds: Math.trunc(minDate.diff(endDate).as("seconds") / shiftStep) * shiftStep });
890
+ if (endDate < minDate)
891
+ endDate = endDate.plus(this.timePicker ? this.timePickerStepSize : { days: 1 });
892
+ violation.new = endDate;
893
+ if (!violation.new.equals(violation.old))
894
+ result.endDate.violations.push(violation);
895
+ }
896
+ }
897
+ if (this.isInvalidDate(endDate))
898
+ result.endDate.violations.push({ old: endDate, reason: "isInvalidDate" });
899
+ if (this.timePicker) {
900
+ for (let unit of units) {
901
+ if (this.isInvalidTime(endDate, unit, "end"))
902
+ result.endDate.violations.push({ old: endDate, reason: "isInvalidTime", unit });
903
+ }
904
+ }
905
+ if (result.startDate.violations.length == 0 && result.endDate.violations.length == 0)
906
+ return null;
907
+ if (dipatch) {
908
+ let newValues = { startDate, endDate };
909
+ const ret = this.element.triggerHandler("violated.daterangepicker", [this, result, newValues]);
910
+ if (ret) {
911
+ result.newDate = newValues;
912
+ return result;
913
+ }
914
+ return result;
915
+ } else {
916
+ return result;
917
+ }
918
+ }
919
+ /**
920
+ * Updates the picker when calendar is initiated or any date has been selected.
921
+ * Could be useful after running {@link #DateRangePicker+setStartDate|setStartDate} or {@link #DateRangePicker+setEndDate|setRange}
922
+ * @emits "beforeRenderTimePicker.daterangepicker"
923
+ */
924
+ updateView() {
925
+ if (this.timePicker) {
926
+ this.element.trigger("beforeRenderTimePicker.daterangepicker", this);
927
+ this.renderTimePicker("start");
928
+ this.renderTimePicker("end");
929
+ if (!this.#endDate) {
930
+ this.container.find(".calendar-time.end-time select").prop("disabled", true).addClass("disabled");
931
+ } else {
932
+ this.container.find(".calendar-time.end-time select").prop("disabled", false).removeClass("disabled");
933
+ }
934
+ }
935
+ this.updateLabel();
936
+ this.updateMonthsInView();
937
+ this.updateCalendars();
938
+ this.setApplyBtnState();
939
+ }
940
+ /**
941
+ * Shows calendar months based on selected date values
942
+ * @private
943
+ */
944
+ updateMonthsInView() {
945
+ if (this.#endDate) {
946
+ if (!this.singleDatePicker && this.leftCalendar.month && this.rightCalendar.month && (this.#startDate.hasSame(this.leftCalendar.month, "month") || this.#startDate.hasSame(this.rightCalendar.month, "month")) && (this.#endDate.hasSame(this.leftCalendar.month, "month") || this.#endDate.hasSame(this.rightCalendar.month, "month")))
947
+ return;
948
+ this.leftCalendar.month = this.#startDate.startOf("month");
949
+ if (!this.singleMonthView) {
950
+ if (!this.linkedCalendars && !this.#endDate.hasSame(this.#startDate, "month")) {
951
+ this.rightCalendar.month = this.#endDate.startOf("month");
952
+ } else {
953
+ this.rightCalendar.month = this.#startDate.startOf("month").plus({ month: 1 });
954
+ }
955
+ }
956
+ } else {
957
+ if (!this.#startDate && this.initalMonth) {
958
+ this.leftCalendar.month = this.initalMonth;
959
+ if (!this.singleMonthView)
960
+ this.rightCalendar.month = this.initalMonth.plus({ month: 1 });
961
+ } else {
962
+ if (!this.leftCalendar.month.hasSame(this.#startDate, "month") && !this.rightCalendar.month.hasSame(this.#startDate, "month")) {
963
+ this.leftCalendar.month = this.#startDate.startOf("month");
964
+ this.rightCalendar.month = this.#startDate.startOf("month").plus({ month: 1 });
965
+ }
966
+ }
967
+ }
968
+ if (this.maxDate && this.linkedCalendars && !this.singleDatePicker && !this.singleMonthView && this.rightCalendar.month > this.maxDate) {
969
+ this.rightCalendar.month = this.maxDate.startOf("month");
970
+ this.leftCalendar.month = this.maxDate.startOf("month").minus({ month: 1 });
971
+ }
972
+ }
973
+ /**
974
+ * Updates the selected day value from calendar with selected time values
975
+ * @emits "beforeRenderCalendar.daterangepicker"
976
+ * @private
977
+ */
978
+ updateCalendars() {
979
+ if (this.timePicker) {
980
+ var hour, minute, second;
981
+ if (this.#endDate) {
982
+ hour = parseInt(this.container.find(".start-time .hourselect").val(), 10);
983
+ if (isNaN(hour))
984
+ hour = parseInt(this.container.find(".start-time .hourselect option:last").val(), 10);
985
+ minute = 0;
986
+ if (this.timePickerOpts.showMinutes) {
987
+ minute = parseInt(this.container.find(".start-time .minuteselect").val(), 10);
988
+ if (isNaN(minute))
989
+ minute = parseInt(this.container.find(".start-time .minuteselect option:last").val(), 10);
990
+ }
991
+ second = 0;
992
+ if (this.timePickerOpts.showSeconds) {
993
+ second = parseInt(this.container.find(".start-time .secondselect").val(), 10);
994
+ if (isNaN(second))
995
+ second = parseInt(this.container.find(".start-time .secondselect option:last").val(), 10);
996
+ }
997
+ } else {
998
+ hour = parseInt(this.container.find(".end-time .hourselect").val(), 10);
999
+ if (isNaN(hour))
1000
+ hour = parseInt(this.container.find(".end-time .hourselect option:last").val(), 10);
1001
+ minute = 0;
1002
+ if (this.timePickerOpts.showMinutes) {
1003
+ minute = parseInt(this.container.find(".end-time .minuteselect").val(), 10);
1004
+ if (isNaN(minute))
1005
+ minute = parseInt(this.container.find(".end-time .minuteselect option:last").val(), 10);
1006
+ }
1007
+ second = 0;
1008
+ if (this.timePickerOpts.showSeconds) {
1009
+ second = parseInt(this.container.find(".end-time .secondselect").val(), 10);
1010
+ if (isNaN(second))
1011
+ second = parseInt(this.container.find(".end-time .secondselect option:last").val(), 10);
1012
+ }
1013
+ }
1014
+ this.leftCalendar.month = this.leftCalendar.month.set({ hour, minute, second });
1015
+ if (!this.singleMonthView)
1016
+ this.rightCalendar.month = this.rightCalendar.month.set({ hour, minute, second });
1017
+ } else {
1018
+ this.leftCalendar.month = this.leftCalendar.month.set({ hour: 0, minute: 0, second: 0 });
1019
+ if (!this.singleMonthView)
1020
+ this.rightCalendar.month = this.rightCalendar.month.set({ hour: 0, minute: 0, second: 0 });
1021
+ }
1022
+ this.element.trigger("beforeRenderCalendar.daterangepicker", this);
1023
+ this.renderCalendar("left");
1024
+ this.renderCalendar("right");
1025
+ this.container.find(".ranges li").removeClass("active");
1026
+ if (this.#endDate == null) return;
1027
+ this.calculateChosenLabel();
1028
+ }
1029
+ /**
1030
+ * Renders the calendar month
1031
+ * @private
1032
+ */
1033
+ renderCalendar(side) {
1034
+ if (side === "right" && this.singleMonthView)
1035
+ return;
1036
+ var calendar = side === "left" ? this.leftCalendar : this.rightCalendar;
1037
+ if (calendar.month == null && !this.#startDate && this.initalMonth)
1038
+ calendar.month = this.initalMonth.startOf("month");
1039
+ const firstDay = calendar.month.startOf("month");
1040
+ const lastDay = calendar.month.endOf("month").startOf("day");
1041
+ var theDate = calendar.month.startOf("month").minus({ day: 1 });
1042
+ const time = { hour: calendar.month.hour, minute: calendar.month.minute, second: calendar.month.second };
1043
+ var calendar = [];
1044
+ calendar.firstDay = firstDay;
1045
+ calendar.lastDay = lastDay;
1046
+ for (var i = 0; i < 6; i++)
1047
+ calendar[i] = [];
1048
+ while (theDate.weekday != this.locale.firstDay)
1049
+ theDate = theDate.minus({ day: 1 });
1050
+ for (let col = 0, row = -1; col < 42; col++, theDate = theDate.plus({ day: 1 })) {
1051
+ if (col % 7 === 0)
1052
+ row++;
1053
+ calendar[row][col % 7] = theDate.set(time);
1054
+ }
1055
+ if (side === "left") {
1056
+ this.leftCalendar.calendar = calendar;
1057
+ } else {
1058
+ this.rightCalendar.calendar = calendar;
1059
+ }
1060
+ var minDate = side === "left" ? this.minDate : this.#startDate;
1061
+ var maxDate = this.maxDate;
1062
+ var html = "<tr>";
1063
+ if (this.showWeekNumbers || this.showISOWeekNumbers)
1064
+ html += "<th></th>";
1065
+ if ((!minDate || minDate < calendar.firstDay) && (!this.linkedCalendars || side === "left")) {
1066
+ html += '<th class="prev available"><span></span></th>';
1067
+ } else {
1068
+ html += "<th></th>";
1069
+ }
1070
+ var dateHtml = `${this.locale.monthNames[calendar.firstDay.month - 1]} ${calendar.firstDay.year}`;
1071
+ if (this.showDropdowns) {
1072
+ const maxYear = (maxDate && maxDate.year) ?? this.maxYear;
1073
+ const minYear = (minDate && minDate.year) ?? this.minYear;
1074
+ let div = this.externalStyle === "bulma" ? '<div class="select is-small mr-1">' : "";
1075
+ var monthHtml = `${div}<select class="monthselect">`;
1076
+ for (var m = 1; m <= 12; m++) {
1077
+ monthHtml += `<option value="${m}"${m === calendar.firstDay.month ? " selected" : ""}`;
1078
+ if (minDate && calendar.firstDay.set({ month: m }) < minDate.startOf("month") || maxDate && calendar.firstDay.set({ month: m }) > maxDate.endOf("month"))
1079
+ monthHtml += ` disabled`;
1080
+ monthHtml += `>${this.locale.monthNames[m - 1]}</option>`;
1081
+ }
1082
+ monthHtml += "</select>";
1083
+ if (this.externalStyle === "bulma")
1084
+ monthHtml += "</div>";
1085
+ div = this.externalStyle === "bulma" ? '<div class="select is-small ml-1">' : "";
1086
+ var yearHtml = `${div}<select class="yearselect">`;
1087
+ for (var y = minYear; y <= maxYear; y++)
1088
+ yearHtml += `<option value="${y}"${y === calendar.firstDay.year ? " selected" : ""}>${y}</option>`;
1089
+ yearHtml += "</select>";
1090
+ if (this.externalStyle === "bulma")
1091
+ yearHtml += "</div>";
1092
+ dateHtml = monthHtml + yearHtml;
1093
+ }
1094
+ html += '<th colspan="5" class="month">' + dateHtml + "</th>";
1095
+ if ((!maxDate || maxDate > calendar.lastDay.endOf("day")) && (!this.linkedCalendars || side === "right" || this.singleDatePicker || this.singleMonthView)) {
1096
+ html += '<th class="next available"><span></span></th>';
1097
+ } else {
1098
+ html += "<th></th>";
1099
+ }
1100
+ html += "</tr>";
1101
+ html += "<tr>";
1102
+ if (this.showWeekNumbers || this.showISOWeekNumbers)
1103
+ html += `<th class="week">${this.locale.weekLabel}</th>`;
1104
+ for (let [index, dayOfWeek] of this.locale.daysOfWeek.entries()) {
1105
+ html += "<th";
1106
+ if (this.weekendDayClasses && this.weekendDayClasses.length && Info.getWeekendWeekdays().includes(index + 1))
1107
+ html += ` class="${this.weekendDayClasses}"`;
1108
+ html += `>${dayOfWeek}</th>`;
1109
+ }
1110
+ ;
1111
+ html += "</tr>";
1112
+ this.container.find(".drp-calendar." + side + " .calendar-table thead").html(html);
1113
+ html = "";
1114
+ if (this.#endDate == null && this.maxSpan) {
1115
+ var maxLimit = this.#startDate.plus(this.maxSpan).endOf("day");
1116
+ if (!maxDate || maxLimit < maxDate) {
1117
+ maxDate = maxLimit;
1118
+ }
1119
+ }
1120
+ var minLimit;
1121
+ if (this.#endDate == null && this.minSpan)
1122
+ minLimit = this.#startDate.plus(this.minSpan).startOf("day");
1123
+ for (let row = 0; row < 6; row++) {
1124
+ html += "<tr>";
1125
+ if (this.showISOWeekNumbers)
1126
+ html += '<td class="week">' + calendar[row][0].weekNumber + "</td>";
1127
+ else if (this.showWeekNumbers)
1128
+ html += '<td class="week">' + calendar[row][0].localWeekNumber + "</td>";
1129
+ for (let col = 0; col < 7; col++) {
1130
+ var classes = [];
1131
+ if (this.todayClasses && this.todayClasses.length && calendar[row][col].hasSame(DateTime.now(), "day"))
1132
+ classes.push(this.todayClasses);
1133
+ if (this.weekendClasses && this.weekendClasses.length && Info.getWeekendWeekdays().includes(calendar[row][col].weekday))
1134
+ classes.push(this.weekendClasses);
1135
+ if (calendar[row][col].month != calendar[1][1].month)
1136
+ classes.push("off", "ends");
1137
+ if (this.minDate && calendar[row][col].startOf("day") < this.minDate.startOf("day"))
1138
+ classes.push("off", "disabled");
1139
+ if (maxDate && calendar[row][col].startOf("day") > maxDate.startOf("day"))
1140
+ classes.push("off", "disabled");
1141
+ if (minLimit && calendar[row][col].startOf("day") > this.#startDate.startOf("day") && calendar[row][col].startOf("day") < minLimit.startOf("day"))
1142
+ classes.push("off", "disabled");
1143
+ if (this.isInvalidDate(calendar[row][col]))
1144
+ classes.push("off", "disabled");
1145
+ if (this.#startDate != null && calendar[row][col].hasSame(this.#startDate, "day"))
1146
+ classes.push("active", "start-date");
1147
+ if (this.#endDate != null && calendar[row][col].hasSame(this.#endDate, "day"))
1148
+ classes.push("active", "end-date");
1149
+ if (this.#endDate != null && calendar[row][col] > this.#startDate && calendar[row][col] < this.#endDate)
1150
+ classes.push("in-range");
1151
+ var isCustom = this.isCustomDate(calendar[row][col]);
1152
+ if (isCustom !== false) {
1153
+ if (typeof isCustom === "string")
1154
+ classes.push(isCustom);
1155
+ else
1156
+ Array.prototype.push.apply(classes, isCustom);
1157
+ }
1158
+ if (!classes.includes("disabled"))
1159
+ classes.push("available");
1160
+ html += `<td class="${classes.join(" ")}" data-title="r${row}c${col}">${calendar[row][col].day}</td>`;
1161
+ }
1162
+ html += "</tr>";
1163
+ }
1164
+ this.container.find(".drp-calendar." + side + " .calendar-table tbody").html(html);
1165
+ }
1166
+ /**
1167
+ * Emitted before the TimePicker is rendered.
1168
+ * Useful to remove any manually added elements.
1169
+ * @event
1170
+ * @name "beforeRenderTimePicker.daterangepicker"
1171
+ * @param {DateRangePicker} this - The daterangepicker object
1172
+ */
1173
+ /**
1174
+ * Renders the time pickers
1175
+ * @private
1176
+ * @emits "beforeRenderTimePicker.daterangepicker"
1177
+ */
1178
+ renderTimePicker(side) {
1179
+ if (side === "end" && !this.#endDate) return;
1180
+ var selected, minLimit, minDate, maxDate = this.maxDate;
1181
+ let html = "";
1182
+ if (this.showWeekNumbers || this.showISOWeekNumbers)
1183
+ html += "<th></th>";
1184
+ if (this.maxSpan && (!this.maxDate || this.#startDate.plus(this.maxSpan) < this.maxDate))
1185
+ maxDate = this.#startDate.plus(this.maxSpan);
1186
+ if (this.minSpan && side === "end")
1187
+ minLimit = this.#startDate.plus(this.defaultSpan ?? this.minSpan);
1188
+ if (side === "start") {
1189
+ selected = this.#startDate;
1190
+ minDate = this.minDate;
1191
+ } else if (side === "end") {
1192
+ selected = this.#endDate;
1193
+ minDate = this.#startDate;
1194
+ var timeSelector = this.container.find(".drp-calendar .calendar-time.end-time");
1195
+ if (timeSelector.html() != "") {
1196
+ selected = selected.set({
1197
+ hour: !isNaN(selected.hour) ? selected.hour : timeSelector.find(".hourselect option:selected").val(),
1198
+ minute: !isNaN(selected.minute) ? selected.minute : timeSelector.find(".minuteselect option:selected").val(),
1199
+ second: !isNaN(selected.second) ? selected.second : timeSelector.find(".secondselect option:selected").val()
1200
+ });
1201
+ }
1202
+ if (selected < this.#startDate)
1203
+ selected = this.#startDate;
1204
+ if (maxDate && selected > maxDate)
1205
+ selected = maxDate;
1206
+ }
1207
+ html += `<th colspan="7">`;
1208
+ if (this.externalStyle === "bulma")
1209
+ html += '<div class="select is-small mx-1">';
1210
+ html += '<select class="hourselect">';
1211
+ const ampm = selected.toFormat("a", { locale: "en-US" });
1212
+ let start = 0;
1213
+ if (!this.timePicker24Hour)
1214
+ start = ampm === "AM" ? 1 : 13;
1215
+ for (var i = start; i <= start + 23; i += this.timePickerOpts.hourStep) {
1216
+ let time = selected.set({ hour: i % 24 });
1217
+ let disabled = false;
1218
+ if (minDate && time.set({ minute: 59 }) < minDate)
1219
+ disabled = true;
1220
+ if (maxDate && time.set({ minute: 0 }) > maxDate)
1221
+ disabled = true;
1222
+ if (minLimit && time.endOf("hour") < minLimit)
1223
+ disabled = true;
1224
+ if (!disabled && this.isInvalidTime(time, this.singleDatePicker ? null : side, "hour"))
1225
+ disabled = true;
1226
+ if (this.timePicker24Hour) {
1227
+ if (!disabled && i == selected.hour) {
1228
+ html += `<option value="${i}" selected>${i}</option>`;
1229
+ } else if (disabled) {
1230
+ html += `<option value="${i}" disabled class="disabled">${i}</option>`;
1231
+ } else {
1232
+ html += `<option value="${i}">${i}</option>`;
1233
+ }
1234
+ } else {
1235
+ const i_12 = DateTime.fromFormat(`${i % 24}`, "H").toFormat("h");
1236
+ const i_ampm = DateTime.fromFormat(`${i % 24}`, "H").toFormat("a", { locale: "en-US" });
1237
+ if (ampm == i_ampm) {
1238
+ if (!disabled && i == selected.hour) {
1239
+ html += `<option ampm="${i_ampm}" value="${i % 24}" selected>${i_12}</option>`;
1240
+ } else if (disabled) {
1241
+ html += `<option ampm="${i_ampm}" value="${i % 24}" disabled class="disabled">${i_12}</option>`;
1242
+ } else {
1243
+ html += `<option ampm="${i_ampm}" value="${i % 24}">${i_12}</option>`;
1244
+ }
1245
+ } else {
1246
+ html += `<option ampm="${i_ampm}" hidden="hidden" value="${i % 24}">${i_12}</option>`;
1247
+ }
1248
+ }
1249
+ }
1250
+ html += "</select>";
1251
+ if (this.externalStyle === "bulma")
1252
+ html += "</div>";
1253
+ if (this.timePickerOpts.showMinutes) {
1254
+ html += " : ";
1255
+ if (this.externalStyle === "bulma")
1256
+ html += '<div class="select is-small mx-1">';
1257
+ html += '<select class="minuteselect">';
1258
+ for (var i = 0; i < 60; i += this.timePickerOpts.minuteStep) {
1259
+ var padded = i < 10 ? "0" + i : i;
1260
+ let time = selected.set({ minute: i });
1261
+ let disabled = false;
1262
+ if (minDate && time.set({ second: 59 }) < minDate)
1263
+ disabled = true;
1264
+ if (maxDate && time.set({ second: 0 }) > maxDate)
1265
+ disabled = true;
1266
+ if (minLimit && time.endOf("minute") < minLimit)
1267
+ disabled = true;
1268
+ if (!disabled && this.isInvalidTime(time, this.singleDatePicker ? null : side, "minute"))
1269
+ disabled = true;
1270
+ if (selected.minute == i && !disabled) {
1271
+ html += `<option value="${i}" selected>${padded}</option>`;
1272
+ } else if (disabled) {
1273
+ html += `<option value="${i}" disabled class="disabled">${padded}</option>`;
1274
+ } else {
1275
+ html += `<option value="${i}">${padded}</option>`;
1276
+ }
1277
+ }
1278
+ html += "</select>";
1279
+ if (this.externalStyle === "bulma")
1280
+ html += "</div>";
1281
+ }
1282
+ if (this.timePickerOpts.showSeconds) {
1283
+ html += " : ";
1284
+ if (this.externalStyle === "bulma")
1285
+ html += '<div class="select is-small mx-1">';
1286
+ html += '<select class="secondselect">';
1287
+ for (var i = 0; i < 60; i += this.timePickerOpts.secondStep) {
1288
+ var padded = i < 10 ? "0" + i : i;
1289
+ let time = selected.set({ second: i });
1290
+ let disabled = false;
1291
+ if (minDate && time < minDate)
1292
+ disabled = true;
1293
+ if (maxDate && time > maxDate)
1294
+ disabled = true;
1295
+ if (minLimit && time < minLimit)
1296
+ disabled = true;
1297
+ if (!disabled && this.isInvalidTime(time, this.singleDatePicker ? null : side, "second"))
1298
+ disabled = true;
1299
+ if (selected.second == i && !disabled) {
1300
+ html += `<option value="${i}" selected>${padded}</option>`;
1301
+ } else if (disabled) {
1302
+ html += `<option value="${i}" disabled class="disabled">${padded}</option>`;
1303
+ } else {
1304
+ html += `<option value="${i}">${padded}</option>`;
1305
+ }
1306
+ }
1307
+ html += "</select>";
1308
+ if (this.externalStyle === "bulma")
1309
+ html += "</div>";
1310
+ }
1311
+ if (!this.timePicker24Hour) {
1312
+ if (this.externalStyle === "bulma")
1313
+ html += '<div class="select is-small mx-1">';
1314
+ html += '<select class="ampmselect">';
1315
+ var am_html = "";
1316
+ var pm_html = "";
1317
+ let disabled = false;
1318
+ if (minDate && selected.startOf("day") < minDate)
1319
+ disabled = true;
1320
+ if (maxDate && selected.endOf("day") > maxDate)
1321
+ disabled = true;
1322
+ if (minLimit && selected.startOf("day") < minLimit)
1323
+ disabled = true;
1324
+ if (disabled) {
1325
+ am_html = ' disabled class="disabled "';
1326
+ pm_html = ' disabled class="disabled"';
1327
+ } else {
1328
+ if (this.isInvalidTime(selected, this.singleDatePicker ? null : side, "ampm")) {
1329
+ if (selected.toFormat("a", { locale: "en-US" }) === "AM") {
1330
+ pm_html = ' disabled class="disabled"';
1331
+ } else {
1332
+ am_html = ' disabled class="disabled"';
1333
+ }
1334
+ }
1335
+ }
1336
+ html += `<option value="AM"${am_html}`;
1337
+ if (selected.toFormat("a", { locale: "en-US" }) === "AM")
1338
+ html += " selected";
1339
+ html += `>${Info.meridiems()[0]}</option><option value="PM"${pm_html}`;
1340
+ if (selected.toFormat("a", { locale: "en-US" }) === "PM")
1341
+ html += " selected";
1342
+ html += `>${Info.meridiems()[1]}</option>`;
1343
+ html += "</select>";
1344
+ if (this.externalStyle === "bulma")
1345
+ html += "</div>";
1346
+ }
1347
+ html += "</div></th>";
1348
+ this.container.find(`.drp-calendar .calendar-time.${side}-time`).html(html);
1349
+ }
1350
+ /**
1351
+ * Disable the `Apply` button if no date value is selected
1352
+ * @private
1353
+ */
1354
+ setApplyBtnState() {
1355
+ if (this.singleDatePicker || this.#endDate && this.#startDate <= this.#endDate) {
1356
+ this.container.find("button.applyBtn").prop("disabled", false);
1357
+ } else {
1358
+ this.container.find("button.applyBtn").prop("disabled", true);
1359
+ }
1360
+ }
1361
+ /**
1362
+ * Place the picker at the right place in the document
1363
+ * @private
1364
+ */
1365
+ move() {
1366
+ var parentOffset = { top: 0, left: 0 }, containerTop, drops = this.drops;
1367
+ var parentRightEdge = $(window).width();
1368
+ if (!this.parentEl.is("body")) {
1369
+ parentOffset = {
1370
+ top: this.parentEl.offset().top - this.parentEl.scrollTop(),
1371
+ left: this.parentEl.offset().left - this.parentEl.scrollLeft()
1372
+ };
1373
+ parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;
1374
+ }
1375
+ switch (drops) {
1376
+ case "auto":
1377
+ containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
1378
+ if (containerTop + this.container.outerHeight() >= this.parentEl[0].scrollHeight) {
1379
+ containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
1380
+ drops = "up";
1381
+ }
1382
+ break;
1383
+ case "up":
1384
+ containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
1385
+ break;
1386
+ default:
1387
+ containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
1388
+ break;
1389
+ }
1390
+ this.container.css({
1391
+ top: 0,
1392
+ left: 0,
1393
+ right: "auto"
1394
+ });
1395
+ var containerWidth = this.container.outerWidth();
1396
+ this.container.toggleClass("drop-up", drops === "up");
1397
+ if (this.opens === "left") {
1398
+ var containerRight = parentRightEdge - this.element.offset().left - this.element.outerWidth();
1399
+ if (containerWidth + containerRight > $(window).width()) {
1400
+ this.container.css({
1401
+ top: containerTop,
1402
+ right: "auto",
1403
+ left: 9
1404
+ });
1405
+ } else {
1406
+ this.container.css({
1407
+ top: containerTop,
1408
+ right: containerRight,
1409
+ left: "auto"
1410
+ });
1411
+ }
1412
+ } else if (this.opens === "center") {
1413
+ var containerLeft = this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2 - containerWidth / 2;
1414
+ if (containerLeft < 0) {
1415
+ this.container.css({
1416
+ top: containerTop,
1417
+ right: "auto",
1418
+ left: 9
1419
+ });
1420
+ } else if (containerLeft + containerWidth > $(window).width()) {
1421
+ this.container.css({
1422
+ top: containerTop,
1423
+ left: "auto",
1424
+ right: 0
1425
+ });
1426
+ } else {
1427
+ this.container.css({
1428
+ top: containerTop,
1429
+ left: containerLeft,
1430
+ right: "auto"
1431
+ });
1432
+ }
1433
+ } else {
1434
+ var containerLeft = this.element.offset().left - parentOffset.left;
1435
+ if (containerLeft + containerWidth > $(window).width()) {
1436
+ this.container.css({
1437
+ top: containerTop,
1438
+ left: "auto",
1439
+ right: 0
1440
+ });
1441
+ } else {
1442
+ this.container.css({
1443
+ top: containerTop,
1444
+ left: containerLeft,
1445
+ right: "auto"
1446
+ });
1447
+ }
1448
+ }
1449
+ }
1450
+ /**
1451
+ * Shows the picker
1452
+ * @emits "show.daterangepicker"
1453
+ */
1454
+ show() {
1455
+ if (this.isShowing) return;
1456
+ this._outsideClickProxy = function(e) {
1457
+ this.outsideClick(e);
1458
+ }.bind(this);
1459
+ $(document).on("mousedown.daterangepicker", this._outsideClickProxy).on("touchend.daterangepicker", this._outsideClickProxy).on("click.daterangepicker", "[data-toggle=dropdown]", this._outsideClickProxy).on("focusin.daterangepicker", this._outsideClickProxy);
1460
+ $(window).on("resize.daterangepicker", function(e) {
1461
+ this.move(e);
1462
+ }.bind(this));
1463
+ this.oldStartDate = this.#startDate;
1464
+ this.oldEndDate = this.#endDate;
1465
+ this.updateView();
1466
+ this.container.show();
1467
+ this.move();
1468
+ this.element.trigger("show.daterangepicker", this);
1469
+ this.isShowing = true;
1470
+ }
1471
+ /**
1472
+ * Hides the picker
1473
+ * @emits "beforeHide.daterangepicker"
1474
+ * @emits "hide.daterangepicker"
1475
+ */
1476
+ hide() {
1477
+ if (!this.isShowing) return;
1478
+ if (!this.#endDate) {
1479
+ this.#startDate = this.oldStartDate;
1480
+ this.#endDate = this.oldEndDate;
1481
+ }
1482
+ if (this.#startDate != this.oldStartDate || this.#endDate != this.oldEndDate)
1483
+ this.callback(this.startDate, this.endDate, this.chosenLabel);
1484
+ this.updateElement();
1485
+ if (this.element.triggerHandler("beforeHide.daterangepicker", this))
1486
+ return;
1487
+ $(document).off(".daterangepicker");
1488
+ $(window).off(".daterangepicker");
1489
+ this.container.hide();
1490
+ this.element.trigger("hide.daterangepicker", this);
1491
+ this.isShowing = false;
1492
+ }
1493
+ /**
1494
+ * Toggles visibility of the picker
1495
+ */
1496
+ toggle() {
1497
+ if (this.isShowing) {
1498
+ this.hide();
1499
+ } else {
1500
+ this.show();
1501
+ }
1502
+ }
1503
+ /**
1504
+ * Closes the picker when user clicks outside
1505
+ * @param {external:jQuery} e - The Event target
1506
+ * @emits "outsideClick.daterangepicker"
1507
+ * @private
1508
+ */
1509
+ outsideClick(e) {
1510
+ var target = $(e.target);
1511
+ if (
1512
+ // ie modal dialog fix
1513
+ e.type === "focusin" || target.closest(this.element).length || target.closest(this.container).length || target.closest(".calendar-table").length
1514
+ ) return;
1515
+ if (this.onOutsideClick === "cancel") {
1516
+ this.#startDate = this.oldStartDate;
1517
+ this.#endDate = this.oldEndDate;
1518
+ }
1519
+ this.hide();
1520
+ this.element.trigger("outsideClick.daterangepicker", this);
1521
+ }
1522
+ /**
1523
+ * Shows calendar when user selects "Custom Ranges"
1524
+ * @emits "showCalendar.daterangepicker"
1525
+ */
1526
+ showCalendars() {
1527
+ this.container.addClass("show-calendar");
1528
+ this.move();
1529
+ this.element.trigger("showCalendar.daterangepicker", this);
1530
+ }
1531
+ /**
1532
+ * Hides calendar when user selects a predefined range
1533
+ * @emits "hideCalendar.daterangepicker"
1534
+ */
1535
+ hideCalendars() {
1536
+ this.container.removeClass("show-calendar");
1537
+ this.element.trigger("hideCalendar.daterangepicker", this);
1538
+ }
1539
+ /**
1540
+ * Set date values after user selected a date
1541
+ * @param {external:jQuery} e - The Event target
1542
+ * @private
1543
+ */
1544
+ clickRange(e) {
1545
+ var label = e.target.getAttribute("data-range-key");
1546
+ this.chosenLabel = label;
1547
+ if (label == this.locale.customRangeLabel) {
1548
+ this.showCalendars();
1549
+ } else {
1550
+ var dates = this.ranges[label];
1551
+ this.#startDate = dates[0];
1552
+ this.#endDate = dates[1];
1553
+ if (!this.timePicker) {
1554
+ this.#startDate.startOf("day");
1555
+ this.#endDate.endOf("day");
1556
+ }
1557
+ if (!this.alwaysShowCalendars)
1558
+ this.hideCalendars();
1559
+ if (this.element.triggerHandler("beforeHide.daterangepicker", this))
1560
+ this.updateView();
1561
+ this.clickApply();
1562
+ }
1563
+ }
1564
+ /**
1565
+ * Move calendar to previous month
1566
+ * @param {external:jQuery} e - The Event target
1567
+ * @private
1568
+ */
1569
+ clickPrev(e) {
1570
+ var cal = $(e.target).parents(".drp-calendar");
1571
+ if (cal.hasClass("left")) {
1572
+ this.leftCalendar.month = this.leftCalendar.month.minus({ month: 1 });
1573
+ if (this.linkedCalendars && !this.singleMonthView)
1574
+ this.rightCalendar.month = this.rightCalendar.month.minus({ month: 1 });
1575
+ } else {
1576
+ this.rightCalendar.month = this.rightCalendar.month.minus({ month: 1 });
1577
+ }
1578
+ this.updateCalendars();
1579
+ }
1580
+ /**
1581
+ * Move calendar to next month
1582
+ * @param {external:jQuery} e - The Event target
1583
+ * @private
1584
+ */
1585
+ clickNext(e) {
1586
+ var cal = $(e.target).parents(".drp-calendar");
1587
+ if (cal.hasClass("left")) {
1588
+ this.leftCalendar.month = this.leftCalendar.month.plus({ month: 1 });
1589
+ } else {
1590
+ this.rightCalendar.month = this.rightCalendar.month.plus({ month: 1 });
1591
+ if (this.linkedCalendars)
1592
+ this.leftCalendar.month = this.leftCalendar.month.plus({ month: 1 });
1593
+ }
1594
+ this.updateCalendars();
1595
+ }
1596
+ /**
1597
+ * User hovers over date values
1598
+ * @param {external:jQuery} e - The Event target
1599
+ * @private
1600
+ */
1601
+ hoverDate(e) {
1602
+ if (!$(e.target).hasClass("available")) return;
1603
+ let title = $(e.target).attr("data-title");
1604
+ const row = title.substring(1, 2);
1605
+ const col = title.substring(3, 4);
1606
+ const cal = $(e.target).parents(".drp-calendar");
1607
+ var date = cal.hasClass("left") ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1608
+ const leftCalendar = this.leftCalendar;
1609
+ const rightCalendar = this.rightCalendar;
1610
+ const startDate = this.#startDate;
1611
+ const initalMonth = this.initalMonth;
1612
+ if (!this.#endDate) {
1613
+ this.container.find(".drp-calendar tbody td").each(function(index, el) {
1614
+ if ($(el).hasClass("week")) return;
1615
+ const title2 = $(el).attr("data-title");
1616
+ const row2 = title2.substring(1, 2);
1617
+ const col2 = title2.substring(3, 4);
1618
+ const cal2 = $(el).parents(".drp-calendar");
1619
+ const dt = cal2.hasClass("left") ? leftCalendar.calendar[row2][col2] : rightCalendar.calendar[row2][col2];
1620
+ if (!startDate && initalMonth) {
1621
+ $(el).removeClass("in-range");
1622
+ } else {
1623
+ if (dt > startDate && dt < date || dt.hasSame(date, "day")) {
1624
+ $(el).addClass("in-range");
1625
+ } else {
1626
+ $(el).removeClass("in-range");
1627
+ }
1628
+ }
1629
+ });
1630
+ }
1631
+ }
1632
+ /**
1633
+ * User hovers over ranges
1634
+ * @param {external:jQuery} e - The Event target
1635
+ * @private
1636
+ */
1637
+ hoverRange(e) {
1638
+ const label = e.target.getAttribute("data-range-key");
1639
+ const previousDates = [this.#startDate, this.#endDate];
1640
+ const dates = this.ranges[label] ?? [this.#startDate, this.#endDate];
1641
+ const leftCalendar = this.leftCalendar;
1642
+ const rightCalendar = this.rightCalendar;
1643
+ this.container.find(".drp-calendar tbody td").each(function(index, el) {
1644
+ if ($(el).hasClass("week")) return;
1645
+ const title = $(el).attr("data-title");
1646
+ const row = title.substring(1, 2);
1647
+ const col = title.substring(3, 4);
1648
+ const cal = $(el).parents(".drp-calendar");
1649
+ const dt = cal.hasClass("left") ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
1650
+ let classAdded = false;
1651
+ if (dt.hasSame(dates[0], "day"))
1652
+ classAdded = $(el).addClass("start-hover").length > 0;
1653
+ if (dt.hasSame(previousDates[0], "day"))
1654
+ classAdded = $(el).addClass("start-date").length > 0;
1655
+ if (dt.hasSame(dates[1], "day"))
1656
+ classAdded = $(el).addClass("end-hover").length > 0;
1657
+ if (previousDates[1] != null && dt.hasSame(previousDates[1], "day"))
1658
+ classAdded = $(el).addClass("end-date").length > 0;
1659
+ if (dt.startOf("day") >= dates[0].startOf("day") && dt.startOf("day") <= dates[1].startOf("day"))
1660
+ classAdded = $(el).addClass("range-hover").length > 0;
1661
+ if (dt.startOf("day") >= previousDates[0].startOf("day") && previousDates[1] != null && dt.startOf("day") <= previousDates[1].startOf("day"))
1662
+ classAdded = $(el).addClass("in-range").length > 0;
1663
+ if (!classAdded) {
1664
+ $(el).removeClass("start-hover");
1665
+ $(el).removeClass("end-hover");
1666
+ $(el).removeClass("start-date");
1667
+ $(el).removeClass("end-date");
1668
+ $(el).removeClass("in-range");
1669
+ $(el).removeClass("range-hover");
1670
+ }
1671
+ });
1672
+ }
1673
+ /**
1674
+ * User leave ranges, remove hightlight from dates
1675
+ * @param {external:jQuery} e - The Event target
1676
+ * @private
1677
+ */
1678
+ leaveRange(e) {
1679
+ this.container.find(".drp-calendar tbody td").each(function(index, el) {
1680
+ if ($(el).hasClass("week")) return;
1681
+ $(el).removeClass("start-hover");
1682
+ $(el).removeClass("end-hover");
1683
+ $(el).removeClass("range-hover");
1684
+ });
1685
+ }
1686
+ /**
1687
+ * User clicked a date
1688
+ * @param {external:jQuery} e - The Event target
1689
+ * @emits "dateChange.daterangepicker"
1690
+ * @private
1691
+ */
1692
+ clickDate(e) {
1693
+ if (!$(e.target).hasClass("available")) return;
1694
+ var title = $(e.target).attr("data-title");
1695
+ var row = title.substring(1, 2);
1696
+ var col = title.substring(3, 4);
1697
+ var cal = $(e.target).parents(".drp-calendar");
1698
+ var date = cal.hasClass("left") ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
1699
+ let side;
1700
+ if (this.#endDate || !this.#startDate || date < this.#startDate.startOf("day")) {
1701
+ if (this.timePicker) {
1702
+ let hour = parseInt(this.container.find(".start-time .hourselect").val(), 10);
1703
+ if (isNaN(hour))
1704
+ hour = parseInt(this.container.find(".start-time .hourselect option:last").val(), 10);
1705
+ let minute = 0;
1706
+ if (this.timePickerOpts.showMinutes) {
1707
+ minute = parseInt(this.container.find(".start-time .minuteselect").val(), 10);
1708
+ if (isNaN(minute))
1709
+ minute = parseInt(this.container.find(".start-time .minuteselect option:last").val(), 10);
1710
+ }
1711
+ let second = 0;
1712
+ if (this.timePickerOpts.showSeconds) {
1713
+ second = parseInt(this.container.find(".start-time .secondselect").val(), 10);
1714
+ if (isNaN(second))
1715
+ second = parseInt(this.container.find(".start-time .secondselect option:last").val(), 10);
1716
+ }
1717
+ date = date.set({ hour, minute, second });
1718
+ } else {
1719
+ date = date.startOf("day");
1720
+ }
1721
+ this.#endDate = null;
1722
+ this.#startDate = date;
1723
+ side = "start";
1724
+ } else if (!this.#endDate && date < this.#startDate) {
1725
+ this.#endDate = this.#startDate;
1726
+ side = "end";
1727
+ } else {
1728
+ if (this.timePicker) {
1729
+ let hour = parseInt(this.container.find(".end-time .hourselect").val(), 10);
1730
+ if (isNaN(hour))
1731
+ hour = parseInt(this.container.find(".end-time .hourselect option:last").val(), 10);
1732
+ let minute = 0;
1733
+ if (this.timePickerOpts.showMinutes) {
1734
+ minute = parseInt(this.container.find(".end-time .minuteselect").val(), 10);
1735
+ if (isNaN(minute))
1736
+ minute = parseInt(this.container.find(".end-time .minuteselect option:last").val(), 10);
1737
+ }
1738
+ let second = 0;
1739
+ if (this.timePickerOpts.showSeconds) {
1740
+ second = parseInt(this.container.find(".end-time .secondselect").val(), 10);
1741
+ if (isNaN(second))
1742
+ second = parseInt(this.container.find(".end-time .secondselect option:last").val(), 10);
1743
+ }
1744
+ date = date.set({ hour, minute, second });
1745
+ } else {
1746
+ date = date.endOf("day");
1747
+ }
1748
+ this.#endDate = date;
1749
+ if (this.autoApply) {
1750
+ this.calculateChosenLabel();
1751
+ this.clickApply();
1752
+ }
1753
+ side = "end";
1754
+ }
1755
+ if (this.singleDatePicker) {
1756
+ this.#endDate = this.#startDate;
1757
+ if (!this.timePicker && this.autoApply)
1758
+ this.clickApply();
1759
+ side = null;
1760
+ }
1761
+ this.updateView();
1762
+ e.stopPropagation();
1763
+ if (this.autoUpdateInput)
1764
+ this.updateElement();
1765
+ this.element.trigger("dateChange.daterangepicker", [this, side]);
1766
+ }
1767
+ /**
1768
+ * Hightlight selected predefined range in calendar
1769
+ * @private
1770
+ */
1771
+ calculateChosenLabel() {
1772
+ var customRange = true;
1773
+ var i = 0;
1774
+ for (var range in this.ranges) {
1775
+ var unit = this.timePicker ? "hour" : "day";
1776
+ if (this.timePicker) {
1777
+ if (this.timePickerOpts.showMinutes) {
1778
+ unit = "minute";
1779
+ } else if (this.timePickerOpts.showSeconds) {
1780
+ unit = "second";
1781
+ }
1782
+ }
1783
+ if (this.#startDate.startOf(unit).equals(this.ranges[range][0].startOf(unit)) && this.#endDate.startOf(unit).equals(this.ranges[range][1].startOf(unit))) {
1784
+ customRange = false;
1785
+ this.chosenLabel = this.container.find(".ranges li:eq(" + i + ")").addClass("active").attr("data-range-key");
1786
+ break;
1787
+ }
1788
+ i++;
1789
+ }
1790
+ if (customRange) {
1791
+ if (this.showCustomRangeLabel) {
1792
+ this.chosenLabel = this.container.find(".ranges li:last").addClass("active").attr("data-range-key");
1793
+ } else {
1794
+ this.chosenLabel = null;
1795
+ }
1796
+ this.showCalendars();
1797
+ }
1798
+ }
1799
+ /**
1800
+ * User clicked `Apply` button
1801
+ * @emits "apply.daterangepicker"
1802
+ * @private
1803
+ */
1804
+ clickApply() {
1805
+ this.hide();
1806
+ this.element.trigger("apply.daterangepicker", this);
1807
+ }
1808
+ /**
1809
+ * User clicked `Cancel` button
1810
+ * @emits "cancel.daterangepicker"
1811
+ * @private
1812
+ */
1813
+ clickCancel() {
1814
+ this.#startDate = this.oldStartDate;
1815
+ this.#endDate = this.oldEndDate;
1816
+ this.hide();
1817
+ this.element.trigger("cancel.daterangepicker", this);
1818
+ }
1819
+ /**
1820
+ * Calender month moved
1821
+ * @param {external:jQuery} e - The Event target
1822
+ * @private
1823
+ */
1824
+ monthOrYearChanged(e) {
1825
+ var isLeft = $(e.target).closest(".drp-calendar").hasClass("left"), leftOrRight = isLeft ? "left" : "right", cal = this.container.find(".drp-calendar." + leftOrRight);
1826
+ var month = parseInt(cal.find(".monthselect").val(), 10);
1827
+ var year = cal.find(".yearselect").val();
1828
+ if (!isLeft) {
1829
+ if (year < this.#startDate.year || year == this.#startDate.year && month < this.#startDate.month) {
1830
+ month = this.#startDate.month;
1831
+ year = this.#startDate.year;
1832
+ }
1833
+ }
1834
+ if (this.minDate) {
1835
+ if (year < this.minDate.year || year == this.minDate.year && month < this.minDate.month) {
1836
+ month = this.minDate.month;
1837
+ year = this.minDate.year;
1838
+ }
1839
+ }
1840
+ if (this.maxDate) {
1841
+ if (year > this.maxDate.year || year == this.maxDate.year && month > this.maxDate.month) {
1842
+ month = this.maxDate.month;
1843
+ year = this.maxDate.year;
1844
+ }
1845
+ }
1846
+ if (isLeft) {
1847
+ this.leftCalendar.month = this.leftCalendar.month.set({ year, month });
1848
+ if (this.linkedCalendars)
1849
+ this.rightCalendar.month = this.leftCalendar.month.plus({ month: 1 });
1850
+ } else {
1851
+ this.rightCalendar.month = this.rightCalendar.month.set({ year, month });
1852
+ if (this.linkedCalendars)
1853
+ this.leftCalendar.month = this.rightCalendar.month.minus({ month: 1 });
1854
+ }
1855
+ this.updateCalendars();
1856
+ }
1857
+ /**
1858
+ * User clicked a time
1859
+ * @param {external:jQuery} e - The Event target
1860
+ * @emits "timeChange.daterangepicker"
1861
+ * @private
1862
+ */
1863
+ timeChanged(e) {
1864
+ const time = $(e.target).closest(".calendar-time");
1865
+ ;
1866
+ const side = time.hasClass("start-time") ? "start" : "end";
1867
+ var hour = parseInt(time.find(".hourselect").val(), 10);
1868
+ if (isNaN(hour))
1869
+ hour = parseInt(time.find(".hourselect option:last").val(), 10);
1870
+ if (!this.timePicker24Hour) {
1871
+ const ampm = time.find(".ampmselect").val();
1872
+ if (ampm == null)
1873
+ time.find(".ampmselect option:last").val();
1874
+ if (ampm != DateTime.fromFormat(`${hour}`, "H").toFormat("a", { locale: "en-US" })) {
1875
+ time.find(".hourselect > option").each(function() {
1876
+ const hidden = $(this).attr("hidden") || false;
1877
+ $(this).attr("hidden", hidden);
1878
+ });
1879
+ const h = DateTime.fromFormat(`${hour}`, "H").toFormat("h");
1880
+ hour = DateTime.fromFormat(`${h}${ampm}`, "ha", { locale: "en-US" }).hour;
1881
+ }
1882
+ }
1883
+ var minute = 0;
1884
+ if (this.timePickerOpts.showMinutes) {
1885
+ minute = parseInt(time.find(".minuteselect").val(), 10);
1886
+ if (isNaN(minute))
1887
+ minute = parseInt(time.find(".minuteselect option:last").val(), 10);
1888
+ }
1889
+ var second = 0;
1890
+ if (this.timePickerOpts.showSeconds) {
1891
+ second = parseInt(time.find(".secondselect").val(), 10);
1892
+ if (isNaN(second))
1893
+ second = parseInt(time.find(".secondselect option:last").val(), 10);
1894
+ }
1895
+ if (side === "start") {
1896
+ if (this.#startDate)
1897
+ this.#startDate = this.#startDate.set({ hour, minute, second });
1898
+ if (this.singleDatePicker) {
1899
+ this.#endDate = this.#startDate;
1900
+ } else if (this.#endDate && this.#endDate.hasSame(this.#startDate, "day") && this.#endDate < this.#startDate) {
1901
+ this.#endDate = this.#startDate;
1902
+ }
1903
+ } else if (this.#endDate) {
1904
+ this.#endDate = this.#endDate.set({ hour, minute, second });
1905
+ }
1906
+ this.updateCalendars();
1907
+ this.setApplyBtnState();
1908
+ this.element.trigger("beforeRenderTimePicker.daterangepicker", this);
1909
+ this.renderTimePicker("start");
1910
+ this.renderTimePicker("end");
1911
+ if (this.autoUpdateInput)
1912
+ this.updateElement();
1913
+ this.element.trigger("timeChange.daterangepicker", [this, this.singleDatePicker ? null : side]);
1914
+ }
1915
+ /**
1916
+ * Update the picker with value from `<input>` element.<br>
1917
+ * Input values must be given in format of `locale.format`. Invalid values are handles by `violated.daterangepicker` Event
1918
+ * @emits "inputChanged.daterangepicker"
1919
+ * @private
1920
+ */
1921
+ elementChanged() {
1922
+ if (!this.element.is("input:text")) return;
1923
+ if (!this.element.val().length) return;
1924
+ const format = typeof this.locale.format === "string" ? this.locale.format : DateTime.parseFormatForOpts(this.locale.format);
1925
+ const dateString = this.element.val().split(this.locale.separator);
1926
+ if (this.singleDatePicker) {
1927
+ let newDate = DateTime.fromFormat(this.element.val(), format, { locale: DateTime.now().locale });
1928
+ const oldDate = this.#startDate;
1929
+ if (!newDate.isValid || oldDate.equals(newDate))
1930
+ return;
1931
+ const violations = this.validateInput([newDate, null], true);
1932
+ if (violations != null) {
1933
+ if (violations.newDate != null) {
1934
+ newDate = violations.newDate.startDate;
1935
+ } else {
1936
+ return null;
1937
+ }
1938
+ }
1939
+ this.#startDate = newDate;
1940
+ this.#endDate = this.#startDate;
1941
+ } else if (!this.singleDatePicker && dateString.length === 2) {
1942
+ const newDate = [1, 2].map((i) => DateTime.fromFormat(dateString[i], format, { locale: DateTime.now().locale }));
1943
+ const oldDate = [this.#startDate, this.#endDate];
1944
+ if (!newDate[0].isValid || !newDate[1].isValid || (oldDate[0].equals(newDate[0]) && oldDate[1].equals(newDate[1]) || newDate[1] > newDate[0]))
1945
+ return;
1946
+ const violations = this.validateInput([newDate[0], newDate[1]], true);
1947
+ if (violations != null) {
1948
+ if (violations.newDate != null) {
1949
+ newDate[0] = violations.newDate.startDate;
1950
+ newDate[1] = violations.newDate.endDate;
1951
+ } else {
1952
+ return;
1953
+ }
1954
+ }
1955
+ this.#startDate = newDate[0];
1956
+ this.#endDate = newDate[1];
1957
+ } else {
1958
+ return;
1959
+ }
1960
+ this.updateView();
1961
+ this.updateElement();
1962
+ this.element.trigger("inputChanged.daterangepicker", this);
1963
+ }
1964
+ /**
1965
+ * Handles key press, IE 11 compatibility
1966
+ * @param {external:jQuery} e - The Event target
1967
+ * @private
1968
+ */
1969
+ keydown(e) {
1970
+ if (e.keyCode === 9 || e.keyCode === 13) {
1971
+ this.hide();
1972
+ }
1973
+ if (e.keyCode === 27) {
1974
+ e.preventDefault();
1975
+ e.stopPropagation();
1976
+ this.hide();
1977
+ }
1978
+ }
1979
+ /**
1980
+ * Update attached `<input>` element with selected value
1981
+ * @emits external:change
1982
+ */
1983
+ updateElement() {
1984
+ if (this.#startDate == null && this.initalMonth)
1985
+ return;
1986
+ if (this.element.is("input:text")) {
1987
+ let newValue = this.formatDate(this.#startDate);
1988
+ if (!this.singleDatePicker) {
1989
+ newValue += this.locale.separator;
1990
+ if (this.#endDate)
1991
+ newValue += this.formatDate(this.#endDate);
1992
+ }
1993
+ this.updateAltInput();
1994
+ if (newValue !== this.element.val())
1995
+ this.element.val(newValue).trigger("change");
1996
+ } else {
1997
+ this.updateAltInput();
1998
+ }
1999
+ }
2000
+ /**
2001
+ * Update altInput `<input>` element with selected value
2002
+ */
2003
+ updateAltInput() {
2004
+ if (this.altInput == null)
2005
+ return;
2006
+ if (this.singleDatePicker)
2007
+ $(this.altInput[1]).val(null);
2008
+ if (this.altFormat == null) {
2009
+ let precision = "day";
2010
+ if (this.timePicker) {
2011
+ if (this.timePickerOpts.showSeconds) {
2012
+ precision = "second";
2013
+ } else if (this.timePickerOpts.showMinutes) {
2014
+ precision = "minute";
2015
+ } else {
2016
+ precision = "hour";
2017
+ }
2018
+ }
2019
+ const startDate = this.#startDate.toISO({ format: "basic", precision, includeOffset: false });
2020
+ $(this.singleDatePicker ? this.altInput : this.altInput[0]).val(startDate);
2021
+ if (!this.singleDatePicker && this.#endDate) {
2022
+ const endDate = this.#endDate.toISO({ format: "basic", precision, includeOffset: false });
2023
+ $(this.altInput[1]).val(endDate);
2024
+ }
2025
+ } else {
2026
+ const startDate = typeof this.altFormat === "function" ? this.altFormat(this.#startDate) : this.formatDate(this.#startDate, this.altFormat);
2027
+ $(this.singleDatePicker ? this.altInput : this.altInput[0]).val(startDate);
2028
+ if (!this.singleDatePicker && this.#endDate) {
2029
+ const endDate = typeof this.altFormat === "function" ? this.altFormat(this.#endDate) : this.formatDate(this.#endDate, this.altFormat);
2030
+ $(this.altInput[1]).val(endDate);
2031
+ }
2032
+ }
2033
+ }
2034
+ /**
2035
+ * Removes the picker from document
2036
+ */
2037
+ remove() {
2038
+ this.container.remove();
2039
+ this.element.off(".daterangepicker");
2040
+ this.element.removeData();
2041
+ }
2042
+ }
2043
+ if (!$.fn.daterangepicker) {
2044
+ $.fn.daterangepicker = function(options, callback) {
2045
+ const implementOptions = $.extend(true, {}, $.fn.daterangepicker.defaultOptions, options);
2046
+ this.each(function() {
2047
+ const el = $(this);
2048
+ if (el.data("daterangepicker"))
2049
+ el.data("daterangepicker").remove();
2050
+ el.data("daterangepicker", new DateRangePicker(el, implementOptions, callback));
2051
+ });
2052
+ return this;
2053
+ };
2054
+ }
2055
+ })();