簡體   English   中英

fullcalendar 上的事件更新和創建問題(呈現事件信息和多個事件)

[英]Problems on events update and creation on fullcalendar (rendering events infos and multiple events)

我在 laravel 應用程序 (8.75) 上使用帶 livewire 的 fullcalendar JS (6.0.1)。 我有一個包含一些事件的日歷。

當我單擊事件時,會打開一個模態 window,其中包含一個填寫了標題、描述、開始日期和全天輸入等信息的表單。 輸入已啟用,我可以使用提交按鈕更新事件或使用另一個按鈕將其刪除。

更新和刪除功能有效。

當我點擊某一天時,相同的模態 window 打開時會顯示一個空表單(當然不會出現刪除按鈕)。 我可以通過提交此表單來創建一個活動,它有效

我的問題是,在創建或更新之后,模態關閉,我返回到日歷。 我的新事件(或我所做的修改)出現在它(時間和標題)上,但如果我單擊它以查看詳細信息,模態上的表單對於事件創建是空的(沒有標題、描述、開始日期等)ans 空的數據我剛剛更改了更新。如果我單擊日歷上的任何其他事件(以前創建的事件)也是一樣的。 我必須刷新頁面才能在單擊它時查看詳細信息。

當我在 eventClick() 上記錄 info.event 時,即使我只是更改了某些內容,我也擁有所有正確的事件數據。 日歷上顯示的數據也是正確的。

因此,我認為這是由於我的模態表單填充功能所致,但我無法確定。

這是我的 livewire 組件:

