reactjsreact-big-calendar

React Big Calendar 15 minutes events


I am using react-big-calendar and while it works pretty great there is this thing where I am stuck.

I want to be able to add 15 minutes events when the user clicks on a cell. No matter what settings I've tried, I can't get the hours to have less than 30 minutes slots.

Basically, setting timeslot=1, and steps=15 makes the calendar display hours in the left side like this: 9:00AM, 9:30AM, 10:00AM, 10:30AM and having only one slot. The events that I can add when clicking on a day, are of 30 minutes by default. If I enforce the end time to be 15 minutes, there is no difference since events will be added wither at 9:00 or at 9:30.

Adding timeslots=4 and steps=15 makes the calendar "zoom" out and the hours are displayed like 08:00AM that has 4 time slots then 10:00AM and so on.

I want to have 9:00, 9:15, 9:30, 9:45 and be able to click and have the event time by default to 15 minutes.

How can I achieve this?


Solution

  • We can try customize the calendar's settings and handle the event creation logic by setting the timeslots and step properties to control the granularity of the calendar slots

    import React from 'react';
    import { Calendar, momentLocalizer } from 'react-big-calendar';
    import moment from 'moment';
    
    const localizer = momentLocalizer(moment);
    
    const MyCalendar = () => {
      return (
        <Calendar
          localizer={localizer}
          timeslots={4}
          step={15}
          style={{ height: 500 }}
        />
      );
    };
    
    export default MyCalendar;
    

    We can then use the onSelectSlot method to handle user clicks and create 15-minute events

    import React, { useState } from "react";
    import { Calendar, momentLocalizer } from "react-big-calendar";
    import moment from "moment";
    import "react-big-calendar/lib/css/react-big-calendar.css";
    
    const localizer = momentLocalizer(moment);
    
    const MyCalendar = () => {
      const [events, setEvents] = useState([]);
    
      const handleSelectSlot = ({ start }) => {
        const startTime = new Date(start);
        // Align to the nearest 15-minute interval
        const startMinutes = Math.floor(startTime.getMinutes() / 15) * 15;
        startTime.setMinutes(startMinutes);
        startTime.setSeconds(0);
        startTime.setMilliseconds(0);
        const endTime = new Date(startTime.getTime());
        endTime.setMinutes(startMinutes + 15);
    
        const newEvent = {
          title: "New Event",
          start: startTime,
          end: endTime,
        };
    
        setEvents([...events, newEvent]);
      };
    
      return (
        <Calendar
          localizer={localizer}
          events={events}
          step={15} // 15 minutes per step
          timeslots={4} // 4 slots per hour
          selectable
          onSelectSlot={handleSelectSlot}
          style={{ height: 1000 }}
          defaultView="week"
          views={["week", "day"]}
          min={new Date(2024, 0, 1, 8, 0)} // Set the start time of the day view to 8:00 AM
          max={new Date(2024, 0, 1, 18, 0)} // Set the end time of the day view to 6:00 PM
          slotPropGetter={(date) => ({
            style: {
              border: "1px solid #e0e0e0",
              height: "1 rem",
              backgroundColor:
                date.getMinutes() % 15 === 0 ? "#f9f9f9" : "transparent",
            },
          })}
          components={{
            event: ({ event }) => (
              <span>
                <strong>{event.title}</strong>
                <em>
                  {moment(event.start).format("HH:mm")} -{" "}
                  {moment(event.end).format("HH:mm")}
                </em>
              </span>
            ),
          }}
        />
      );
    };
    
    export default MyCalendar;
    
    

    I think this should now allow to create 15-minute events when the user clicks on a cell in the calendar enter image description here