使用fullcalendar 5、laravel 9、livewire和modal添加和编辑事件

xmq68pz9  于 2022-12-14  发布在  其他
关注(0)|答案(1)|浏览(207)

我有一个laravel 9项目与livewire,jetstream,fullcalendar 5,高山,和顺风(高堆栈)的基础上关闭这个项目:https://github.com/LaravelDaily/Laravel-Jetstream-CRUD-Roles和本教程:https://laravel.sillo.org/liveware-fullcalendar/
我有拖放功能,以及select和eventClick操作,它们与livewire一起工作,将事件数据提交到数据库。我还为事件和时间线资源提供了CRUD函数,将数据贡献到日历视图。我正在尝试为select函数和eventClick函数使用一个模态,分别添加事件和编辑事件。
我目前的问题有三个方面:
1.目前,多亏了@ADyson,我成功地让livewire日历元素启动了livewire模态元素并检索了部分数据。事件标题、开始和结束时间。我还尝试在事件CRUD中包含其他字段,如事件首字母缩写、城市、地点等...我认为这里的问题是我没有像ExtendedProps那样将这些字段专门声明为EventObject。
a)我特别感兴趣的是livewire日历类可以在哪里编辑,想象一下它在视图文件的这一节中,其中的事件是从JSON构建的,如下所示

events: JSON.parse(@this.events),

B)我假设同一文件中的select和eventClick语句需要修改event info函数才能检索这些信息。
下面是当前fullcalendar 5的视图文件calendar.blade.php:

<style>
  #calendar-container {
        display: grid;
        grid-template-columns: 200px 1fr;
        padding: 20px;
    }
    #events {
        grid-column: 1;
    }
    #calendar {
        grid-column: 2;
        height: 700px;
    }
    .dropEvent {
        background-color: DodgerBlue;
        color: white;
        padding: 5px 16px;
        margin-bottom: 10px;
        text-align: center;
        display: inline-block;
        font-size: 16px;
        border-radius: 4px;
        cursor:pointer;
    }
</style>
<div>
  @include('livewire.eventmodal')
<div>
  <!-- sidebar -->
    <div id="calendar-container" wire:ignore>
        <div id="events">
            <div data-event='{"title":"Evénement A"}' class="dropEvent">Event One Drag</div>
            <div data-event='{"title":"Evénement B"}' class="dropEvent">Event Two Draggable</div>
        </div>
        <div id="calendar"></div>
    </div>
</div>

</div>

@push('scripts')
<script src='https://cdn.jsdelivr.net/npm/fullcalendar-scheduler@5.10.1/main.min.js'></script>
<script>
create_UUID = () => {
let dt = new Date().getTime();
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    let r = (dt + Math.random() * 16) % 16 | 0;
    dt = Math.floor(dt / 16);
    return (c == 'x' ? r :(r&0x3|0x8)).toString(16);
});
return uuid;
}
document.addEventListener('livewire:load', function () {
const Calendar = FullCalendar.Calendar;
const calendarEl = document.getElementById('calendar');
const Draggable = FullCalendar.Draggable;
    new Draggable(document.getElementById('events'), {
        itemSelector: '.dropEvent'
    });
const calendar = new Calendar(calendarEl, {
  headerToolbar: {
        left: 'promptResource prev,next today',
        center: 'title',
        right: 'resourceMonth,dayGridMonth,timeGridWeek,timeGridDay,listMonth'
      },
      views: {
        resourceMonth: {
        type: 'resourceTimelineMonth',
        buttonText: 'personnel'
        }
      },
      customButtons: {
        promptResource: {
          text: "+ personnel",
      click: function() {
        var title = prompt("Name");
        if (title) {
          calendar.addResource({
            title: title
          });
          fetch("add_resources.php", {
            method: "POST",
            headers: {
              Accept: "application/json"
            },
            body: encodeFormData({ title: title })
          })
            .then(response => console.log(response))
            .catch(error => console.log(error));
        }
      }
    }
  },
    initialView: 'resourceTimelineMonth',
    locale: '{{ config('app.locale') }}',
    events: JSON.parse(@this.events),
    resourceAreaHeaderContent: 'Personnel',
    resources: JSON.parse(@this.resources),
    //'https://fullcalendar.io/api/demo-feeds/resources.json?with-nesting&with-colors',
    editable: true,
    eventResize: info => @this.eventChange(info.event),
    eventDrop: info => @this.eventChange(info.event),
    eventReceive: info => {
        const id = create_UUID();
          info.event.setProp('id', id);
          @this.eventAdd(info.event);
    },
    selectable: true,
    select: function(selectionInfo) {
          $('#eventModal').modal('show');
          },
    eventClick: function(info) {
          // Display the modal and set the values to the event values.
          $('#updateEventModal').modal('show');
          $('#updateEventModal').find('#title').val(info.event.title);
          $('#updateEventModal').find('#acronym').val(info.event.acronym);
          $('#updateEventModal').find('#city').val(info.event.city);
          $('#updateEventModal').find('#start').val(info.event.start);
          $('#updateEventModal').find('#end').val(info.event.end);
          },
});
calendar.render();
});
</script>
<link href='https://cdn.jsdelivr.net/npm/fullcalendar-scheduler@5.11.3/main.min.css' rel='stylesheet' />
@endpush

我进一步将实际的模态从包含在这个文件中的部分分离出来,它是一个单独的livewire元素,现在称为eventmodal.blade.php:

