Alin
Alin

Reputation: 14581

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?

Upvotes: 0

Views: 408

Answers (1)

Sharad Paul
Sharad Paul

Reputation: 471

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

Upvotes: 2

Related Questions