繁体   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