<!-- Insert Modal -->
<div wire:ignore.self class="modal fade" id="eventModal" tabindex="-1" aria-labelledby="eventModalLabel"
    aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="eventModalLabel">Create Event</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
                    wire:click="closeModal"></button>
            </div>
            <form wire:submit.prevent="saveEvent">
                <div class="modal-body">
                    <div class="mb-3">
                        <label>Event Name</label>
                        <input type="text" id="title" wire:model="title" class="form-control">
                        @error('title') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event Acronym</label>
                        <input type="text" id="acronym" wire:model="acronym" class="form-control">
                        @error('acronym') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event City</label>
                        <input type="text" id="city" wire:model="city" class="form-control">
                        @error('city') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event Venue</label>
                        <input type="text" id="venue" wire:model="venue" class="form-control">
                        @error('venue') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event Value</label>
                        <input type="text" id="value" wire:model="value" class="form-control">
                        @error('value') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event Start</label>
                        <input type="text" id="start" wire:model="start" class="form-control">
                        @error('start') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event End</label>
                        <input type="text" id="end"  wire:model="end" class="form-control">
                        @error('end') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>

                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" wire:click="closeModal"
                        data-bs-dismiss="modal">Close</button>
                    <button type="submit" class="btn btn-primary">Save</button>
                </div>
            </form>
        </div>
    </div>
</div>

<!-- Update Event Modal -->
<div wire:ignore.self class="modal fade" id="updateEventModal" tabindex="-1" aria-labelledby="updateEventModalLabel"
    aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="updateEventModalLabel">Edit Event</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" wire:click="closeModal"
                    aria-label="Close"></button>
            </div>
            <form wire:submit.prevent="updateEvent">
                <div class="modal-body">
                    <div class="mb-3">
                        <label>Event Name</label>
                        <input type="text" id="title" wire:model="title" class="form-control">
                        @error('title') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event Acronym</label>
                        <input type="text" id="acronym" wire:model="acronym" class="form-control">
                        @error('acronym') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event City</label>
                        <input type="text" id="city" wire:model="city" class="form-control">
                        @error('city') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event Venue</label>
                        <input type="text" id="venue" wire:model="venue" class="form-control">
                        @error('venue') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event Value</label>
                        <input type="text" id="value" wire:model="value" class="form-control">
                        @error('value') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event Start</label>
                        <input type="text" id="start" wire:model="start" class="form-control">
                        @error('start') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>
                    <div class="mb-3">
                        <label>Event End</label>
                        <input type="text" id="end" wire:model="end" class="form-control">
                        @error('end') <span class="text-danger">{{ $message }}</span> @enderror
                    </div>

                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" wire:click="closeModal"
                        data-bs-dismiss="modal">Close</button>
                    <button type="submit" class="btn btn-primary">Update</button>
                </div>
            </form>
        </div>
    </div>
</div>

<!-- Delete Event Modal -->
<div wire:ignore.self class="modal fade" id="deleteEventModal" tabindex="-1" aria-labelledby="deleteEventModalLabel"
    aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="deleteEventModalLabel">Delete Event</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" wire:click="closeModal"
                    aria-label="Close"></button>
            </div>
            <form wire:submit.prevent="destroyEvent">
                <div class="modal-body">
                    <h4>Are you sure you want to delete this data ?</h4>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" wire:click="closeModal"
                        data-bs-dismiss="modal">Close</button>
                    <button type="submit" class="btn btn-primary">Yes! Delete</button>
                </div>
            </form>
        </div>
    </div>
</div>

1.其次,目前的模态保存功能不起作用。我不知道从哪里开始...我需要一个额外的路线?一些额外的代码的形式控制器?
1.最后,我的select函数...当您在默认的fullcalendar视图中单击一个日期或日期范围时,它不会从fullcalendar中获取日期范围,因为它没有使用标准函数的模态,如下所示:

select: arg => {
        const title = prompt('Title :');
        const id = create_UUID();
        if (title) {
            calendar.addEvent({
                id: id,
                title: title,
                start: arg.start,
                end: arg.end,
                allDay: arg.allDay
            });
            @this.eventAdd(calendar.getEventById(id));
        };
        calendar.unselect();
bbmckpt7

bbmckpt71#

感谢@ADyson,我已经设法检索的开始和结束日期的eventClick事件在我的livewire模态与calendar.blade.php如下:

//...previously posted calendar view code above
select: function(selectionInfo) {
                // Display the modal.
                // You could fill in the start and end fields based on the parameters
                $('#AddEventModal').modal('show');

            },
            eventClick: function(info) {
                // Display the modal and set the values to the event values.
                $('#AddEventModal').find('#title').val(info.event.title);
                $('#AddEventModal').find('#acronym').val(info.event.acronym);
                $('#AddEventModal').find('#start').val(info.event.start);
                $('#AddEventModal').find('#end').val(info.event.end);
                $('#AddEventModal').modal();
            },
...

正如您所看到的,我还尝试从events表中的另一个字段检索数据“acronym '。

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Event;
use App\Models\Resource;
use Illuminate\Support\Arr;

class Calendar extends Component
{
    public $events, $resources, $title, $acronym, $city, $venue, $value ;

    public function eventChange ( $event )
    {
    $e=Event::find($event['id']) ;
    $e->start=$event['start'] ;
    $e->acronym=$event['acronym'] ;
    if(Arr::exists($event,'end')) {
        $e->end=$event['end'];
    }
    $e->save();
    }

    public function render()
    {
        $this->events=json_encode(Event::all());
        $this->resources=json_encode(Resource::all());
        return view('livewire.calendar');
    }
    public function eventAdd ( $event )
    {
      Event::create ( $event );
    }
    public function eventRemove ( $id )
    {
      Event::destroy ( $id );
    }
    public function resourceAdd ( $resources )
    {
      Resource::create ( $resources );
    }
    public function resourceRemove ( $id )
    {
      Resource::destroy ( $id );
    }
}

相关问题