Fix date carousel position persistence to keep selected date in place
- Selected date now stays at its clicked position instead of jumping to center - Fixed timezone issue in localStorage causing dates to shift by one day - Carousel position is preserved across page reloads - Simplified date selection logic by removing complex offset calculations - Added updateSelectedState() method to update selection without re-rendering 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -43,38 +43,11 @@ class DateCarousel {
|
||||
// Загружаем сохранённую дату из localStorage или устанавливаем сегодня
|
||||
const savedData = this.loadSavedCenterDate();
|
||||
if (savedData) {
|
||||
// Если есть смещение, это означает, что дата была выбрана пользователем
|
||||
if (savedData.offset !== 0) {
|
||||
// Проверяем, есть ли выбранная дата в фильтрах
|
||||
if (this.minInput && this.minInput.value && this.maxInput.value &&
|
||||
this.minInput.value === this.maxInput.value) {
|
||||
// Получаем выбранную дату из фильтра
|
||||
const parts = this.minInput.value.split('-');
|
||||
if (parts.length === 3) {
|
||||
const selectedDate = new Date(
|
||||
parseInt(parts[0]),
|
||||
parseInt(parts[1]) - 1,
|
||||
parseInt(parts[2])
|
||||
);
|
||||
selectedDate.setHours(0, 0, 0, 0);
|
||||
|
||||
// Вычисляем центральную дату: выбранная дата минус смещение
|
||||
this.centerDate = new Date(selectedDate);
|
||||
this.centerDate.setDate(this.centerDate.getDate() - savedData.offset);
|
||||
} else {
|
||||
// Если дата в фильтре некорректна, используем сохранённую центральную дату
|
||||
this.centerDate = savedData.centerDate;
|
||||
}
|
||||
} else {
|
||||
// Если нет фильтра с одной датой, используем сохранённую центральную дату
|
||||
this.centerDate = savedData.centerDate;
|
||||
}
|
||||
} else {
|
||||
// Если смещения нет, используем сохранённую центральную дату
|
||||
this.centerDate = savedData.centerDate;
|
||||
}
|
||||
// Восстанавливаем центральную дату как есть
|
||||
this.centerDate = savedData.centerDate;
|
||||
} else {
|
||||
this.centerDate = new Date();
|
||||
this.centerDate.setHours(0, 0, 0, 0); // Сбрасываем время!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,43 +58,6 @@ class DateCarousel {
|
||||
this.calculateDaysCount();
|
||||
this.loadSelectedDate(); // Загрузить выбранную дату из фильтра
|
||||
|
||||
// Если в localStorage есть сохраненные данные
|
||||
const savedData = this.loadSavedCenterDate();
|
||||
if (savedData) {
|
||||
// Если есть смещение, это означает, что дата была выбрана пользователем
|
||||
if (savedData.offset !== 0) {
|
||||
// Проверяем, есть ли выбранная дата в фильтрах
|
||||
if (this.minInput.value && this.maxInput.value &&
|
||||
this.minInput.value === this.maxInput.value) {
|
||||
// Получаем выбранную дату из фильтра
|
||||
const parts = this.minInput.value.split('-');
|
||||
if (parts.length === 3) {
|
||||
const selectedDate = new Date(
|
||||
parseInt(parts[0]),
|
||||
parseInt(parts[1]) - 1,
|
||||
parseInt(parts[2])
|
||||
);
|
||||
selectedDate.setHours(0, 0, 0, 0);
|
||||
|
||||
// Вычисляем центральную дату: выбранная дата минус смещение
|
||||
// (т.к. смещение показывает, на сколько дней выбранная дата
|
||||
// смещена вправо от центра)
|
||||
this.centerDate = new Date(selectedDate);
|
||||
this.centerDate.setDate(this.centerDate.getDate() - savedData.offset);
|
||||
} else {
|
||||
// Если дата в фильтре некорректна, используем сохранённую центральную дату
|
||||
this.centerDate = savedData.centerDate;
|
||||
}
|
||||
} else {
|
||||
// Если нет фильтра с одной датой, используем сохранённую центральную дату
|
||||
this.centerDate = savedData.centerDate;
|
||||
}
|
||||
} else {
|
||||
// Если смещения нет, используем сохранённую центральную дату
|
||||
this.centerDate = savedData.centerDate;
|
||||
}
|
||||
}
|
||||
|
||||
this.render();
|
||||
this.attachNavHandlers();
|
||||
this.attachTodayHandler();
|
||||
@@ -131,33 +67,13 @@ class DateCarousel {
|
||||
* Загрузка выбранной даты из скрытых полей фильтра
|
||||
*/
|
||||
loadSelectedDate() {
|
||||
// Если есть выбранная дата в фильтре
|
||||
// Просто логируем выбранную дату, но НЕ меняем centerDate
|
||||
// Карусель остается там, где была (centerDate из localStorage или today)
|
||||
if (this.minInput.value && this.maxInput.value &&
|
||||
this.minInput.value === this.maxInput.value) {
|
||||
const parts = this.minInput.value.split('-');
|
||||
if (parts.length === 3) {
|
||||
const selectedDate = new Date(
|
||||
parseInt(parts[0]),
|
||||
parseInt(parts[1]) - 1,
|
||||
parseInt(parts[2])
|
||||
);
|
||||
selectedDate.setHours(0, 0, 0, 0);
|
||||
|
||||
// Устанавливаем центральную дату на выбранную дату только если фильтр отличается от сегодняшней даты
|
||||
// Это позволяет определить, был ли фильтр установлен до посещения страницы
|
||||
const todayFormatted = this.formatDate(this.today);
|
||||
if (this.minInput.value !== todayFormatted) {
|
||||
// Возможно, фильтр уже был установлен, но мы всё равно не хотим центрировать
|
||||
// для согласованности с поведением после выбора даты
|
||||
console.log(`Selected date in filter: ${this.formatDate(selectedDate)}, keeping current view`);
|
||||
} else {
|
||||
// Если фильтр равен сегодняшней дате, можно центрировать на сегодня
|
||||
console.log(`Filter is today: ${this.formatDate(selectedDate)}, keeping current view`);
|
||||
}
|
||||
}
|
||||
console.log(`Selected date in filter: ${this.minInput.value}, but keeping current center`);
|
||||
} else {
|
||||
// Если фильтра нет, центрируем на сегодняшнем дне
|
||||
console.log('No filter active - centering on today');
|
||||
console.log('No filter active - keeping current center');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,6 +243,35 @@ class DateCarousel {
|
||||
return this.minInput.value === formattedDate && this.maxInput.value === formattedDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление состояния selected для всех кнопок без перерисовки
|
||||
*/
|
||||
updateSelectedState() {
|
||||
const buttons = this.container.querySelectorAll('.date-btn');
|
||||
buttons.forEach(btn => {
|
||||
// Получаем дату из кнопки (день месяца)
|
||||
const dayElement = btn.querySelector('.date-btn-day');
|
||||
const monthElement = btn.querySelector('.date-btn-month');
|
||||
if (dayElement && monthElement) {
|
||||
const day = parseInt(dayElement.textContent);
|
||||
const monthShort = monthElement.textContent;
|
||||
|
||||
// Находим дату кнопки, сравнивая с датами в generateDays
|
||||
const days = this.generateDays();
|
||||
const matchingDay = days.find(d =>
|
||||
d.date.getDate() === day &&
|
||||
this.getMonthShort(d.date) === monthShort
|
||||
);
|
||||
|
||||
if (matchingDay && this.isDateSelected(matchingDay.date)) {
|
||||
btn.classList.add('selected');
|
||||
} else {
|
||||
btn.classList.remove('selected');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Выбор даты (установка в оба поля фильтра)
|
||||
*/
|
||||
@@ -336,19 +281,21 @@ class DateCarousel {
|
||||
this.minInput.value = formattedDate;
|
||||
this.maxInput.value = formattedDate;
|
||||
|
||||
// Вычисляем смещение выбранной даты от центра
|
||||
const offset = this.calculateDateOffset(date);
|
||||
// Сохраняем центральную дату и смещение перед отправкой формы
|
||||
this.saveCenterDate(offset);
|
||||
// НЕ меняем centerDate - оставляем карусель на месте
|
||||
// Только обновляем визуальное выделение
|
||||
|
||||
// Визуальная обратная связь
|
||||
btn.classList.add('clicked');
|
||||
setTimeout(() => btn.classList.remove('clicked'), 300);
|
||||
|
||||
// Обновление визуального состояния (без изменения центральной даты)
|
||||
this.render();
|
||||
// Обновление визуального состояния (только класс selected)
|
||||
this.updateSelectedState();
|
||||
|
||||
console.log(`Selected date: ${formattedDate}, offset: ${offset}`);
|
||||
console.log(`Selected date: ${formattedDate}, center stays at: ${this.formatDate(this.centerDate)}`);
|
||||
|
||||
// ВАЖНО: Сохраняем текущую позицию карусели перед отправкой формы
|
||||
// чтобы после перезагрузки страницы карусель осталась на том же месте
|
||||
this.saveCenterDate();
|
||||
|
||||
// Автоматическая отправка формы
|
||||
const form = this.minInput.closest('form');
|
||||
@@ -443,7 +390,8 @@ class DateCarousel {
|
||||
*/
|
||||
saveCenterDate(offset = 0) {
|
||||
const key = `date_carousel_center_${this.minInputId}`;
|
||||
const centerDateStr = this.centerDate.toISOString().split('T')[0]; // Формат YYYY-MM-DD
|
||||
// Используем formatDate вместо toISOString для избежания проблем с часовыми поясами
|
||||
const centerDateStr = this.formatDate(this.centerDate);
|
||||
const saveData = {
|
||||
centerDate: centerDateStr,
|
||||
offset: offset
|
||||
|
||||
Reference in New Issue
Block a user