【Next.js】使用Fullcalendar实现外部事件的拖放操作

由于找不到关于使用Fullcalendar+react拖放外部事件的文章,我决定自己写一篇。

构成

    • react+typescript

 

    • MUI

 

    Fullcalendar

在React中引入Fullcalendar。

由于这里忽略,敬请参考下文。

 

基本的日历 de

2023-02-28 10.12のイメージ.jpg
import React from 'react';
// FullCalendar
import FullCalendar from '@fullcalendar/react';
import timeGridPlugin from '@fullcalendar/timegrid';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import jaLocale from '@fullcalendar/core/locales/ja';
import listPlugin from '@fullcalendar/list';
import { Grid } from '@mui/material';

const SampleCalendar: React.FC = () => {
  const ref = React.createRef<any>();

  return (
    <Grid container>
      <FullCalendar
        ref={ref}
        locales={[jaLocale]}
        plugins={[timeGridPlugin, dayGridPlugin, interactionPlugin, listPlugin]}
        initialView='dayGridMonth'
        slotDuration='00:30:00'
        headerToolbar={{
          left: 'prev,next today',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek',
        }}
        //
        selectable={true}
        weekends={true}
      />
    </Grid>
  );
};

export default SampleCalendar;

使得外部事件可以被删除

将droppable设置为true,能够使得事件在内部和外部都可以被拖放。
当拖放外部事件时,指定触发drop事件。
请注意不要与eventDrop混淆。
这将在拖放内部事件时触发。

const drop=()=>{
console.log('dropした')
}

 <FullCalendar
// 省略
+ droppable={true}
+ drop={drop}
/>

创建外部事件组件

我们将创建一个尽可能简洁的外部事件,使其能够被删除。

import React, { useEffect, useRef } from "react";
import { Draggable } from "@fullcalendar/interaction";
import { Box } from "@mui/material";

type Props = {
  event: { id: number; title: string };
};

export const ExternalEvent = ({ event }: Props) => {
  const elRef = useRef<HTMLButtonElement | null>(null);

  useEffect(() => {
    if (!elRef.current) return;

    const draggable = new Draggable(elRef.current, {
      eventData: () => {
        return { ...event, create: true };
      },
    });

    return () => draggable.destroy();
  });

  return (
    <Box
      component="div"
      ref={elRef}
      title={event.title}
      sx={{
        fontWeight: "bold",
        cursor: "grab",
        mb: "0.6rem",
        mx: "1.5rem",
      }}
    >
      {event.title}
    </Box>
  );
};

反映外部事件

这就是完成了。

import React from 'react';
// FullCalendar
import React from "react";
// FullCalendar
import FullCalendar from "@fullcalendar/react";
import timeGridPlugin from "@fullcalendar/timegrid";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";
import jaLocale from "@fullcalendar/core/locales/ja";
import listPlugin from "@fullcalendar/list";
import { Grid } from "@mui/material";
import { ExternalEvent } from "@/conponents/externalEvents";

const events = [
  {
    id: "1",
    title: "脚トレ",
  },
  {
    id: "2",
    title: "胸トレ",
  },
  {
    id: "3",
    title: "背中トレ",
  },
];

const SampleCalendar: React.FC = () => {
  const ref = React.createRef<any>();

  const drop = () => {
    console.log("dropした");
  };

  return (
    <Grid container>
      <Grid item xs={3}>
        {events.map((event) => (
          <ExternalEvent event={event} key={event.id} />
        ))}
      </Grid>
      <Grid item xs={9}>
        <FullCalendar
          ref={ref}
          locales={[jaLocale]}
          plugins={[
            timeGridPlugin,
            dayGridPlugin,
            interactionPlugin,
            listPlugin,
          ]}
          initialView="dayGridMonth"
          slotDuration="00:30:00"
          headerToolbar={{
            left: "prev,next today",
            center: "title",
            right: "dayGridMonth,timeGridWeek",
          }}
          //
          selectable={true}
          weekends={true}
          droppable={true}
          drop={drop}
        />
      </Grid>
    </Grid>
  );
};

export default SampleCalendar;
广告
将在 10 秒后关闭
bannerAds