Hey there
I recently thrown out all of jQuery / bootstrap of a project and used your plugin as a replacement. Works flawlessly and mostly perfect. Our setup is a daterange picker for different view levels in date, month or year view, so users can live-edit by clicking between their view level.
One thing we recognized during testing is that when switching to either day or month view the range-dates set by minDate and maxDate are not selectable anymore. I tracked the problem down to the date validation and parsing based on the format.
What I found out (I do not open a PR but simply describe here as it is quicker for me for the moment):
In Datepicker.js
following lines do check if we are in month / year view. The problem comes when we set new options by the API method setOptions
and internly the processOptions
/ validateDate
functions parse the Dates.
https://github.com/mymth/vanillajs-datepicker/blob/9de5051545626b116db3d213b0b1e429f296967c/js/Datepicker.js#L36-L59
What I pass in to the options:
minDate: "2019-10",
maxDate: "2021-03",
format: "yyyy-mm"
...
For todays date (2021-03-25), I added a console-log at following position:
https://github.com/mymth/vanillajs-datepicker/blob/9de5051545626b116db3d213b0b1e429f296967c/js/options/processOptions.js#L24-L28
retrieving following output dates - time values rewritten in readable format (here only the max-date):
{
value: "2021-03",
format: "yyyy-mm",
origValue: "2021-03-25"
returnValue: "2021-03-01"
}
The return value for the max-date is not useful, as it reflects the beginning of the month, not the ending. What struggles me more is that for the rangeEnd range-check now the maxDate is correctly set to the last day of the month but checked against the first day of the month, which then leads to a blocked selectable month in the picker (when clicking, nothing happens).
The same problem comes when using year format, the max-range year is not selectable.
I guess there are now several possible fixes, one way I fixed the problem locally is by modifying the min- and max-date ranges in Datepicker.js (the lines referenced at the beginning) as following:
let newDates = inputDates.reduce((dates, dt) => {
let date = parseDate(dt, config.format, config.locale);
if (date === undefined) {
return dates;
}
let minDate = config.minDate
let maxDate = config.maxDate
if (config.pickLevel > 0) {
// adjust to 1st of the month/Jan 1st of the year
// or to the last day of the monh/Dec 31st of the year if the datepicker
// is the range-end picker of a rangepicker
const dt = new Date(date);
if (config.pickLevel === 1) {
// MONTH
date = rangeEnd
? dt.setMonth(dt.getMonth() + 1, 0) // set to last day of month
: dt.setDate(1); // set to first day of month
} else {
// YEAR
date = rangeEnd
? dt.setFullYear(dt.getFullYear() + 1, 0, 0) // set to last day of year
: dt.setMonth(0, 1); // set to jan 1st
}
// We need to also adjust the month / year view for min and max dates
maxDate = config.pickLevel === 1
? (new Date(maxDate)).setMonth(dt.getMonth() + 1, 0) // set to last day of month
: (new Date(maxDate)).setFullYear(dt.getFullYear() + 1, 0, 0) // set to last day of year
minDate = config.pickLevel === 1
? (new Date(minDate)).setDate(1) // set to first day of month
: (new Date(minDate)).setMonth(0, 1) // set to jan 1st
}
By updating the min/max ranges now the isInRange method correctly allows the selection of the upper range month / year, in my example 2021-03.
Hope this helps. Maybe I open a PR later, but feel free to do it yourself.