@wernfried/daterangepicker 4.17.5 → 4.19.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.
@@ -532,6 +532,160 @@ class DateRangePicker {
532
532
  set endDate(val) {
533
533
  this.#endDate = val;
534
534
  }
535
+ /**
536
+ * DateRangePicker specific events
537
+ */
538
+ #events = {
539
+ /**
540
+ * Emitted when the date is changed through `<input>` element or via {@link #DateRangePicker+setStartDate|setStartDate} or
541
+ * {@link #DateRangePicker+setRange|setRange} and date is not valid due to
542
+ * `minDate`, `maxDate`, `minSpan`, `maxSpan`, `invalidDate` and `invalidTime` constraints.<br>
543
+ * Event is only triggered when date string is valid and date value is changing<br>
544
+ * @event
545
+ * @name "violate.daterangepicker"
546
+ * @param {DateRangePicker} picker - The daterangepicker object
547
+ * @param {InputViolation} result - The violation object, see example of `validateInput()`
548
+ * @param {Object} newDate - Object of {startDate, endDate}
549
+ * @return {boolean}=undefined - If handler returns `true`, then values from `newDate` object are used
550
+ * @example
551
+ *
552
+ * $('#picker').daterangepicker({
553
+ * startDate: DateTime.now(),
554
+ * // allow only dates from current year
555
+ * minDate: DateTime.now().startOf('year'),
556
+ * manDate: DateTime.now().endOf('year'),
557
+ * singleDatePicker: true,
558
+ * locale: {
559
+ * format: DateTime.DATETIME_SHORT
560
+ * }
561
+ * }).on('violate.daterangepicker', (ev, picker, result, newDate) => {
562
+ * newDate.startDate = DateTime.now().minus({ days: 3 }).startOf('day');
563
+ * return true;
564
+ * });
565
+ *
566
+ * // Try to set date outside permitted range at <input> elemet
567
+ * $('#picker').val(DateTime.now().minus({ years: 10 })).toLocaleString(DateTime.DATETIME_SHORT).trigger('keyup');
568
+
569
+ * // Try to set date outside permitted range by code
570
+ * const drp = $('#picker').data('daterangepicker').setStartDate(DateTime.now().minus({ years: 10 })
571
+ *
572
+ * // -> Calendar selects and shows "today - 3 days"
573
+ */
574
+ onViolate: { type: "violate.daterangepicker", param: (...args) => [this, ...args] },
575
+ /**
576
+ * Emitted before the calendar time picker is rendered.
577
+ * @event
578
+ * @name "beforeRenderCalendar.daterangepicker"
579
+ * @param {DateRangePicker} this - The daterangepicker object
580
+ */
581
+ onBeforeRenderTimePicker: { type: "beforeRenderTimePicker.daterangepicker", param: this },
582
+ /**
583
+ * Emitted before the calendar is rendered. Useful to remove any manually added elements.
584
+ * @event
585
+ * @name "beforeRenderCalendar.daterangepicker"
586
+ * @param {DateRangePicker} this - The daterangepicker object
587
+ */
588
+ onBeforeRenderCalendar: { type: "beforeRenderCalendar.daterangepicker", param: this },
589
+ /**
590
+ * Emitted when the picker is shown
591
+ * @event
592
+ * @name "show.daterangepicker"
593
+ * @param {DateRangePicker} this - The daterangepicker object
594
+ */
595
+ onShow: { type: "show.daterangepicker", param: this },
596
+ /**
597
+ * Emitted before the picker will hide. When EventHandler returns `true`, then picker remains visible
598
+ * @event
599
+ * @name "beforeHide.daterangepicker"
600
+ * @param {DateRangePicker} this - The daterangepicker object
601
+ * @return {boolean} cancel - If `true`, then the picker remains visible
602
+ */
603
+ onBeforeHide: { type: "beforeHide.daterangepicker", param: this },
604
+ /**
605
+ * Emitted when the picker is hidden
606
+ * @event
607
+ * @name "hide.daterangepicker"
608
+ * @param {DateRangePicker} this - The daterangepicker object
609
+ */
610
+ onHide: { type: "hide.daterangepicker", param: this },
611
+ /**
612
+ * Emitted when the calendar(s) are shown.
613
+ * Only useful when {@link #Ranges|Ranges} are used.
614
+ * @event
615
+ * @name "showCalendar.daterangepicker"
616
+ * @param {DateRangePicker} this - The daterangepicker object
617
+ */
618
+ onShowCalendar: { type: "showCalendar.daterangepicker", param: this },
619
+ /**
620
+ * Emitted when the calendar(s) are hidden. Only used when {@link #Ranges|Ranges} are used.
621
+ * @event
622
+ * @name "hideCalendar.daterangepicker"
623
+ * @param {DateRangePicker} this - The daterangepicker object
624
+ */
625
+ onHideCalendar: { type: "hideCalendar.daterangepicker", param: this },
626
+ /**
627
+ * Emitted when user clicks outside the picker. Use option `onOutsideClick` to define the default action, then you may not need to handle this event.
628
+ * @event
629
+ * @name "outsideClick.daterangepicker"
630
+ * @param {DateRangePicker} this - The daterangepicker object
631
+ */
632
+ onOutsideClick: { type: "outsideClick.daterangepicker", param: this },
633
+ /**
634
+ * Emitted when the date changed. Does not trigger when time is changed, use {@link #event_timeChange.daterangepicker|"timeChange.daterangepicker"} to handle it
635
+ * @event
636
+ * @name "dateChange.daterangepicker"
637
+ * @param {DateRangePicker} this - The daterangepicker object
638
+ * @param {string} side - Either `'start'` or `'end'` indicating whether startDate or endDate was changed. `null` when `singleDatePicker: true`
639
+ */
640
+ onDateChange: { type: "dateChange.daterangepicker", param: (side) => [this, side] },
641
+ /**
642
+ * Emitted when the time changed. Does not trigger when date is changed
643
+ * @event
644
+ * @name "timeChange.daterangepicker"
645
+ * @param {DateRangePicker} this - The daterangepicker object
646
+ * @param {string} side - Either `'start'` or `'end'` indicating whether startDate or endDate was changed
647
+ */
648
+ onTimeChange: { type: "timeChange.daterangepicker", param: (side) => [this, side] },
649
+ /**
650
+ * Emitted when the `Apply` button is clicked, or when a predefined {@link #Ranges|Ranges} is clicked
651
+ * @event
652
+ * @name "apply.daterangepicker"
653
+ * @param {DateRangePicker} this - The daterangepicker object
654
+ */
655
+ onApply: { type: "apply.daterangepicker", param: this },
656
+ /**
657
+ * Emitted when the `Cancel` button is clicked
658
+ * @event
659
+ * @name "cancel.daterangepicker"
660
+ * @param {DateRangePicker} this - The daterangepicker object
661
+ */
662
+ onCancel: { type: "cancel.daterangepicker", param: this },
663
+ /**
664
+ * Emitted when the date is changed through `<input>` element. Event is only triggered when date string is valid and date value has changed
665
+ * @event
666
+ * @name "inputChange.daterangepicker"
667
+ * @param {DateRangePicker} this - The daterangepicker object
668
+ */
669
+ onInputChange: { type: "inputChange.daterangepicker", param: this },
670
+ /**
671
+ * Emitted after month view changed, for example by click on 'prev' or 'next'
672
+ * @event
673
+ * @name "monthViewChange.daterangepicker"
674
+ * @param {DateRangePicker} this - The daterangepicker object
675
+ * @param {external:DateTime} left - For day of left-hand calendar
676
+ * @param {external:DateTime|null} right - For day of right-hand calendar
677
+ */
678
+ onMonthViewChange: {
679
+ type: "monthViewChange.daterangepicker",
680
+ param: (left, right) => [this, left.startOf("month"), right ? right.startOf("month") : null]
681
+ }
682
+ };
683
+ /**
684
+ * Getter for all DateRangePickerEvents
685
+ */
686
+ get events() {
687
+ return this.#events;
688
+ }
535
689
  /* #region Set startDate/endDate */
