@wernfried/daterangepicker 5.6.1 → 5.7.1

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.
package/API_Doc.md CHANGED
@@ -104,6 +104,7 @@ Ranges are not validated against <code>minDate</code>, <code>maxDate</code>, <co
104
104
  * [.setStartDate(startDate, updateView)](#DateRangePicker+setStartDate) ⇒ <code>InputViolation</code>
105
105
  * [.setEndDate(endDate, updateView)](#DateRangePicker+setEndDate) ⇒ <code>InputViolation</code>
106
106
  * [.setRange(startDate, endDate, updateView)](#DateRangePicker+setRange) ⇒ <code>InputViolation</code>
107
+ * [.clearDate(month)](#DateRangePicker+clearDate)
107
108
  * [.parseDate(value)](#DateRangePicker+parseDate) ⇒ [<code>DateTime</code>](https://moment.github.io/luxon/api-docs/index.html#datetime)
108
109
  * [.formatDate(date, format)](#DateRangePicker+formatDate) ⇒ <code>string</code>
109
110
  * [.validateInput(range, dipatch)](#DateRangePicker+validateInput) ⇒ <code>InputViolation</code> \| <code>null</code>
@@ -210,6 +211,18 @@ Invalid date values are handled by [violate](#DateRangePicker+violate) Event
210
211
  const drp = getDateRangePicker('#picker');
211
212
  drp.setRange(DateTime.now().startOf('hour'), DateTime.now().endOf('day'));
212
213
  ```
214
+ <a name="DateRangePicker+clearDate"></a>
215
+
216
+ ### dateRangePicker.clearDate(month)
217
+ Clear selected date values.
218
+ Does not invoke callback function, disables "Apply" button
219
+
220
+ **Kind**: instance method of [<code>DateRangePicker</code>](#DateRangePicker)
221
+
222
+ | Param | Type | Description |
223
+ | --- | --- | --- |
224
+ | month | <code>sting</code> \| [<code>DateTime</code>](https://moment.github.io/luxon/api-docs/index.html#datetime) \| <code>Date</code> | The month to be shown, if null then current month is selected. |
225
+
213
226
  <a name="DateRangePicker+parseDate"></a>
214
227
 
215
228
  ### dateRangePicker.parseDate(value) ⇒ [<code>DateTime</code>](https://moment.github.io/luxon/api-docs/index.html#datetime)
@@ -699,7 +712,7 @@ Options for DateRangePicker
699
712
  | isInvalidDate | <code>function</code> | <code>false</code> | A function that is passed each date in the two calendars before they are displayed,<br> and may return `true` or `false` to indicate whether that date should be available for selection or not.<br> Signature: `isInvalidDate(date)`<br> |
700
713
  | isInvalidTime | <code>function</code> | <code>false</code> | A function that is passed each hour/minute/second/am-pm in the two calendars before they are displayed,<br> and may return `true` or `false` to indicate whether that date should be available for selection or not.<br> Signature: `isInvalidTime(time, side, unit)`<br> `side` is `'start'` or `'end'` or `null` for `singleDatePicker: true`<br> `unit` is `'hour'`, `'minute'`, `'second'` or `'ampm'`<br> Hours are always given as 24-hour clock<br> Ensure that your function returns `false` for at least one item. Otherwise the calender is not rendered.<br> |
701
714
  | isCustomDate | <code>function</code> | <code>false</code> | A function that is passed each date in the two calendars before they are displayed, and may return a string or array of CSS class names to apply to that date's calendar cell.<br> Signature: `isCustomDate(date)` |
702
- | altInput | <code>string</code> \| <code>Array</code> \| [<code>HTMLInputElement</code>](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement) | <code>null</code> | A [Document querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#selectors)<br> string or `HTMLElement` for an alternative output (typically hidden) `<input>` element. Uses `altFormat` to format the value.<br> Must be a single string/HTMLElement for `singleDatePicker: true` or an array of two strings or HTMLElement for `singleDatePicker: false`<br> Example: `['#start', '#end']` |
715
+ | altInput | <code>string</code> \| <code>Array</code> \| [<code>HTMLInputElement</code>](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement) | <code>null</code> | A [Document querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#selectors)<br> string or `HTMLElement` for an alternative output (typically hidden) `<input>` element. Uses `altFormat` to format the value.<br> Must be a single string/HTMLElement for `singleDatePicker: true` or an array of two strings or HTMLElement for `singleDatePicker: false`<br> Example: `['#start', '#end']` |
703
716
  | altFormat | <code>function</code> \| <code>string</code> | | The output format used for `altInput`.<br> Default: ISO-8601 basic format without time zone, precisison is derived from `timePicker` and `timePickerStepSize`<br> Example `yyyyMMdd'T'HHmm` for `timePicker=true` and display of Minutes<br> If defined, either a string used with [Format tokens](https://moment.github.io/luxon/#/formatting?id=table-of-tokens) or a function.<br> Examples: `"yyyy:MM:dd'T'HH:mm"`,<br>`(date) => date.toUnixInteger()` |
704
717
  | applyButtonClasses | <code>string</code> | <code>&quot;btn-primary&quot;</code> | CSS class names that will be added only to the apply button |
705
718
  | cancelButtonClasses | <code>string</code> | <code>&quot;btn-default&quot;</code> | CSS class names that will be added only to the cancel button |
package/README.md CHANGED
@@ -19,8 +19,8 @@ Above samples are based on the [original repository](https://github.com/dangross
19
19
  #### Global import with `<script>` tags
20
20
  ```html
21
21
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/luxon@3.5.0/build/global/luxon.min.js"></script>
22
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.6.1/dist/global/daterangepicker.min.js"></script>
23
- <link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.6.1/css/daterangepicker.min.css" rel="stylesheet" />
22
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.7.1/dist/global/daterangepicker.min.js"></script>
23
+ <link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.7.1/css/daterangepicker.min.css" rel="stylesheet" />
24
24
 
25
25
  <input type="text" id="picker" />
26
26
 
@@ -40,11 +40,11 @@ Above samples are based on the [original repository](https://github.com/dangross
40
40
  {
41
41
  "imports": {
42
42
  "luxon": "https://cdn.jsdelivr.net/npm/luxon@3.7.2/+esm",
43
- "daterangepicker": "https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.6.1/+esm"
43
+ "daterangepicker": "https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.7.1/+esm"
44
44
  }
45
45
  }
46
46
  </script>
47
- <link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.6.1/css/daterangepicker.min.css" rel="stylesheet" />
47
+ <link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.7.1/css/daterangepicker.min.css" rel="stylesheet" />
48
48
 
49
49
  <input type="text" id="picker" />
50
50
 
@@ -63,9 +63,9 @@ Above samples are based on the [original repository](https://github.com/dangross
63
63
  #### Style with Bulma
64
64
  ```html
65
65
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/luxon@3.5.0/build/global/luxon.min.js"></script>
66
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.6.1/dist/global/daterangepicker.min.js"></script>
66
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.7.1/dist/global/daterangepicker.min.js"></script>
67
67
  <link type="text/css" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css" rel="stylesheet" />
68
- <link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.6.1/css/daterangepicker.bulma.min.css" rel="stylesheet" />
68
+ <link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.7.1/css/daterangepicker.bulma.min.css" rel="stylesheet" />
69
69
 
70
70
  <input type="text" id="picker" />
71
71
 
@@ -122,8 +122,8 @@ Initialisation with jQuery is supported in version 5.x
122
122
  ```html
123
123
  <script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
124
124
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/luxon@3.5.0/build/global/luxon.min.js"></script>
125
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.6.1/dist/global/daterangepicker.min.js"></script>
126
- <link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.6.1/css/daterangepicker.min.css" rel="stylesheet" />
125
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.7.1/dist/global/daterangepicker.min.js"></script>
126
+ <link type="text/css" href="https://cdn.jsdelivr.net/npm/@wernfried/daterangepicker@5.7.1/css/daterangepicker.min.css" rel="stylesheet" />
127
127
 
128
128
  <input type="text" id="picker" />
129
129
 
@@ -377,7 +377,7 @@ Options for DateRangePicker
377
377
  | isInvalidDate | <code>function</code> | <code>false</code> | A function that is passed each date in the two calendars before they are displayed,<br> and may return `true` or `false` to indicate whether that date should be available for selection or not.<br> Signature: `isInvalidDate(date)`<br> |
378
378
  | isInvalidTime | <code>function</code> | <code>false</code> | A function that is passed each hour/minute/second/am-pm in the two calendars before they are displayed,<br> and may return `true` or `false` to indicate whether that date should be available for selection or not.<br> Signature: `isInvalidTime(time, side, unit)`<br> `side` is `'start'` or `'end'` or `null` for `singleDatePicker: true`<br> `unit` is `'hour'`, `'minute'`, `'second'` or `'ampm'`<br> Hours are always given as 24-hour clock<br> Ensure that your function returns `false` for at least one item. Otherwise the calender is not rendered.<br> |
379
379
  | isCustomDate | <code>function</code> | <code>false</code> | A function that is passed each date in the two calendars before they are displayed, and may return a string or array of CSS class names to apply to that date's calendar cell.<br> Signature: `isCustomDate(date)` |
380
- | altInput | <code>string</code> \| <code>Array</code> \| [<code>HTMLInputElement</code>](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement) | <code>null</code> | A [Document querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#selectors)<br> string or `HTMLElement` for an alternative output (typically hidden) `<input>` element. Uses `altFormat` to format the value.<br> Must be a single string/HTMLElement for `singleDatePicker: true` or an array of two strings or HTMLElement for `singleDatePicker: false`<br> Example: `['#start', '#end']` |
380
+ | altInput | <code>string</code> \| <code>Array</code> \| [<code>HTMLInputElement</code>](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement) | <code>null</code> | A [Document querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#selectors)<br> string or `HTMLElement` for an alternative output (typically hidden) `<input>` element. Uses `altFormat` to format the value.<br> Must be a single string/HTMLElement for `singleDatePicker: true` or an array of two strings or HTMLElement for `singleDatePicker: false`<br> Example: `['#start', '#end']` |
381
381
  | altFormat | <code>function</code> \| <code>string</code> | | The output format used for `altInput`.<br> Default: ISO-8601 basic format without time zone, precisison is derived from `timePicker` and `timePickerStepSize`<br> Example `yyyyMMdd'T'HHmm` for `timePicker=true` and display of Minutes<br> If defined, either a string used with [Format tokens](https://moment.github.io/luxon/#/formatting?id=table-of-tokens) or a function.<br> Examples: `"yyyy:MM:dd'T'HH:mm"`,<br>`(date) => date.toUnixInteger()` |
382
382
  | applyButtonClasses | <code>string</code> | <code>&quot;btn-primary&quot;</code> | CSS class names that will be added only to the apply button |
383
383
  | cancelButtonClasses | <code>string</code> | <code>&quot;btn-default&quot;</code> | CSS class names that will be added only to the cancel button |
@@ -384,8 +384,6 @@ class DateRangePicker {
384
384
  }
385
385
  if (!this.#startDate && this.initialMonth) {
386
386
  this.#endDate = null;
387
- if (this.timePicker)
388
- console.error(`Option 'initialMonth' works only with 'timePicker: false'`);
389
387
  } else {
390
388
  const violations = this.validateInput(null, false);
391
389
  if (violations != null) {
@@ -418,15 +416,15 @@ class DateRangePicker {
418
416
  if (this.singleDatePicker) {
419
417
  if (typeof options.altInput === "string") {
420
418
  const el = document.querySelector(options.altInput);
421
- this.altInput = el instanceof HTMLInputElement && el.type === "text" ? el : null;
419
+ this.altInput = el instanceof HTMLInputElement && ["text", "hidden"].includes(el.type) ? el : null;
422
420
  } else if (options.altInput instanceof HTMLElement) {
423
- this.altInput = options.altInput instanceof HTMLInputElement && options.altInput.type === "text" ? options.altInput : null;
421
+ this.altInput = options.altInput instanceof HTMLInputElement && ["text", "hidden"].includes(options.altInput.type) ? options.altInput : null;
424
422
  }
425
423
  } else if (!this.singleDatePicker && Array.isArray(options.altInput) && options.altInput.length === 2) {
426
424
  this.altInput = [];
427
425
  for (let item of options.altInput) {
428
426
  const el = typeof item === "string" ? document.querySelector(item) : item;
429
- if (el instanceof HTMLInputElement && el.type === "text")
427
+ if (el instanceof HTMLInputElement && ["text", "hidden"].includes(el.type))
430
428
  this.altInput.push(el);
431
429
  }
432
430
  if (this.altInput.length !== 2)
@@ -872,6 +870,31 @@ class DateRangePicker {
872
870
  this.updateView(monthChange);
873
871
  return violations;
874
872
  }
873
+ /**
874
+ * Clear selected date values.
875
+ * Does not invoke callback function, disables "Apply" button
876
+ * @param {sting|external:DateTime|Date} month - The month to be shown, if null then current month is selected.
877
+ */
878
+ clearDate(month) {
879
+ const initialMonth = this.parseDate(month ?? this.#startDate.startOf("month"));
880
+ this.oldStartDate = this.#startDate;
881
+ this.oldEndDate = this.#endDate;
882
+ this.#startDate = null;
883
+ this.#endDate = null;
884
+ if (this.isInputText)
885
+ this.element.value = "";
886
+ if (!this.singleDatePicker)
887
+ this.chosenLabel = null;
888
+ if (this.altInput) {
889
+ if (this.singleDatePicker) {
890
+ this.altInput.value = "";
891
+ } else {
892
+ this.altInput[0].value = "";
893
+ this.altInput[1].value = "";
894
+ }
895
+ }
896
+ this.updateView(!initialMonth.hasSame(this.oldStartDate, "month"));
897
+ }
875
898
  /**
876
899
  * Parse date value
877
900
  * @param {sting|external:DateTime|Date} value - The value to be parsed
@@ -884,7 +907,7 @@ class DateRangePicker {
884
907
  } else if (value instanceof Date) {
885
908
  return luxon.DateTime.fromJSDate(value);
886
909
  } else {
887
- throw RangeError(`Value must be a luxon.DateTime or Date or string`);
910
+ throw RangeError(`Value must be a luxon.DateTime or Date or string. Or use clearDate() to clear date values`);
888
911
  }
889
912
  } else if (typeof value === "string") {
890
913
  const format = typeof this.locale.format === "string" ? this.locale.format : luxon.DateTime.parseFormatForOpts(this.locale.format);
@@ -1214,42 +1237,48 @@ class DateRangePicker {
1214
1237
  updateCalendars(monthChange) {
1215
1238
  if (this.timePicker) {
1216
1239
  var hour, minute, second;
1217
- if (this.#endDate) {
1218
- hour = parseInt(this.container.querySelector(".start-time .hourselect").value, 10);
1219
- if (isNaN(hour))
1220
- hour = parseInt(this.container.querySelector(".start-time .hourselect option:last-child").value, 10);
1221
- minute = 0;
1222
- if (this.timePickerOpts.showMinutes) {
1223
- minute = parseInt(this.container.querySelector(".start-time .minuteselect").value, 10);
1224
- if (isNaN(minute))
1225
- minute = parseInt(this.container.querySelector(".start-time .minuteselect option:last-child").value, 10);
1226
- }
1227
- second = 0;
1228
- if (this.timePickerOpts.showSeconds) {
1229
- second = parseInt(this.container.querySelector(".start-time .secondselect").value, 10);
1230
- if (isNaN(second))
1231
- second = parseInt(this.container.querySelector(".start-time .secondselect option:last-child").value, 10);
1232
- }
1240
+ if (this.#startDate == null && this.#endDate == null) {
1241
+ this.leftCalendar.month = this.leftCalendar.month.set({ hour: 0, minute: 0, second: 0 });
1242
+ if (!this.singleMonthView)
1243
+ this.rightCalendar.month = this.rightCalendar.month.set({ hour: 0, minute: 0, second: 0 });
1233
1244
  } else {
1234
- hour = parseInt(this.container.querySelector(".end-time .hourselect").value, 10);
1235
- if (isNaN(hour))
1236
- hour = parseInt(this.container.querySelector(".end-time .hourselect option:last-child").value, 10);
1237
- minute = 0;
1238
- if (this.timePickerOpts.showMinutes) {
1239
- minute = parseInt(this.container.querySelector(".end-time .minuteselect").value, 10);
1240
- if (isNaN(minute))
1241
- minute = parseInt(this.container.querySelector(".end-time .minuteselect option:last-child").value, 10);
1242
- }
1243
- second = 0;
1244
- if (this.timePickerOpts.showSeconds) {
1245
- second = parseInt(this.container.querySelector(".end-time .secondselect").value, 10);
1246
- if (isNaN(second))
1247
- second = parseInt(this.container.querySelector(".end-time .secondselect option:last-child").value, 10);
1245
+ if (this.#endDate) {
1246
+ hour = parseInt(this.container.querySelector(".start-time .hourselect").value, 10);
1247
+ if (isNaN(hour))
1248
+ hour = parseInt(this.container.querySelector(".start-time .hourselect option:last-child").value, 10);
1249
+ minute = 0;
1250
+ if (this.timePickerOpts.showMinutes) {
1251
+ minute = parseInt(this.container.querySelector(".start-time .minuteselect").value, 10);
1252
+ if (isNaN(minute))
1253
+ minute = parseInt(this.container.querySelector(".start-time .minuteselect option:last-child").value, 10);
1254
+ }
1255
+ second = 0;
1256
+ if (this.timePickerOpts.showSeconds) {
1257
+ second = parseInt(this.container.querySelector(".start-time .secondselect").value, 10);
1258
+ if (isNaN(second))
1259
+ second = parseInt(this.container.querySelector(".start-time .secondselect option:last-child").value, 10);
1260
+ }
1261
+ } else {
1262
+ hour = parseInt(this.container.querySelector(".end-time .hourselect").value, 10);
1263
+ if (isNaN(hour))
1264
+ hour = parseInt(this.container.querySelector(".end-time .hourselect option:last-child").value, 10);
1265
+ minute = 0;
1266
+ if (this.timePickerOpts.showMinutes) {
1267
+ minute = parseInt(this.container.querySelector(".end-time .minuteselect").value, 10);
1268
+ if (isNaN(minute))
1269
+ minute = parseInt(this.container.querySelector(".end-time .minuteselect option:last-child").value, 10);
1270
+ }
1271
+ second = 0;
1272
+ if (this.timePickerOpts.showSeconds) {
1273
+ second = parseInt(this.container.querySelector(".end-time .secondselect").value, 10);
1274
+ if (isNaN(second))
1275
+ second = parseInt(this.container.querySelector(".end-time .secondselect option:last-child").value, 10);
1276
+ }
1248
1277
  }
1278
+ this.leftCalendar.month = this.leftCalendar.month.set({ hour, minute, second });
1279
+ if (!this.singleMonthView)
1280
+ this.rightCalendar.month = this.rightCalendar.month.set({ hour, minute, second });
1249
1281
  }
1250
- this.leftCalendar.month = this.leftCalendar.month.set({ hour, minute, second });
1251
- if (!this.singleMonthView)
1252
- this.rightCalendar.month = this.rightCalendar.month.set({ hour, minute, second });
1253
1282
  } else {
1254
1283
  this.leftCalendar.month = this.leftCalendar.month.set({ hour: 0, minute: 0, second: 0 });
1255
1284
  if (!this.singleMonthView)
@@ -1404,20 +1433,27 @@ class DateRangePicker {
1404
1433
  * @emits "beforeRenderTimePicker"
1405
1434
  */
1406
1435
  renderTimePicker(side) {
1407
- if (side === "end" && !this.#endDate) return;
1436
+ if (side === "end" && !this.#endDate && this.#startDate) return;
1408
1437
  var selected, minLimit, minDate, maxDate = this.maxDate;
1409
1438
  let html = "";
1410
1439
  if (this.showWeekNumbers || this.showISOWeekNumbers)
1411
1440
  html += "<th></th>";
1412
- if (this.maxSpan && (!this.maxDate || this.#startDate.plus(this.maxSpan) < this.maxDate))
1413
- maxDate = this.#startDate.plus(this.maxSpan);
1414
- if (this.minSpan && side === "end")
1415
- minLimit = this.#startDate.plus(this.minSpan);
1441
+ if (this.#startDate) {
1442
+ if (this.maxSpan && (!this.maxDate || this.#startDate.plus(this.maxSpan) < this.maxDate))
1443
+ maxDate = this.#startDate.plus(this.maxSpan);
1444
+ if (this.minSpan && side === "end")
1445
+ minLimit = this.#startDate.plus(this.minSpan);
1446
+ } else {
1447
+ if (this.maxSpan && (!this.maxDate || this.initialMonth.plus(this.maxSpan) < this.maxDate))
1448
+ maxDate = this.initialMonth.plus(this.maxSpan);
1449
+ if (this.minSpan && side === "end")
1450
+ minLimit = this.initialMonth.plus(this.minSpan);
1451
+ }
1416
1452
  if (side === "start") {
1417
- selected = this.#startDate;
1453
+ selected = this.#startDate ?? this.initialMonth.startOf("day");
1418
1454
  minDate = this.minDate;
1419
1455
  } else if (side === "end") {
1420
- selected = this.#endDate;
1456
+ selected = this.#endDate ?? this.initialMonth.startOf("day");
1421
1457
  minDate = this.#startDate;
1422
1458
  let timeSelector = this.container.querySelector(".drp-calendar .calendar-time.end-time");
1423
1459
  if (timeSelector.innerHTML != "") {