<div>
    <div>
        <div id='calendar-container' wire:ignore>
            <div id='calendar' class="z-10"></div>
        </div>
    </div>
    @push('scripts')
    <script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.6.0/main.min.js'></script>
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.6.0/locales-all.min.js"></script>
    <script>
        document.addEventListener('livewire:load', function () {
            const Calendar = FullCalendar.Calendar;
            const calendarEl = document.getElementById('calendar');
            const calendar = new Calendar(calendarEl, {

                                    headerToolbar: {
                                        left: 'prev,next today',
                                        center: 'title',
                                        right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
                                    },

                                    locale: '{{config('app.locale')}}',

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

                                    editable: true,

                                    eventResize: info => @this.eventChange(info.event),

                                    eventDrop: info => @this.eventChange(info.event),

                                    selectable: true,

                                    unselectAuto: true,

                                    longPressDelay: 1,

                                    eventLongPressDelay: 1,

                                    selectLongPressDelay: 1,

                                    select: arg => {
                                        arg.jsEvent.preventDefault();

                                        // Select the modal
                                        let modal = document.getElementById('modal')

                                        // Empty inputs 
                                        modal.querySelectorAll('input').forEach((el) => {
                                            el.setAttribute('value', '')
                                        })
                                        
                                        // Unselect checkbox
                                        modal.querySelector('input[id="allDay"]').removeAttribute('checked')
                                        
                                        // If deletion button is present, hide it
                                        let deleteBtn = modal.querySelector('#delete')
                                        if(!deleteBtn.hasAttribute('hidden')) {
                                            deleteBtn.setAttribute('hidden', true)
                                        }

                                        // Fill the start date with the selected date
                                    modal.querySelector('input[id="start"]').setAttribute('value', (new Date((arg.start).toString().split('GMT')[0]+' UTC').toISOString()).substr(0,23))
                                        
                                        // Change modal title
                                        modal.querySelector('#modal-title').innerText = 'Create an event'
                                        
                                        // If modal is hidden
                                        if(modal.hasAttribute('hidden')) {
                                            // Display it
                                            modal.removeAttribute('hidden')
                                        }
                                        
                                        // On submitting form
                                        modal.querySelector('button[id="submitCreatingEventForm"]').addEventListener('click', (evt) => {
                                            evt.preventDefault()
                                            // evt.stopImmediatePropagation()
                                            
                                            if(title && start) {
                                                // allDay definition
                                                let allD = allDay.checked ? true : false

                                                // Adding event on db
                                                @this.eventAdd({
                                                    title: title.value,
                                                    description: description.value,
                                                    start: start.value,
                                                    end: end.value,
                                                    allDay: allD
                                                });

                                                // Adding event on calendar
                                                calendar.addEvent({
                                                    title: title.value,
                                                    description: description.value,
                                                    start: start.value,
                                                    end: end.value,
                                                    allDay: allD
                                                });
                                                
                                            }

                                        })
                                        
                                        // @this.render()
                                        // Close modal button
document.getElementById('close').addEventListener('click', (evt) => {
                                            document.getElementById('modal').setAttribute('hidden', true)
                                            @this.render()
                                            // Unselect the selection
                                            calendar.unselect();

                                        })
                                        // Unselect the selection
                                        calendar.unselect();
                                        calendar.render();
                                    },

                                    eventClick: info => {
                                        info.jsEvent.preventDefault();
                                        console.log(info.event);
                                        // Select the modal
                                        let modal = document.getElementById('modal')

                                        // Empty inputs 
                                        modal.querySelectorAll('input').forEach((el) => {
                                            el.setAttribute('value', '')
                                        })
                                        // Unselect checkbox
                                        modal.querySelector('input[id="allDay"]').removeAttribute('checked')
                                        
                                        let deleteBtn = modal.querySelector('#delete')
                                        // If deletion button is hidden
                                        if(deleteBtn.hasAttribute('hidden')) {
                                            // Display it
                                            deleteBtn.removeAttribute('hidden') 
                                        } 
                                        // If a report has already been create, disabled the deletion button
                                        if(info.event.extendedProps.report) {
                                            deleteBtn.setAttribute('disabled', '')
                                        } else {
                                            deleteBtn.removeAttribute('disabled')
                                        }
                                        // deletion button
                                        deleteBtn.addEventListener('click', (evt) => {
                                                evt.preventDefault()
                                                // Remove event form db
                                                @this.eventRemove(info.event.id)
                                                // remove event from calendar
                                                info.event.remove()
                                            })

                                        // Modify modal title
                                        modal.querySelector('#modal-title').innerText = 'Update an event'


                                        // If modal is hidden
                                        if(modal.hasAttribute('hidden')) {
                                            // Display it
                                            modal.removeAttribute('hidden')
                                        }

                                        // Fill the form inputs
                                        // Title
                                        modal.querySelector('input[id="title"]').setAttribute('value', info.event.title)

                                        // Description
                                        if(info.event.extendedProps.description != null) {
                                            modal.querySelector('input[id="description"]').setAttribute('value', info.event.extendedProps.description)
                                        }

                                        // Start date
                                        modal.querySelector('input[id="start"]').setAttribute('value', (new Date((info.event.start).toString().split('GMT')[0]+' UTC').toISOString()).substr(0,23))

                                        // allDay
                                        if(info.event.allDay) {
                                            modal.querySelector('input[id="allDay"]').setAttribute('checked', true)
                                        }

                                        // On form submitting
                                        modal.querySelector('button[id="submitCreatingEventForm"]').addEventListener('click', (evt) => {
                                            evt.preventDefault()

                                            const e = info.event

                                            if(title && start) {
                                                // Modify calendar event object
                                                if(title.value != e.title) {
                                                    e.setProp('title', title.value)
                                                }
                                                if(description.value != e.extendedProps.description) {
                                                    e.setExtendedProp( 'description', description.value )
                                                }
                                                if(start.value != (new Date((e.start).toString().split('GMT')[0]+' UTC').toISOString()).substr(0,23)) {
                                                    e.setStart(start.value)
                                                }
                                                if(allDay.checked != e.allDay) {
                                                    e.setAllDay(allDay.checked)
                                                }

                                                // Modify db event
                                                @this.eventUpdate({
                                                    id: e.id,
                                                    title: title.value,
                                                    description: description.value,
                                                    start: start.value,
                                                    end: end.value,
                                                    allDay: allDay.checked
                                                });
                    
                                                @this.render()

                                            }
                                        // deletion button
modal.querySelector('button[id="delete"]').addEventListener('click', (evt) => {
                                            // Remove event on calendar
                                            calendar.remove(e)
                                            // Remove event on db
                                            $this.eventRemove(e.id)
                                        })
                                        })
                                        // close modal button
document.getElementById('close').addEventListener('click', (evt) => {
                                            document.getElementById('modal').setAttribute('hidden', true)
                                            calendar.render()
                                        })

                                    }
                                });
            calendar.render();
        
        });


    </script>
    <link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.6.0/main.min.css' rel='stylesheet' />
    @endpush
    <div id="modal" hidden>
        <div>
            <form>
                <div>
                    <h1 id="modal-title">Créer un événement</h1>
                    
                    <button id="submitCreatingEventForm" type="submit" >Enregistrer</button>
                </div>

                <div>
                    <div>
                        <label for="title">
                            Titre *
                        </label>
                        <input id="title" type="text">
                    </div>
                </div>
                <div>
                    <div>
                        <label for="description">
                            Description
                        </label>
                        <input id="description" type="text">
                    </div>
                </div>
                <div>
                    <div>
                        <label for="start">
                            Début *
                        </label>
                        <input id="start" type="datetime-local" name="start">
                    </div>
                    <div>
                        <label for="allDay">Journée entière</label>
                        <input id="allDay" type="checkbox" name="allDay" value="true">
                    </div>
                    <div hidden>
                        <label for="end">
                            Fin
                        </label>
                        <input id="end" type="datetime-local" name="end">
                    </div>
                </div>
            </form>    
            <div id="modal-buttons">
                <button id="close">Fermer</button>
                <button id="delete">Supprimer</button>
            </div>
        </div>
    </div>