536
690
  /**
537
691
  * Sets the date range picker's currently selected start date to the provided date.<br>
@@ -559,6 +713,7 @@ class DateRangePicker {
559
713
  return violations;
560
714
  }
561
715
  }
716
+ const monthChange = !this.#startDate.hasSame(newDate, "month");
562
717
  this.#startDate = newDate;
563
718
  this.#endDate = this.#startDate;
564
719
  if (!this.timePicker) {
@@ -567,7 +722,7 @@ class DateRangePicker {
567
722
  }
568
723
  this.updateElement();
569
724
  if (updateView)
570
- this.updateView();
725
+ this.updateView(monthChange);
571
726
  return violations;
572
727
  }
573
728
  /**
@@ -614,6 +769,7 @@ class DateRangePicker {
614
769
  return violations;
615
770
  }
616
771
  }
772
+ const monthChange = !this.#startDate.hasSame(newDate[0], "month") || !this.#endDate.hasSame(newDate[1], "month");
617
773
  this.#startDate = newDate[0];
618
774
  this.#endDate = newDate[1];
619
775
  if (!this.timePicker) {
@@ -622,7 +778,7 @@ class DateRangePicker {
622
778
  }
623
779
  this.updateElement();
624
780
  if (updateView)
625
- this.updateView();
781
+ this.updateView(monthChange);
626
782
  return violations;
627
783
  }
628
784
  /**
@@ -708,42 +864,6 @@ class DateRangePicker {
708
864
  }
709
865
  }
710
866
  /**
711
- * Emitted when the date is changed through `<input>` element or via {@link #DateRangePicker+setStartDate|setStartDate} or
712
- * {@link #DateRangePicker+setRange|setRange} and date is not valid due to
713
- * `minDate`, `maxDate`, `minSpan`, `maxSpan`, `invalidDate` and `invalidTime` constraints.<br>
714
- * Event is only triggered when date string is valid and date value is changing<br>
715
- * @event
716
- * @name "violated.daterangepicker"
717
- * @param {Object} this - The event object
718
- * @param {DateRangePicker} picker - The daterangepicker object
719
- * @param {InputViolation} result - The violation object, see example of `validateInput()`
720
- * @param {Object} newDate - Object of {startDate, endDate}
721
- * @return {boolean}=undefined - If handler returns `true`, then values from `newDate` object are used
722
- * @example
723
- *
724
- * $('#picker').daterangepicker({
725
- * startDate: DateTime.now(),
726
- * // allow only dates from current year
727
- * minDate: DateTime.now().startOf('year'),
728
- * manDate: DateTime.now().endOf('year'),
729
- * singleDatePicker: true,
730
- * locale: {
731
- * format: DateTime.DATETIME_SHORT
732
- * }
733
- * }).on('violated.daterangepicker', (ev, picker, result, newDate) => {
734
- * newDate.startDate = DateTime.now().minus({ days: 3 }).startOf('day');
735
- * return true;
736
- * });
737
- *
738
- * // Try to set date outside permitted range at <input> elemet
739
- * $('#picker').val(DateTime.now().minus({ years: 10 })).toLocaleString(DateTime.DATETIME_SHORT).trigger('keyup');
740
-
741
- * // Try to set date outside permitted range by code
742
- * const drp = $('#picker').data('daterangepicker').setStartDate(DateTime.now().minus({ years: 10 })
743
- *
744
- * // -> Calendar selects and shows "today - 3 days"
745
- */
746
- /**
747
867
  * @typedef InputViolation
748
868
  * @type {Object}
749
869
  * @property {external:DateTime} startDate - Violation of startDate
@@ -843,7 +963,7 @@ class DateRangePicker {
843
963
  return null;
844
964
  if (dipatch) {
845
965
  let newValues = { startDate };
846
- const ret = this.element.triggerHandler("violated.daterangepicker", [this, result, newValues]);
966
+ const ret = this.triggerHandler(this.#events.onViolate, result, newValues);
847
967
  if (ret) {
848
968
  result.newDate = newValues;
849
969
  return result;
@@ -919,7 +1039,7 @@ class DateRangePicker {
919
1039
  return null;
920
1040
  if (dipatch) {
921
1041
  let newValues = { startDate, endDate };
922
- const ret = this.element.triggerHandler("violated.daterangepicker", [this, result, newValues]);
1042
+ const ret = this.triggerHandler(this.#events.onViolate, result, newValues);
923
1043
  if (ret) {
924
1044
  result.newDate = newValues;
925
1045
  return result;
@@ -933,11 +1053,12 @@ class DateRangePicker {
933
1053
  /**
934
1054
  * Updates the picker when calendar is initiated or any date has been selected.
935
1055
  * Could be useful after running {@link #DateRangePicker+setStartDate|setStartDate} or {@link #DateRangePicker+setEndDate|setRange}
1056
+ * @param {boolean} monthChange - If `true` then monthView changed
936
1057
  * @emits "beforeRenderTimePicker.daterangepicker"
937
1058
  */
938
- updateView() {
1059
+ updateView(monthChange) {
939
1060
  if (this.timePicker) {
940
- this.element.trigger("beforeRenderTimePicker.daterangepicker", this);
1061
+ this.triggerEvent(this.#events.onBeforeRenderTimePicker);
941
1062
  this.renderTimePicker("start");
942
1063
  this.renderTimePicker("end");
943
1064
  if (!this.#endDate) {
@@ -948,7 +1069,7 @@ class DateRangePicker {
948
1069
  }
949
1070
  this.updateLabel();
950
1071
  this.updateMonthsInView();
951
- this.updateCalendars();
1072
+ this.updateCalendars(monthChange);
952
1073
  this.setApplyBtnState();
953
1074
  }
954
1075
  /**
@@ -987,9 +1108,11 @@ class DateRangePicker {
987
1108
  /**
988
1109
  * Updates the selected day value from calendar with selected time values
989
1110
  * @emits "beforeRenderCalendar.daterangepicker"
1111
+ * @emits "monthViewChange.daterangepicker"
1112
+ * @param {boolean} monthChange - If `true` then monthView changed
990
1113
  * @private
991
1114
  */
992
- updateCalendars() {
1115
+ updateCalendars(monthChange) {
993
1116
  if (this.timePicker) {
994
1117
  var hour, minute, second;
995
1118
  if (this.#endDate) {
@@ -1033,9 +1156,15 @@ class DateRangePicker {
1033
1156
  if (!this.singleMonthView)
1034
1157
  this.rightCalendar.month = this.rightCalendar.month.set({ hour: 0, minute: 0, second: 0 });
1035
1158
  }
1036
- this.element.trigger("beforeRenderCalendar.daterangepicker", this);
1159
+ this.triggerEvent(this.#events.onBeforeRenderCalendar);
1037
1160
  this.renderCalendar("left");
1038
1161
  this.renderCalendar("right");
1162
+ if (monthChange)
1163
+ this.triggerEvent(
1164
+ this.#events.onMonthViewChange,
1165
+ this.leftCalendar.month,
1166
+ this.singleMonthView || this.singleDatePicker ? null : this.rightCalendar.month
1167
+ );
1039
1168
  this.container.find(".ranges li").removeClass("active");
1040
1169
  if (this.#endDate == null) return;
1041
1170
  this.calculateChosenLabel();
@@ -1478,10 +1607,10 @@ class DateRangePicker {
1478
1607
  }.bind(this));
1479
1608
  this.oldStartDate = this.#startDate;
1480
1609
  this.oldEndDate = this.#endDate;
1481
- this.updateView();
1610
+ this.updateView(false);
1482
1611
  this.container.show();
1483
1612
  this.move();
1484
- this.element.trigger("show.daterangepicker", this);
1613
+ this.triggerEvent(this.#events.onShow);
1485
1614
  this.isShowing = true;
1486
1615
  }
1487
1616
  /**
@@ -1498,12 +1627,12 @@ class DateRangePicker {
1498
1627
  if (!this.#startDate.equals(this.oldStartDate) || !this.#endDate.equals(this.oldEndDate))
1499
1628
  this.callback(this.startDate, this.endDate, this.chosenLabel);
1500
1629
  this.updateElement();
1501
- if (this.element.triggerHandler("beforeHide.daterangepicker", this))
1630
+ if (this.triggerHandler(this.#events.onBeforeHide))
1502
1631
  return;
1503
1632
  $(document).off(".daterangepicker");
1504
1633
  $(window).off(".daterangepicker");
1505
1634
  this.container.hide();
1506
- this.element.trigger("hide.daterangepicker", this);
1635
+ this.triggerEvent(this.#events.onHide);
1507
1636
  this.isShowing = false;
1508
1637
  }
1509
1638
  /**
@@ -1523,7 +1652,7 @@ class DateRangePicker {
1523
1652
  showCalendars() {
1524
1653
  this.container.addClass("show-calendar");
1525
1654
  this.move();
1526
- this.element.trigger("showCalendar.daterangepicker", this);
1655
+ this.triggerEvent(this.#events.onShowCalendar);
1527
1656
  }
1528
1657
  /**
1529
1658
  * Hides calendar when user selects a predefined range
@@ -1531,7 +1660,7 @@ class DateRangePicker {
1531
1660
  */
1532
1661
  hideCalendars() {
1533
1662
  this.container.removeClass("show-calendar");
1534
- this.element.trigger("hideCalendar.daterangepicker", this);
1663
+ this.triggerEvent(this.#events.onHideCalendar);
1535
1664
  }
1536
1665
  /* #endregion */
1537
1666
  /* #region Handle mouse related events */
@@ -1552,7 +1681,7 @@ class DateRangePicker {
1552
1681
  this.#endDate = this.oldEndDate;
1553
1682
  }
1554
1683
  this.hide();
1555
- this.element.trigger("outsideClick.daterangepicker", this);
1684
+ this.triggerEvent(this.#events.onOutsideClick);
1556
1685
  }
1557
1686
  /**
1558
1687
  * Move calendar to previous month
@@ -1568,7 +1697,7 @@ class DateRangePicker {
1568
1697
  } else {
1569
1698
  this.rightCalendar.month = this.rightCalendar.month.minus({ month: 1 });
1570
1699
  }
1571
- this.updateCalendars();
1700
+ this.updateCalendars(true);
1572
1701
  }
1573
1702
  /**
1574
1703
  * Move calendar to next month
@@ -1584,7 +1713,7 @@ class DateRangePicker {
1584
1713
  if (this.linkedCalendars)
1585
1714
  this.leftCalendar.month = this.leftCalendar.month.plus({ month: 1 });
1586
1715
  }
1587
- this.updateCalendars();
1716
+ this.updateCalendars(true);
1588
1717
  }
1589
1718
  /**
1590
1719
  * User hovers over date values
@@ -1689,17 +1818,18 @@ class DateRangePicker {
1689
1818
  if (label == this.locale.customRangeLabel) {
1690
1819
  this.showCalendars();
1691
1820
  } else {
1692
- var dates = this.ranges[label];
1693
- this.#startDate = dates[0];
1694
- this.#endDate = dates[1];
1821
+ var newDate = this.ranges[label];
1822
+ const monthChange = !this.#startDate.hasSame(newDate[0], "month") || !this.#endDate.hasSame(newDate[1], "month");
1823
+ this.#startDate = newDate[0];
1824
+ this.#endDate = newDate[1];
1695
1825
  if (!this.timePicker) {
1696
1826
  this.#startDate.startOf("day");
1697
1827
  this.#endDate.endOf("day");
1698
1828
  }
1699
1829
  if (!this.alwaysShowCalendars)
1700
1830
  this.hideCalendars();
1701
- if (this.element.triggerHandler("beforeHide.daterangepicker", this))
1702
- this.updateView();
1831
+ if (this.triggerHandler(this.#events.onBeforeHide))
1832
+ this.updateView(monthChange);
1703
1833
  this.clickApply();
1704
1834
  }
1705
1835
  }
@@ -1778,11 +1908,11 @@ class DateRangePicker {
1778
1908
  this.clickApply();
1779
1909
  side = null;
1780
1910
  }
1781
- this.updateView();
1911
+ this.updateView(false);
1782
1912
  e.stopPropagation();
1783
1913
  if (this.autoUpdateInput)
1784
1914
  this.updateElement();
1785
- this.element.trigger("dateChange.daterangepicker", [this, side]);
1915
+ this.triggerEvent(this.#events.onDateChange, side);
1786
1916
  }
1787
1917
  /**
1788
1918
  * Hightlight selected predefined range in calendar
@@ -1865,14 +1995,14 @@ class DateRangePicker {
1865
1995
  } else if (this.#endDate) {
1866
1996
  this.#endDate = this.#endDate.set({ hour, minute, second });
1867
1997
  }
1868
- this.updateCalendars();
1998
+ this.updateCalendars(false);
1869
1999
  this.setApplyBtnState();
1870
- this.element.trigger("beforeRenderTimePicker.daterangepicker", this);
2000
+ this.triggerEvent(this.#events.onBeforeRenderTimePicker);
1871
2001
  this.renderTimePicker("start");
1872
2002
  this.renderTimePicker("end");
1873
2003
  if (this.autoUpdateInput)
1874
2004
  this.updateElement();
1875
- this.element.trigger("timeChange.daterangepicker", [this, this.singleDatePicker ? null : side]);
2005
+ this.triggerEvent(this.#events.onTimeChange, this.singleDatePicker ? null : side);
1876
2006
  }
1877
2007
  /**
1878
2008
  * Calender month moved
@@ -1883,6 +2013,7 @@ class DateRangePicker {
1883
2013
  var isLeft = $(e.target).closest(".drp-calendar").hasClass("left"), leftOrRight = isLeft ? "left" : "right", cal = this.container.find(".drp-calendar." + leftOrRight);
1884
2014
  var month = parseInt(cal.find(".monthselect").val(), 10);
1885
2015
  var year = cal.find(".yearselect").val();
2016
+ let monthChange = false;
1886
2017
  if (!isLeft) {
1887
2018
  if (year < this.#startDate.year || year == this.#startDate.year && month < this.#startDate.month) {
1888
2019
  month = this.#startDate.month;
@@ -1902,15 +2033,17 @@ class DateRangePicker {
1902
2033
  }
1903
2034
  }
1904
2035
  if (isLeft) {
2036
+ monthChange = !DateTime.fromObject({ year, month }).hasSame(this.leftCalendar.month, "month");
1905
2037
  this.leftCalendar.month = this.leftCalendar.month.set({ year, month });
1906
2038
  if (this.linkedCalendars)
1907
2039
  this.rightCalendar.month = this.leftCalendar.month.plus({ month: 1 });
1908
2040
  } else {
2041
+ monthChange = !DateTime.fromObject({ year, month }).hasSame(this.leftCalendar.month, "month");
1909
2042
  this.rightCalendar.month = this.rightCalendar.month.set({ year, month });
1910
2043
  if (this.linkedCalendars)
1911
2044
  this.leftCalendar.month = this.rightCalendar.month.minus({ month: 1 });
1912
2045
  }
1913
- this.updateCalendars();
2046
+ this.updateCalendars(monthChange);
1914
2047
  }
1915
2048
  /**
1916
2049
  * User clicked `Apply` button
@@ -1919,7 +2052,7 @@ class DateRangePicker {
1919
2052
  */
1920
2053
  clickApply() {
1921
2054
  this.hide();
1922
- this.element.trigger("apply.daterangepicker", this);
2055
+ this.triggerEvent(this.#events.onApply);
1923
2056
  }
1924
2057
  /**
1925
2058
  * User clicked `Cancel` button
@@ -1930,13 +2063,13 @@ class DateRangePicker {
1930
2063
  this.#startDate = this.oldStartDate;
1931
2064
  this.#endDate = this.oldEndDate;
1932
2065
  this.hide();
1933
- this.element.trigger("cancel.daterangepicker", this);
2066
+ this.triggerEvent(this.#events.onCancel);
1934
2067
  }
1935
2068
  /* #endregion */
1936
2069
  /**
1937
2070
  * Update the picker with value from `<input>` element.<br>
1938
2071
  * Input values must be given in format of `locale.format`. Invalid values are handles by `violated.daterangepicker` Event
1939
- * @emits "inputChanged.daterangepicker"
2072
+ * @emits "inputChange.daterangepicker"
1940
2073
  * @private
1941
2074
  */
1942
2075
  elementChanged() {
@@ -1944,6 +2077,7 @@ class DateRangePicker {
1944
2077
  if (!this.element.val().length) return;
1945
2078
  const format = typeof this.locale.format === "string" ? this.locale.format : DateTime.parseFormatForOpts(this.locale.format);
1946
2079
  const dateString = this.element.val().split(this.locale.separator);
2080
+ let monthChange = false;
1947
2081
  if (this.singleDatePicker) {
1948
2082
  let newDate = DateTime.fromFormat(this.element.val(), format, { locale: DateTime.now().locale });
1949
2083
  const oldDate = this.#startDate;
@@ -1957,6 +2091,7 @@ class DateRangePicker {
1957
2091
  return;
1958
2092
  }
1959
2093
  }
2094
+ monthChange = !this.#startDate.hasSame(newDate, "month");
1960
2095
  this.#startDate = newDate;
1961
2096
  this.#endDate = this.#startDate;
1962
2097
  if (!this.timePicker) {
@@ -1977,6 +2112,7 @@ class DateRangePicker {
1977
2112
  return;
1978
2113
  }
1979
2114
  }
2115
+ monthChange = !this.#startDate.hasSame(newDate[0], "month") || !this.#endDate.hasSame(newDate[1], "month");
1980
2116
  this.#startDate = newDate[0];
1981
2117
  this.#endDate = newDate[1];
1982
2118
  if (!this.timePicker) {
@@ -1986,9 +2122,9 @@ class DateRangePicker {
1986
2122
  } else {
1987
2123
  return;
1988
2124
  }
1989
- this.updateView();
2125
+ this.updateView(monthChange);
1990
2126
  this.updateElement();
1991
- this.element.trigger("inputChanged.daterangepicker", this);
2127
+ this.triggerEvent(this.#events.onInputChange);
1992
2128
  }
1993
2129
  /**
1994
2130
  * Handles key press, IE 11 compatibility
@@ -2068,6 +2204,34 @@ class DateRangePicker {
2068
2204
  this.element.off(".daterangepicker");
2069
2205
  this.element.removeData();
2070
2206
  }
2207
+ /**
2208
+ * Helper function to trigger events
2209
+ * @param {Event} ev - From this.#events
2210
+ * @param {...any} args - Argument spread
2211
+ * @private
2212
+ */
2213
+ triggerEvent(ev, ...args) {
2214
+ if (args.length === 0) {
2215
+ this.element.trigger(ev.type, ev.param);
2216
+ } else {
2217
+ const params = ev.param(...args);
2218
+ this.element.trigger(ev.type, params);
2219
+ }
2220
+ }
2221
+ /**
2222
+ * Helper function to trigger events
2223
+ * @param {Event} ev - From this.#events
2224
+ * @param {...any} args - Argument spread
2225
+ * @private
2226
+ */
2227
+ triggerHandler(ev, ...args) {
2228
+ if (args.length === 0) {
2229
+ return this.element.triggerHandler(ev.type, ev.param);
2230
+ } else {
2231
+ const params = ev.param(...args);
2232
+ return this.element.triggerHandler(ev.type, params);
2233
+ }
2234
+ }
2071
2235
  }
2072
2236
  if (!$.fn.daterangepicker) {
2073
2237
  $.fn.daterangepicker = function(options, callback) {