javascript 在fullcalendar上更新和创建事件的问题(呈现事件信息和多个事件)

w6mmgewl  于 2023-01-07  发布在  Java
关注(0)|答案(1)|浏览(168)

我在一个laravel应用程序(8.75)上使用fullcalendar JS(6.0.1)和livewire,我有一个日历,上面有一些事件。
当我点击事件时,一个模态窗口打开,其中有一个表单,填写了标题,描述,开始日期和输入的所有日期等信息。输入被启用,我可以使用提交按钮更新事件,或使用另一个按钮删除它。
更新和删除功能正常工作。
当我点击某一天,同样的模态窗口打开一个空的表单(和删除按钮不出现当然)。我可以创建一个事件提交此表单,它的工作
我的问题是,在创建或更新之后,模态被关闭,我返回到日历。(或我所做的修改)(时间和标题),但如果我单击它查看详细信息,模态上的表单对于事件创建是空的(没有标题,描述,开始日期等),而我刚刚更新的数据为空。如果我单击日历上的任何其他事件,也是如此(以前创建的事件)。单击该页面时,我必须刷新该页面才能查看详细信息。
当我在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'));
    }
}

尽管我做了研究,我还是找不到解决办法。
有人知道这件事吗?

wpx232ag

wpx232ag1#

通过在调用select和eventClick方法的每个侦听器上使用removeEventListener(),并在回调函数的顶部添加evt. stopImmediatePropagation()以提交表单(用于创建和更新),我不再需要多次创建。
为了完成并避免在select和eventClick方法上调用不必要的eventlistener,我对侦听器进行了因子分解,以关闭calendar对象外部的模态(因为此函数没有使用calendar属性)

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>

相关问题