</div>

您是否看到任何可能導致此問題的原因?

這是我的日歷組件:

<?php

namespace App\Http\Livewire;

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

class Calendar extends Component
{
    public $events = [];

    public function mount($events)
    {
        $this->events = json_encode($events);
    }

    public function render()
    {
        return view('livewire.calendar');
    }

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

    public function eventRemove($id)
    {
        Event::destroy($id);
    }

    public function eventUpdate($event)
    {
        $e = Event::find($event['id']);
        $e->title = $event['title'];
        $e->description = $event['description'];
        $e->start = $event['start'];
        $e->end = $event['end'];
        $e->allDay = $event['allDay'];

        if($e->isDirty()) {
            $e->update($event);
        }
    }

    public function reload() {
        return redirect(request()->header('Referer'));
    }
}

盡管我進行了研究,但我仍然找不到解決方案。

有人知道嗎?

通過在調用 select 和 eventClick 方法的每個偵聽器上使用 removeEventListener() 並在我的回調函數頂部添加 evt.stopImmediatePropagation() 以提交 forms(用於創建和更新),我不再有多個創建。

為了完成並避免在 select 和 eventClick 方法上調用不必要的事件偵聽器,我分解了偵聽器以關閉日歷 object 之外的模式(因為此 function 上沒有任何內容使用日歷屬性)


select: arg => {
[...]
let submitCreationBtn = modal.querySelector('button[id="submitCreatingEventForm"]')
submitCreationBtn.addEventListener('click', handleSubmitCreationForm)

function handleSubmitCreationForm(evt) {
    evt.preventDefault()
    
    evt.stopImmediatePropagation()
    
    if(title && start) {
        
        let allD = allDay.checked ? true : false

        @this.eventAdd({
            title: title.value,
            description: description.value,
            start: start.value,
            end: end.value,
            allDay: allD
        });

        calendar.addEvent({
            title: title.value,
            description: description.value,
            start: start.value,
            end: end.value,
            allDay: allD
        });
        
    }
    submitCreationBtn.removeEventListener('click', handleSubmitCreationForm)
}

[...]
}
eventClick: info => {
[...]
let submitUpdateBtn = modal.querySelector('button[id="submitCreatingEventForm"]')
submitUpdateBtn.addEventListener('click', handleSubmitUpdateForm)
function handleSubmitUpdateForm(evt) {
    evt.preventDefault()
    evt.stopImmediatePropagation()

    const e = info.event

    if(title && start) {
        if(title.value != e.title) {
            e.setProp('title', title.value)
        }
        if(description.value != e.extendedProps.description) {
            e.setExtendedProp( 'description', description.value )
        }
        if(start.value != (new Date((e.start).toString().split('GMT')[0]+' UTC').toISOString()).substr(0,23)) {
            e.setStart(start.value)
        }
        if(allDay.checked != e.allDay) {
            e.setAllDay(allDay.checked)
        }

        @this.eventUpdate({
            id: e.id,
            title: title.value,
            description: description.value,
            start: start.value,
            end: end.value,
            allDay: allDay.checked
        });

        @this.render()
    }
    submitUpdateBtn.removeEventListener('click', handleSubmitUpdateForm)

}
[...]
}

<script>
[...]
    let closeBtn = document.getElementById('close')
    closeBtn.addEventListener('click', handleClickOnCloseBtn)
    function handleClickOnCloseBtn(evt) {
        document.getElementById('modal').setAttribute('hidden', true)
    }
[...]
</script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM