Im trying to implement custom date range, is there any way to use ref api to do this? Im using custom toolbar component where I have next,today,prev buttons working with calendar ref, but I also want to have 2 date inputs, one is start date, second is end date, but unfortunately I cant figure out how to use ref to change calendar view dates
const CustomCalendarHeader: React.FC<Props> = ({
calendarRef,
currentDate,
setCurrentDate,
}) => {
const ref = calendarRef.current!.getApi();
const nextHandle = () => {
ref.next();
};
const prevHandle = () => {
ref.prev();
};
const todayHandle = () => {
ref.today();
};
const dayHandle = () => {
ref.changeView('resourceTimelineDay');
};
const weekHandle = () => {
ref.changeView('resourceTimelineWeek');
};
return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
px: 2,
mb: 5,
}}
>
<Box
sx={{ display: 'flex', alignItems: 'center', gap: 2, flexGrow: 0.3 }}
>
<Button variant="contained" onClick={dayHandle}>
Day
</Button>
<Button variant="contained" onClick={weekHandle}>
Week
</Button>
<Typography>Custom: </Typography>
<TextField type="date" size="small" sx={{ maxWidth: '125px' }} />
-
<TextField type="date" size="small" sx={{ maxWidth: '125px' }} />
</Box>
<ButtonGroup
color="primary"
variant="contained"
sx={{ display: 'flex', alignItems: 'center' }}
>
<Button onClick={prevHandle}>Prev</Button>
<Button onClick={todayHandle}>Today</Button>
<Button onClick={nextHandle}>Next</Button>
</ButtonGroup>
</Box>
);
};
and my Calendar component is looking like this:
<FullCalendar
eventDrop={handleResizeOrRedropEvent}
eventResize={handleResizeOrRedropEvent}
droppable={true}
eventReceive={handleEventReceive}
viewDidMount={handleViewChange}
ref={refCalendar as LegacyRef<FullCalendar> | undefined}
nowIndicator
dayMaxEvents
timeZone="UTC"
height="80vh"
datesSet={(arg) => setCurrentDate(arg)}
// visibleRange={{
// start: currentDate?.startStr,
// end: currentDate?.endStr,
// }}
displayEventTime={false}
eventClick={handleEventClick}
eventsSet={handleEvents}
weekends={true}
editable={true}
selectable={true}
// selectMirror={true}
plugins={[resourceTimelinePlugin, interactionPlugin]}
events={[dragEventRow, ...timeFrames]}
resources={[dragEventRow, ...timeFrames].map((timeframe) => ({
id: `${timeframe.type}-${timeframe.title}`,
title: timeframe.title,
type: timeframe.type,
...('children' in timeframe && {
children: timeframe.children,
}),
}))}
resourceGroupField="type"
resourceAreaWidth={'20%'}
initialView="resourceTimeline"
eventContent={renderEventContent}
headerToolbar={{
left: '',
center: 'title',
right: '',
}}
/>
)}
searched in docs, but only vound visibleRange that is not actually working for me alongside with datesSet, it causes infinite setState calls
>Solution :
To implement a custom date range in FullCalendar using the ref API, you can use the gotoDate method of the FullCalendar API to navigate to a specific date. However, to set a range of dates, you need to use the validRange option of FullCalendar. This option allows you to specify a start and end date for the calendar’s valid date window.
Here is an example of how you can implement this:
const CustomCalendarHeader: React.FC<Props> = ({
calendarRef,
currentDate,
setCurrentDate,
}) => {
const ref = calendarRef.current!.getApi();
const nextHandle = () => {
ref.next();
};
const prevHandle = () => {
ref.prev();
};
const todayHandle = () => {
ref.today();
};
const dayHandle = () => {
ref.changeView('resourceTimelineDay');
};
const weekHandle = () => {
ref.changeView('resourceTimelineWeek');
};
const handleDateRangeChange = () => {
const startDate = document.getElementById('start_date').value;
const endDate = document.getElementById('end_date').value;
ref.setOption('validRange', {
start: startDate,
end: endDate,
});
};
return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
px: 2,
mb: 5,
}}
>
<Box
sx={{ display: 'flex', alignItems: 'center', gap: 2, flexGrow: 0.3 }}
>
<Button variant="contained" onClick={dayHandle}>
Day
</Button>
<Button variant="contained" onClick={weekHandle}>
Week
</Button>
<Typography>Custom: </Typography>
<TextField id="start_date" type="date" size="small" sx={{ maxWidth: '125px' }} onChange={handleDateRangeChange} />
-
<TextField id="end_date" type="date" size="small" sx={{ maxWidth: '125px' }} onChange={handleDateRangeChange} />
</Box>
<ButtonGroup
color="primary"
variant="contained"
sx={{ display: 'flex', alignItems: 'center' }}
>
<Button onClick={prevHandle}>Prev</Button>
<Button onClick={todayHandle}>Today</Button>
<Button onClick={nextHandle}>Next</Button>
</ButtonGroup>
</Box>
);
};
In this example, I added an onChange event to the date input fields that calls the handleDateRangeChange function. This function gets the values of the start and end date input fields and sets the validRange option of the FullCalendar instance.
Please note that the validRange option will limit the range of dates that the user can navigate to, but it won’t automatically change the view to fit the specified range. If you want to navigate to the start date of the range after setting the validRange, you can call ref.gotoDate(startDate) at the end of the handleDateRangeChange function.