Initially I was searching for solution for generating some class for start and end dates under the jQuery Datepicker, and the solution was given to me under this post https://stackoverflow.com/a/67191802/14723575
But it works only if start and end dates are under the same month. There is an issue with both of suggested codes if I need to slide to some next month in order to select end date. For example, if I select 24 April as start date and 6 May as end date, it brakes at the last day of the current month.
I got suggestion to open separated ticket for this problem, so here we go.
I have modified the code to adapt to your problem. As you could see, the code have to test lot of different situations, i think i have not forgotten...
i have put the code in snippet, because there lot of lines of code, but the snippet is not functional...
$(function () {
var dates_selected = [];
var firstdate_present = false;//is firstdate present in the current display?
var lastdate_present = false;//is lastdate present in the current display?
$(".date-picker-input").datepick({
rangeSelect: true,
dateFormat: "dd/mm/yyyy",
changeMonth: false,
prevText: "<",
nextText: ">",
showOtherMonths: true,
dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
onShow: function (dates) {setTimeout(() => {Open();}, 0);},
onChangeMonthYear: function (year, month) { Change(year, month);},
onDate: highlightDays,
onClose: Close,
showTrigger: "#calImg",
});
// function waits a return, false or true or other but
// dunno the utility
function highlightDays(date) {
if (dates_selected.length == 0) return false;
if (compareDates(date, dates_selected[0]) == 0) {
firstdate_present = true;//yes present in current display
}
if (compareDates(date, dates_selected[1]) == 0) {
lastdate_present = true;//yes present in current display
}
return true;
}
function Change(y, m) {
firstdate_present = false;
lastdate_present = false;
}
function Open() {
if (dates_selected.length == 0) return;
//current year month displayed YYYYMM
let current = parseDate($(".datepick-month-header").text());
//year month for first and last date of range
let months = new objDate(dates_selected[0].getFullYear() * 100 + dates_selected[0].getMonth(),
dates_selected[1].getFullYear() * 100 + dates_selected[1].getMonth());
let days = new objDate(dates_selected[0].getDate(), dates_selected[1].getDate());
//let years = new objDate(dates_selected[0].getFullYear(), dates_selected[1].getFullYear() );
let others = $(".datepick-other-month").map( (_, e) => parseInt($(e).text())).get();
if (firstdate_present && lastdate_present) {
if (current == months.first && current == months.last) {
$(".datepick-popup .datepick-selected:first, .datepick-popup .datepick-selected:last").addClass("selected");
} else if (current == months.first) {
$(".datepick-popup .datepick-selected:first").addClass("selected");
let indexfirst = others.findIndex( num => num < 15);
let indexlast = others.findIndex( num => num == days.last);
for(let i = indexfirst; i <= indexlast; i++){
if(i == indexlast ) $(".datepick-other-month").eq(i).addClass("selected");
$(".datepick-other-month").eq(i).addClass("datepick-selected");
}
} else if (current == months.last) {
$(".datepick-popup .datepick-selected:last").addClass("selected");
let indexfirst = others.findIndex( num => num == days.first);
for(let i = indexfirst; i < others.length && others[i] > 15; i++){
if(i == indexfirst ) $(".datepick-other-month").eq(i).addClass("selected");
$(".datepick-other-month").eq(i).addClass("datepick-selected");
}
} else if (current != months.first && current != months.last) {
let indexfirst = others.findIndex( num => num == days.first);
let indexlast = others.findIndex( num => num == days.last);
for(let i = indexfirst; i <= indexlast; i++){
if( i == indexfirst || i == indexlast ) $(".datepick-other-month").eq(i).addClass("selected");
$(".datepick-other-month").eq(i).addClass("datepick-selected");
}
}
} else if (firstdate_present) {
if (current == months.first) {
$(".datepick-popup .datepick-selected:first").addClass("selected");
let indexfirst = others.findIndex( num => num < 15);
for(let i = indexfirst; i <= others.length && i >= 0; i++){
$(".datepick-other-month").eq(i).addClass("datepick-selected");
}
} else if (current != months.first) {
let indexfirst = others.findIndex( num => num == days.first);
for(let i = indexfirst; i < others.length; i++){
if( i == indexfirst ) $(".datepick-other-month").eq(i).addClass("selected");
$(".datepick-other-month").eq(i).addClass("datepick-selected");
}
}
} else if (lastdate_present) {
if (current == months.last) {
$(".datepick-popup .datepick-selected:last").addClass("selected");
for(let i = 0; i <= others.length && others[i] >= 15; i++){
$(".datepick-other-month").eq(i).addClass("datepick-selected");
}
} else if (current != months.last) {
let indexfirst = others.findIndex( num => num == days.last);
for(let i = indexfirst; i < others.length; i++){
if( i == indexfirst ) $(".datepick-other-month").eq(i).addClass("selected");
$(".datepick-other-month").eq(i).addClass("datepick-selected");
}
}
} else if( current > months.first && current < months.last){
$(".datepick-other-month").addClass("datepick-selected");
}
}
function Close(dates) {
dates_selected = dates;
firstdate_present = false;
lastdate_present = false;
}
function compareDates(a, b) {
if (a < b) return -1;
if (a > b) return +1;
return 0; // dates are equal
}
function objDate(first, last) {
this.first = first;
this.last = last;
this.same = first == last;
}
// arg:string MMMM YYYY, return:number YYYYMM
function parseDate(s) {
// to adapt following the setting of name month displayed
var months = {january: 0, february: 1, march: 2, april: 3, may: 4, june: 5, july: 6, august: 7, september: 8, october: 9, november: 10, december: 11};
var p = s.split(" ");
return parseInt(p[1]) * 100 + parseInt(months[p[0].toLowerCase()]);
}
});