I’m working with Pikaday (https://github.com/Pikaday/Pikaday).
I’m trying to create a calendar with two months opened at the same time, which would allow to choose date range.
Everything works correctly except when I have my date selected, my hovering effect, which allows to see the picked range, does not stop.
It looks like this: https://i.imgur.com/ZvVbKwj.gif
Here is the relevant code fragment:
function addHoverListener(startDate) {
var dates = document.querySelectorAll('.pika-button[data-pika-month="' + startDate.getMonth() + '"][data-pika-year="' + startDate.getFullYear() + '"]');
var allDates = [];
document.querySelectorAll('.pika-single').forEach(function(pikaSingle) {
allDates.push(...pikaSingle.querySelectorAll('.pika-button'));
});
var firstCalendar = document.querySelector('.pika-single').children[0];
var secondCalendar = document.querySelector('.pika-single').children[1];
function hoverHandler() {
var date = this;
var isHoveredDateInFirstCalendar = firstCalendar.contains(date);
var isHoveredDateInSecondCalendar = secondCalendar.contains(date);
var hoveredDate = new Date(date.getAttribute('data-pika-year'), date.getAttribute('data-pika-month'), date.getAttribute('data-pika-day'));
allDates.forEach(function(date) {
applyStylesOnDate(date, startDate, hoveredDate, firstCalendar, secondCalendar, isHoveredDateInFirstCalendar, isHoveredDateInSecondCalendar);
});
}
function clickHandler() {
console.log("Date clicked");
this.removeEventListener('mouseover', hoverHandler);
console.log("Hover event listener removed");
}
allDates.forEach(function(date) {
date.addEventListener('mouseover', hoverHandler);
date.addEventListener('click', clickHandler);
});
console.log("Hover listeners added");
}
and here is nearly the whole code I wrote if necessary:
Pikaday = function(options) {
var self = this,
opts = self.config(options),
firstSelectedDate = null,
secondSelectedDate = null;
self._onMouseDown = function(e) {
if (!self._v) return;
e = e || window.event;
var target = e.target || e.srcElement;
if (!target) return;
if (!hasClass(target, 'is-disabled')) {
if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty') && !hasClass(target.parentNode, 'is-disabled')) {
if (!firstSelectedDate) {
firstSelectedDate = new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day'));
target.classList.add('first-selected');
self.setDate(firstSelectedDate);
addHoverListener(firstSelectedDate);
} else if (!secondSelectedDate) {
secondSelectedDate = new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day'));
target.classList.add('second-selected');
if (firstSelectedDate.getTime() > secondSelectedDate.getTime())
opts.field.value = secondSelectedDate.toDateString() + " - " + firstSelectedDate.toDateString();
else
opts.field.value = firstSelectedDate.toDateString() + " - " + secondSelectedDate.toDateString();
if (opts.blurFieldOnSelect && opts.field) opts.field.blur();
}
if (firstSelectedDate && secondSelectedDate) {
firstSelectedDate = null;
secondSelectedDate = null;
}
} else if (hasClass(target, 'pika-prev')) {
self.prevMonth();
} else if (hasClass(target, 'pika-next')) {
self.nextMonth();
}
}
if (!hasClass(target, 'pika-select')) {
if (e.preventDefault) e.preventDefault();
else {
e.returnValue = false;
return false;
}
} else self._c = true;
};
function addHoverListener(startDate) {
var allDates = [];
document.querySelectorAll('.pika-single').forEach(function(pikaSingle) {
allDates.push(...pikaSingle.querySelectorAll('.pika-button'));
});
var firstCalendar = document.querySelector('.pika-single').children[0];
var secondCalendar = document.querySelector('.pika-single').children[1];
function hoverHandler() {
var date = this;
var isHoveredDateInFirstCalendar = firstCalendar.contains(date);
var isHoveredDateInSecondCalendar = secondCalendar.contains(date);
var hoveredDate = new Date(date.getAttribute('data-pika-year'), date.getAttribute('data-pika-month'), date.getAttribute('data-pika-day'));
allDates.forEach(function(date) {
applyStylesOnDate(date, startDate, hoveredDate, firstCalendar, secondCalendar, isHoveredDateInFirstCalendar, isHoveredDateInSecondCalendar);
});
}
function clickHandler() {
console.log("Date clicked");
this.removeEventListener('mouseover', hoverHandler);
console.log("Hover event listener removed");
}
allDates.forEach(function(date) {
date.addEventListener('mouseover', hoverHandler);
date.addEventListener('click', clickHandler);
});
console.log("Hover listeners added");
}
function applyStylesOnDate(date, startDate, hoveredDate, firstCalendar, secondCalendar, isHoveredDateInFirstCalendar, isHoveredDateInSecondCalendar) {
var dateObj = new Date(date.getAttribute('data-pika-year'), date.getAttribute('data-pika-month'), date.getAttribute('data-pika-day'));
var button = document.querySelector('.is-selected .pika-button, .has-event .pika-button');
if (dateObj.getTime() === hoveredDate.getTime() && dateObj.getTime() > startDate.getTime()) {
date.classList.add('hovered-date-future');
button.style.borderTopLeftRadius = '3px';
button.style.borderBottomLeftRadius = '3px';
button.style.borderTopRightRadius = '0px';
button.style.borderBottomRightRadius = '0px';
} else if (dateObj.getTime() === hoveredDate.getTime() && dateObj.getTime() < startDate.getTime()) {
date.classList.add('hovered-date-past');
button.style.borderTopLeftRadius = '0px';
button.style.borderBottomLeftRadius = '0px';
button.style.borderTopRightRadius = '3px';
button.style.borderBottomRightRadius = '3px';
} else if ((isHoveredDateInFirstCalendar && dateObj >= startDate && dateObj <= hoveredDate) ||
(isHoveredDateInSecondCalendar && dateObj >= startDate && dateObj <= hoveredDate)) {
date.classList.add('between-selected');
date.classList.remove('hovered-date-future');
date.classList.remove('hovered-date-past');
} else if ((isHoveredDateInFirstCalendar && dateObj <= startDate && dateObj >= hoveredDate) ||
(isHoveredDateInSecondCalendar && dateObj <= startDate && dateObj >= hoveredDate)) {
date.classList.add('between-selected');
date.classList.remove('hovered-date-future');
date.classList.remove('hovered-date-past');
} else {
date.classList.remove('between-selected');
date.classList.remove('hovered-date-future');
date.classList.remove('hovered-date-past');
}
}```
I tried what can be seen in the code. Also tried to add some booleans and set them to false after the click. I'm new to javascript.