You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何获取FullCalendar事件ID以实现事件删除

Laravel + FullCalendar 日历应用删除事件模态框问题

问题描述

我正在开发基于Laravel和FullCalendar的日历应用,需要实现点击日历事件弹出带删除按钮的模态框来删除事件。目前可以通过JS选择器获取事件ID并以文本展示,但无法将其转为PHP变量用于表单的action参数。

我采用异步加载事件的方式(而非通过foreach循环填充FullCalendar的events数组),原因是后者会让页面源代码充斥大量事件信息,而异步加载能提升页面渲染速度(可能我的理解存在偏差)。

现有代码实现

EventsController

public function getEvents() 
{
    return Event::where('event_date', '>', '2022-01-01') 
    ->join('hospitals', 'events.hospital_id', '=', 'hospitals.hospital_id')
    ->select('hospitals.hospital_color', 'hospitals.hospital_max_people', 'event_id', 'event_content', 'event_date', 'user_id')
    ->get()
    ->map(fn ($events) => [
        'id' => $events->event_id,
        'title' => $events->event_content,
        'start' => $events->event_date,
        'allDay' => true,
        'editable' => false,
        'backgroundColor' => $events->hospital_color,
        'borderColor' => $events->hospital_color,
        'hospital_max_people' => $events->hospital_max_people,
        'volunteer' => User::find($events->user_id)->first_name .' '. User::find($events->user_id)->last_name
    ]);
}

Events Blade模板 - FullCalendar设置

<script>
    document.addEventListener('DOMContentLoaded', function() {
        var calendarEl = document.getElementById('calendar');
        var calendar = new FullCalendar.Calendar(calendarEl, {
            editable: false,
            droppable: true,
            selectable: true,
            initialView: 'dayGridWeek',
            views: {
                dayGridWeek: {
                    type: 'dayGridWeek',
                    duration: { weeks: 2 },
                    buttonText: '4 day'
                }
            },
            header: {
                left: 'prev,next today',
                center: 'title',
                right: 'month,listMonth'
            },
            themeSystem: 'bootstrap5',
            locale: 'en',
            firstDay: '1',
            contentHeight: 500,
            height: 700,
            expandRows: true,
            events: 'getEvents',

            eventClick: function(calendar, jsEvent, view) {
                $('#eventDetail').modal("show");
                $('#id').html(calendar.event.id);
                $('#title').html(calendar.event.title);
                $('#start').html(moment(calendar.event.start).format('DD.MM.YYYY'));
                $('#volunteer').html(calendar.event.extendedProps.volunteer);
            }
        });
        calendar.render();
    });
</script>

Events Blade模板 - 模态框代码

<div class="modal fade" id="eventDetail" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="bar" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="staticBackdropLabel">Event details</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                Start: <p id="start"></p>
                Volunteer: <p id="volunteer"></p>
                Title: <p id="title"></p>
            </div>
            <div class="modal-footer">
                <form method="POST" action="{{ route('calendar.destroy') }}" class="needs-validation" novalidate="">
                    @csrf
                    @method('DELETE')
                    <div class="form-group">
                        <x-button tabindex="3">
                            {{ __('Delete event') }}
                        </x-button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

解决方案

方法1:通过隐藏字段传递事件ID

这是最直接的实现方式,把事件ID存入隐藏表单字段,提交时一起传给后端:

  1. 在模态框的表单中添加隐藏input:
<form method="POST" action="{{ route('calendar.destroy') }}" class="needs-validation" novalidate="">
    @csrf
    @method('DELETE')
    <!-- 添加隐藏字段存储事件ID -->
    <input type="hidden" name="event_id" id="event_id">
    <div class="form-group">
        <x-button tabindex="3">
            {{ __('Delete event') }}
        </x-button>
    </div>
</form>
  1. 在eventClick回调中给隐藏字段赋值:
eventClick: function(info) {
    $('#eventDetail').modal("show");
    $('#id').html(info.event.id);
    $('#title').html(info.event.title);
    $('#start').html(moment(info.event.start).format('DD.MM.YYYY'));
    $('#volunteer').html(info.event.extendedProps.volunteer);
    // 给隐藏字段设置当前事件ID
    $('#event_id').val(info.event.id);
}
  1. 后端destroy方法接收并处理:
public function destroy(Request $request)
{
    $event = Event::findOrFail($request->event_id);
    $event->delete();
    return redirect()->back()->with('success', '事件已删除');
}

方法2:动态修改表单action(RESTful路由场景)

如果你的路由是RESTful风格(比如/calendar/{event}),可以动态替换action中的ID参数:

  1. 调整路由定义:
Route::delete('/calendar/{event}', [EventsController::class, 'destroy'])->name('calendar.destroy');
  1. 修改模态框表单,去掉固定action:
<form method="POST" class="needs-validation" novalidate="">
    @csrf
    @method('DELETE')
    <div class="form-group">
        <x-button tabindex="3">
            {{ __('Delete event') }}
        </x-button>
    </div>
</form>
  1. 在eventClick中动态设置表单action:
eventClick: function(info) {
    $('#eventDetail').modal("show");
    // 其他渲染代码...
    // 替换路由模板中的ID占位符
    const deleteUrl = "{{ route('calendar.destroy', ['event' => ':id']) }}".replace(':id', info.event.id);
    $('#eventDetail form').attr('action', deleteUrl);
}
  1. 后端使用路由模型绑定直接获取事件:
public function destroy(Event $event)
{
    $event->delete();
    return redirect()->back()->with('success', '事件已删除');
}

补充说明

  • 你对异步加载事件的理解是正确的:这种方式能减少初始页面的HTML体积,提升首屏渲染速度,事件数量越多优势越明显。
  • FullCalendar官方文档中,eventClick的回调参数是info对象,建议把原代码中的参数名从calendar改成info,避免和日历实例混淆。

内容的提问来源于stack exchange,提问作者Nikola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:10:30