Код: Выделить всё
The Previous button moves the list backward.
The Next button moves the list forward.
< /code>
Идея состоит в том, что это должно работать круглым способом, поэтому, когда я достигаю последней даты в списке и нажимаю далее, она должна перейти обратно в первые несколько дат, и то же самое происходит на обратном направлении при нажатии предыдущего. < /p>
< 01/22 02/22 03/22 04/22 (Current) 05/22 06/22 07/22 >
Нажмите следующий, должен в идеале обернуться и продолжить так:
Код: Выделить всё
< 02/22 03/22 04/22 05/22 (Current) 06/22 07/22 08/22 >
, но вместо этого моя реализация просто переходит к следующим доступным датам после 07/22, а список-08/22 и далее.
Вот мой код:
import { DatePicker, Button } from 'antd';
import './ButtonedAntDDatePicker.css';
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import { useState, useEffect } from 'react';
dayjs.extend(customParseFormat);
function ButtonedAntDDatePicker({
selectedDate,
disabledDate,
isDatePickerDisabled,
enabledDates,
setSelectedDate
}) {
const [isAnimating, setIsAnimating] = useState(false);
const [prevButtonsStyle, setPrevButtonsStyle] = useState({});
const [nextButtonsStyle, setNextButtonsStyle] = useState({});
const [datePickerInput, setDatePickerInput] = useState(null);
// handle date picker input field
useEffect(() => {
const input = document.querySelector('.date-picker-container .ant-picker-input input');
if (input) {
setDatePickerInput(input);
// If selectedDate is already set (from URL), update the input field
if (selectedDate) {
input.value = selectedDate.format('DD/MM/YYYY');
}
const handleInputEvent = (e) => {
const inputValue = e.target.value;
const formats = ['DD/MM/YYYY', 'D/M/YYYY', 'DD/M/YYYY', 'D/MM/YYYY'];
for (const format of formats) {
const parsedDate = dayjs(inputValue, format, true);
if (parsedDate.isValid()) {
setSelectedDate(parsedDate);
e.target.value = parsedDate.format('DD/MM/YYYY');
break;
}
}
};
input.addEventListener('blur', handleInputEvent);
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
handleInputEvent(e);
}
});
return () => {
input.removeEventListener('blur', handleInputEvent);
input.removeEventListener('keypress', handleInputEvent);
};
}
}, [setSelectedDate, selectedDate]);
const findSurroundingDates = (currentDate, count) => {
if (enabledDates.length === 0 || !currentDate) return { prevDates: [], nextDates: [] };
const sortedDates = [...enabledDates].sort((a, b) => dayjs(a).diff(dayjs(b)));
const currentIndex = sortedDates.findIndex(date =>
dayjs(date).isSame(currentDate, 'day')
);
const effectiveIndex = currentIndex === -1
? sortedDates.findIndex(date => dayjs(date).isAfter(currentDate))
: currentIndex;
const prevDates = sortedDates
.slice(Math.max(0, effectiveIndex - count), effectiveIndex)
.map(date => dayjs(date));
const nextDates = sortedDates
.slice(effectiveIndex + 1, effectiveIndex + count + 1)
.map(date => dayjs(date));
let hasFirstDate = false;
let firstDateIndex = -1;
const isNearEnd = effectiveIndex >= sortedDates.length - count;
if (nextDates.length < count) {
const remainingDates = count - nextDates.length;
const firstDates = sortedDates.slice(0, remainingDates).map(date => dayjs(date));
if (firstDates.length > 0) {
hasFirstDate = true;
firstDateIndex = nextDates.length;
}
nextDates.push(...firstDates);
}
//if it is first date in the list prev dates should be last dates in the list
if (prevDates.length < count) {
const remainingDates = count - prevDates.length;
const lastDates = sortedDates.slice(-remainingDates).map(date => dayjs(date));
prevDates.unshift(...lastDates);
}
return { prevDates, nextDates, hasFirstDate, firstDateIndex, isNearEnd };
};
const { prevDates, nextDates, hasFirstDate, firstDateIndex, isNearEnd } = findSurroundingDates(selectedDate, 4);
const handleDatePickerChange = (date) => {
if (!date) return;
setSelectedDate(date);
};
const handleDateButtonClick = (date) => {
if (isAnimating || !date) return;
setIsAnimating(true);
const isGoingLeft = date.isAfter(selectedDate);
if (isGoingLeft) {
setPrevButtonsStyle({ animation: 'moveLeftOut 0.15s cubic-bezier(0.33, 1.0, 0.68, 1.0) forwards' });
setNextButtonsStyle({ animation: 'moveLeftIn 0.15s cubic-bezier(0.22, 1.0, 0.36, 1.0) forwards' });
} else {
setPrevButtonsStyle({ animation: 'moveRightIn 0.15s cubic-bezier(0.22, 1.0, 0.36, 1.0) forwards' });
setNextButtonsStyle({ animation: 'moveRightOut 0.15s cubic-bezier(0.33, 1.0, 0.68, 1.0) forwards' });
}
setTimeout(() => {
setSelectedDate(date);
setIsAnimating(false);
setPrevButtonsStyle({});
setNextButtonsStyle({});
}, 200);
};
const formatButtonDate = (date) => {
return date.format('DD/MM/YYYY');
};
// checks if it is first date in the sorted dates list
const isFirstDate = (date) => {
if (!date || enabledDates.length === 0) return false;
const sortedDates = [...enabledDates].sort((a, b) => dayjs(a).diff(dayjs(b)));
const firstDate = dayjs(sortedDates[0]);
return date.isSame(firstDate, 'day');
};
// checks if it is the last date in the sorted dates list
const isLastDate = (date) => {
if (!date || enabledDates.length === 0) return false;
const sortedDates = [...enabledDates].sort((a, b) => dayjs(a).diff(dayjs(b)));
const lastDate = dayjs(sortedDates[sortedDates.length - 1]);
return date.isSame(lastDate, 'day');
};
const renderPrevButtons = () => {
if (!prevDates.length) return null;
return prevDates.map((date, index) => {
const isLastDateIndicator = isLastDate(date);
return (
key={`prev-${index}`}
style={{ position: 'relative' }}
>
handleDateButtonClick(date)}
className={`date-button prev-date ${index === 0 ? 'first-button' : ''}`}
>
{index === 0 ? : formatButtonDate(date)}
);
});
};
const renderNextButtons = () => {
if (!nextDates.length) return null;
return nextDates.map((date, index) => {
return (
key={`next-${index}`}
style={{ position: 'relative' }}
>
handleDateButtonClick(date)}
className={`date-button next-date ${index === nextDates.length - 1 ? 'last-button' : ''}`}
>
{index === nextDates.length - 1 ? : formatButtonDate(date)}
);
});
};
if (isDatePickerDisabled) {
return null;
}
return (
{renderPrevButtons()}
className="date-buttons-container next-dates"
style={nextButtonsStyle}
>
{renderNextButtons()}
);
}
export default ButtonedAntDDatePicker;
< /code>
< /code>
I expect that when I click on next/prev button it will only move to the prev date in the list not move whole thing. I've tried shifting the dates but it didn't quite work. Anyone has any idea on how to approach this issue?
Подробнее здесь: https://stackoverflow.com/questions/795 ... e-one-date