Laravel9, Inertia.ja, vue3, カレンダー表示にFullCalendarの5系を使用しています。
このように、DBに登録されている予定を引っ張て来てカレンダーに表示しています。
日付けをクリックし、新しくスケジュールを登録した際に、今登録したものをカレンダーに反映させるのに、
色々と試行錯誤した末、現在はwindow.location.reload()
でリロードしていますが、
せっかくSPAで構築しているのでスマートに最新のスケジュールを表示したいです。
アドバイスいただけますと幸いです。
(ページを再読み込むほか、< > をクリックすると、DB登録は失敗していないので表示されますが…という感じです)
参考にしたサイト:
https://chigusa-web.com/blog/laravel-fullcalendar/
https://codesandbox.io/s/27n33?file=/src/Demo.vue
コード
CalendarTest.vue
<template> <Head title="Dashboard" /> <AuthenticatedLayout :isAdmin="isAdmin"> <template #header> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> CalendarTest </h2> </template> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <div class="p-6 bg-white"> <h1>calendar</h1> <FullCalendar :options="calendarOptions" /> </div> </div> </div> </div> </AuthenticatedLayout> </template> <script setup> import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue'; import { Head, usePage } from '@inertiajs/inertia-vue3'; import { ref } from 'vue' import axios from 'axios' import '@fullcalendar/core/vdom' // solves problem with Vite import FullCalendar from '@fullcalendar/vue3' import dayGridPlugin from '@fullcalendar/daygrid' import timeGridPlugin from '@fullcalendar/timegrid' import interactionPlugin from '@fullcalendar/interaction' const handleDateSelect = (selectInfo) => { // 日付をクリックしてスケジュールを登録するときのメソッド let title = prompt('イベントを入力してください') let calendarApi = selectInfo.view.calendar calendarApi.unselect() // clear date selection if (title) { axios.post('schedule-add', { start_date: selectInfo.start.valueOf(), end_date: selectInfo.end.valueOf(), event_name: title }) .then(() => { // ★登録成功した時に最新のテーブル情報を取得したい window.location.reload() }) .catch(() => { alert("登録に失敗しました") }) } } const getEvent = (info, successCallback, failureCallback) => { // イベント取得用のメソッド。 console.log("getEvent") axios.post('schedule-get', { start_date: info.start.valueOf(), end_date: info.end.valueOf(), }) .then((response) => { successCallback(response.data); }) .catch(() => { alert("取得に失敗しました") }) } const handleEventClick = (clickInfo) => { console.log(clickInfo.event) alert(clickInfo.event.title + ":" + clickInfo.event.id) } const calendarOptions = ref({ plugins: [ dayGridPlugin, timeGridPlugin, interactionPlugin ], initialView: 'dayGridMonth', editable: true, selectable: true, select: handleDateSelect, eventClick: handleEventClick, events: getEvent, selectMirror: true, dayMaxEvents: true, weekends: true, locale: "ja", customButtons: { myCustomButton: { text: 'custom!', click: function() { alert('clicked the custom button!'); } } }, headerToolbar: { left: 'prev,next today myCustomButton', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay' } }) </script>
試したこと1
参考にしたサイトhttps://chigusa-web.com/blog/laravel-fullcalendar/
では、イベント登録時のメソッドの時にオブジェクトにイベントを追加し、イベント取得用のメソッドで一旦クリアにしているので真似してみました
■変更部分のみ抜粋
const handleDateSelect = (selectInfo) => { // 日付をクリックしてスケジュールを登録するときのメソッド 略 if (title) { axios.post('schedule-add', { start_date: selectInfo.start.valueOf(), end_date: selectInfo.end.valueOf(), event_name: title }) .then(() => { calendarApi.addEvent({ // こちらでカレンダーに今登録したものが表示される title, start: selectInfo.startStr, end: selectInfo.endStr, allDay: selectInfo.allDay }) }) .catch(() => { alert("登録に失敗しました") }) } } const getEvent = (info, successCallback, failureCallback) => { // イベント取得用のメソッド。 console.log("getEvent") axios.post('schedule-get', { start_date: info.start.valueOf(), end_date: info.end.valueOf(), }) .then((response) => { // 参考サイトでは追加したイベントを削除をここで行っているが、削除方法が分からず断念… successCallback(response.data); }) .catch(() => { alert("取得に失敗しました") }) }
参考サイトでは追加したイベントを削除するために、イベント取得用メソッド内でクリアを行っていますが、
書き方が違うのでできず、こちらだと登録後はいいですが、<>をクリックして別月に遷移後戻るとこのように2つ表示されてしまいます…
(ページをリロードすればテーブルの中身になるので1つになるのですが…)
試したこと2
少しやり方を変えて、<>をクリックした時に呼ばれるメソッドがわかりましたので、<>をクリックした時にaxiosでテーブルのスケジュールデータを取得し、
vindすることにしました。scriptの変更部分のみ。
const handleDateSelect = (selectInfo) => { // 日付をクリックしてスケジュールを登録するときのメソッド let title = prompt('イベントを入力してください') let calendarApi = selectInfo.view.calendar calendarApi.unselect() // clear date selection if (title) { axios.post('schedule-add', { start_date: selectInfo.start.valueOf(), end_date: selectInfo.end.valueOf(), event_name: title }) .then(() => { // ここでは特に何もしない }) .catch(() => { alert("登録に失敗しました") }) } } const handleEventClick = (clickInfo) => { console.log(clickInfo.event) alert(clickInfo.event.title + ":" + clickInfo.event.id) } const changeDate = (info) => { // 新しく追加。読み込まれたり、<>クリックして月が変更された時によばれるっぽい console.log("getDate") console.log(info) axios.post('schedule-get', { start_date: info.start.valueOf(), end_date: info.end.valueOf(), }) .then((response) => { console.log(response.data) calendarOptions.value.events = response.data }) .catch(() => { alert("取得に失敗しました") }) } const calendarOptions = ref({ plugins: [ dayGridPlugin, timeGridPlugin, interactionPlugin ], initialView: 'dayGridMonth', editable: true, selectable: true, select: handleDateSelect, eventClick: handleEventClick, // 新しく追加 events: [], // 初期値空 datesSet: changeDate, selectMirror: true, dayMaxEvents: true, weekends: true, locale: "ja", customButtons: { myCustomButton: { text: 'custom!', click: function() { alert('clicked the custom button!'); } } }, headerToolbar: { left: 'prev,next today myCustomButton', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay' } })
datesSet
が<>をクリックして表示する月を変更した時に呼び出されるので、
新しくchangeDateメソッド
を作り、datesSet時に呼び出し、
eventsにaxiosで取得したスケジュールデータを渡すようにしました。
こちらは一見うまくいっているのですが、
永遠にchangeDateメソッドが呼び出されてしまっており…
どうしたらよいか分からなくなってしまいました。。
お力を貸していただけると嬉しいです。お願いします…

あなたの回答
tips
プレビュー