1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Next.js】Fullcalendarで外部イベントをドラッグ&ドロップする

Posted at

Fullcalendar+reactで外部のイベントをドラッグ&ドロップしている記事が見つけられなかったので書いてみました。

構成

  • react+typescript
  • MUI
  • Fullcalendar

reactにFullcalendarの導入

ここら辺は飛ばしますので下記を参考にしてください。

基本のカレンダー

2023-02-28 10.12のイメージ.jpg

index.ts
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;

外部イベントdrop可能にする

droppableをtrueにすることで、内部外部に関わらずイベントのdropが可能になります。
外部イベントをdropした時に発火するdropに指定します。
eventDropと間違えないように注意してください。
こちらは内部のイベントをdropした時に発火します。

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

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

外部イベントコンポーネント作成

dropができるだけのシンプルな外部イベントを作成します。

components/ExternalEvents.tsx
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>
  );
};

外部イベントを反映

これで完成です。

index.ts
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;
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?