fullcalendar 为我的日期选择添加了 1 天

问题描述 投票:0回答:1

我遇到了日历问题。我使用 FullCalendar 来选择日期范围。例如,当我选择 11/20/23 到 11/22/23 时。

全日历又增加了 1 天(参见屏幕)。

这是我选择20到22时的结果。

我不明白问题从何而来。

这是我已经制作的代码。

var CalendarProduct = function () {
    var calendarUnvailable;
    var data = {
        id: '',
        eventName: '',
        startDate: '',
        endDate: '',
        allDay: false
    };

    // Add event variables
    var eventName;
    var eventDescription;
    var eventLocation;
    var startDatepicker;
    var startFlatpickr;
    var endDatepicker;
    var endFlatpickr;
    var startTimepicker;
    var startTimeFlatpickr;
    var endTimepicker
    var endTimeFlatpickr;
    var modal;
    var modalTitle;
    var form;
    var validator;
    var addButton;
    var submitButton;
    var cancelButton;
    var closeButton;

    var viewEventName;
    var viewAllDay;
    var viewEventDescription;
    var viewEventLocation;
    var viewStartDate;
    var viewEndDate;
    var viewModal;
    var viewEditButton;
    var viewDeleteButton;

    var initCalendarApp = function () {
        moment.locale('fr');
        let calendarElt = document.getElementById('date_unvailable');
        var todayDate = moment().startOf('day');
        var TODAY = todayDate.format('YYYY-MM-DD');

        calendarUnvailable = new FullCalendar.Calendar(calendarElt, {
            plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],
            events: JSON.parse(unvailable),
            initialView: 'dayGridWeek',
            headerToolbar: {
                left: 'prev,next today',
                center: 'title',
                right: 'dayGridMonth,timeGridWeek,timeGridDay'
            },
            locales: [frLocale],
            locale: 'fr',
            initialDate: TODAY,
            themeSystem: 'bootstrap',
            navLinks: true,
            selectable: true,
            selectMirror: true,
            dayHeaderContent: (args) => {
                return moment(args.date).format('dddd')
            },
            eventResize: function (info) {
                console.log(info);
            },

            // Select dates action --- more info: https://fullcalendar.io/docs/select-callback
            select: function (arg) {
                arg.allDay = false;
                formatArgs(arg);
                handleNewEvent();
            },
            eventDrop: function (info) {
                $.post(calendarUnvailableEditRoute, {
                    'datas': {
                        title: info.event.title,
                        id: info.event.id,
                        start: info.event.start.toISOString(),
                        end: info.event.end.toISOString()
                    }
                })
                    .done(function () {
                        Swal.fire(
                            "Enregistré !",
                            "Date déplacée",
                            "success"
                        )
                    })
                    .fail(function () {
                        Swal.fire(
                            "Internal Error",
                            "Votre date n'a pas été déplacée, contacter un administrateur",
                            "error"
                        )
                    })
            },
            eventClick: function (arg) {
                formatArgs({
                    id: arg.event.id,
                    title: arg.event.title,
                    startStr: arg.event.start,
                    endStr: arg.event.end,
                    allDay: arg.event.allDay
                });

                handleViewEvent();
            },

            editable: true,
            dayMaxEvents: true
        });
        calendarUnvailable.render();
    }

    const handleNewEvent = () => {
        // Update modal title
        modalTitle.innerText = "Ajouter une indisponibilité";

        modal.show();

        // Select datepicker wrapper elements
        const datepickerWrappers = form.querySelectorAll('[data-kt-calendar="datepicker"]');

        // Handle all day toggle
        const allDayToggle = form.querySelector('#kt_calendar_datepicker_allday');
        allDayToggle.addEventListener('click', e => {
            if (e.target.checked) {
                datepickerWrappers.forEach(dw => {
                    dw.classList.add('d-none');
                });
            } else {
                endFlatpickr.setDate(data.endDate, true, 'Y-m-d H:i');
                datepickerWrappers.forEach(dw => {
                    dw.classList.remove('d-none');
                });
            }
        });

        populateForm(data);

        // Handle submit form
        submitButton.addEventListener('click', function (e) {
            // Prevent default button action
            e.preventDefault();

            // Validate form before submit
            if (validator) {
                validator.validate().then(function (status) {
                    if (status == 'Valid') {
                        // Show loading indication
                        submitButton.setAttribute('data-kt-indicator', 'on');

                        // Disable submit button whilst loading
                        submitButton.disabled = true;

                        // Simulate form submission
                        setTimeout(function () {
                            // Simulate form submission
                            submitButton.removeAttribute('data-kt-indicator');

                            // Show popup confirmation
                            Swal.fire({
                                text: "Nouvelle disponibilité ajouté avec succès !",
                                icon: "success",
                                buttonsStyling: false,
                                confirmButtonText: "D'accord, j'ai compris !",
                                customClass: {
                                    confirmButton: "btn btn-primary"
                                }
                            }).then(function (result) {
                                if (result.isConfirmed) {
                                    modal.hide();

                                    // Enable submit button after loading
                                    submitButton.disabled = false;

                                    // Detect if is all day event
                                    let allDayEvent = false;
                                    if (allDayToggle.checked) {
                                        allDayEvent = true;
                                    }
                                    if (startTimeFlatpickr.selectedDates.length === 0) {
                                        allDayEvent = true;
                                    }
                                    // Merge date & time
                                    var startDateTime = moment(startFlatpickr.selectedDates[0]).format();
                                    var endDateTime = moment(endFlatpickr.selectedDates[endFlatpickr.selectedDates.length - 1]).format();
                                    if (!allDayEvent) {
                                        const startDate = moment(startFlatpickr.selectedDates[0]).format('YYYY-MM-DD');
                                        const endDate = startDate;
                                        const startTime = moment(startTimeFlatpickr.selectedDates[0]).format('HH:mm:ss');
                                        const endTime = moment(endTimeFlatpickr.selectedDates[0]).format('HH:mm:ss');

                                        startDateTime = startDate + 'T' + startTime;
                                        endDateTime = endDate + 'T' + endTime;
                                    }
                                    // Add new event to calendar
                                    calendarUnvailable.addEvent({
                                        id: uid(),
                                        title: eventName.value,
                                        start: startDateTime,
                                        end: endDateTime,
                                        className: 'fc-event-success',
                                        allDay: allDayEvent
                                    });
                                    calendarUnvailable.render();

                                    // Save in database
                                    $.post(calendarUnvailableAddRoute, {
                                        'datas': {
                                            title: eventName.value,
                                            start: startDateTime,
                                            end: endDateTime,
                                            allDay: allDayEvent
                                        }
                                    })
                                        .fail(function () {
                                            Swal.fire(
                                                "Internal Error",
                                                "Votre disponibilité n'a pas été enregistré, contacter un administrateur",
                                                "error"
                                            )
                                        })
                                    // Reset form for demo purposes only
                                    form.reset();
                                }
                            });

                            //form.submit(); // Submit form
                        }, 2000);
                    } else {
                        // Show popup warning
                        Swal.fire({
                            text: "Désolé, il semble qu'il y ait des erreurs détectées, veuillez réessayer.",
                            icon: "error",
                            buttonsStyling: false,
                            confirmButtonText: "D'accord, j'ai compris !",
                            customClass: {
                                confirmButton: "btn btn-primary"
                            }
                        });
                    }
                });
            }
        });
    }

    const initDatepickers = () => {
        startFlatpickr = flatpickr(startDatepicker, {
            enableTime: false,
            dateFormat: "d/m/Y",
            locale: French,
            static: true
        });

        endFlatpickr = flatpickr(endDatepicker, {
            enableTime: false,
            dateFormat: "d/m/Y",
            locale: French,
            static: true
        });

        startTimeFlatpickr = flatpickr(startTimepicker, {
            enableTime: true,
            noCalendar: true,
            dateFormat: "H:i",
            locale: French,
            static: true
        });

        endTimeFlatpickr = flatpickr(endTimepicker, {
            enableTime: true,
            noCalendar: true,
            dateFormat: "H:i",
            locale: French,
            static: true
        });
    }

    // Init validator
    const initValidator = () => {
        // Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
        validator = FormValidation.formValidation(
            form,
            {
                fields: {
                    'calendar_event_name': {
                        validators: {
                            notEmpty: {
                                message: 'Le titre est requis'
                            }
                        }
                    },
                    'calendar_event_start_date': {
                        validators: {
                            notEmpty: {
                                message: 'La date de début est requise'
                            }
                        }
                    },
                    'calendar_event_end_date': {
                        validators: {
                            notEmpty: {
                                message: 'La date de fin est requise'
                            }
                        }
                    }
                },
                plugins: {
                    trigger: new FormValidation.plugins.Trigger(),
                    bootstrap: new FormValidation.plugins.Bootstrap5({
                        rowSelector: '.fv-row',
                        eleInvalidClass: '',
                        eleValidClass: ''
                    })
                },
            }
        );
    }

    // Handle add button
    const handleAddButton = () => {
        addButton.addEventListener('click', e => {
            // Reset form data
            data = {
                id: '',
                startDate: new Date(),
                endDate: new Date(),
                allDay: false
            };
            handleNewEvent();
        });
    }

    const resetFormValidator = (element) => {
        // Target modal hidden event --- For more info: https://getbootstrap.com/docs/5.0/components/modal/#events
        element.addEventListener('hidden.bs.modal', e => {
            if (validator) {
                // Reset form validator. For more info: https://formvalidation.io/guide/api/reset-form
                validator.resetForm(true);
            }
        });
    }

    // Populate form
    const populateForm = () => {
        eventName.value = data.title ? data.title : '';
        startFlatpickr.setDate(data.startDate, true, 'Y-m-d');

        // Handle null end dates
        const endDate = data.endDate ? data.endDate : moment(data.startDate).format();
        endFlatpickr.setDate(endDate, true, 'Y-m-d');

        const allDayToggle = form.querySelector('#kt_calendar_datepicker_allday');
        const datepickerWrappers = form.querySelectorAll('[data-kt-calendar="datepicker"]');
        if (data.allDay) {
            allDayToggle.checked = true;
            datepickerWrappers.forEach(dw => {
                dw.classList.add('d-none');
            });
        } else {
            startTimeFlatpickr.setDate(data.startDate, true, 'Y-m-d H:i');
            endTimeFlatpickr.setDate(data.endDate, true, 'Y-m-d H:i');
            endFlatpickr.setDate(data.endDate, true, 'Y-m-d');
            allDayToggle.checked = false;
            datepickerWrappers.forEach(dw => {
                dw.classList.remove('d-none');
            });
        }
    }

    const formatArgs = (res) => {
        console.log(res);
        data.id = res.id;
        data.title = res.title;
        data.startDate = res.startStr;
        data.endDate = res.endStr;
        data.allDay = res.allDay;
    }

    const uid = () => {
        return Date.now().toString() + Math.floor(Math.random() * 1000).toString();
    }

    return {
        init: function () {
            const element = document.getElementById('kt_modal_add_event');
            if (element != undefined) {
                form = element.querySelector('#kt_modal_add_event_form');
                eventName = form.querySelector('[name="calendar_event_name"]');
                eventDescription = form.querySelector('[name="calendar_event_description"]');
                eventLocation = form.querySelector('[name="calendar_event_location"]');
                startDatepicker = form.querySelector('#kt_calendar_datepicker_start_date');
                endDatepicker = form.querySelector('#kt_calendar_datepicker_end_date');
                startTimepicker = form.querySelector('#kt_calendar_datepicker_start_time');
                endTimepicker = form.querySelector('#kt_calendar_datepicker_end_time');
                addButton = document.querySelector('[data-kt-calendar="add"]');
                submitButton = form.querySelector('#kt_modal_add_event_submit');
                cancelButton = form.querySelector('#kt_modal_add_event_cancel');
                closeButton = element.querySelector('#kt_modal_add_event_close');
                modalTitle = form.querySelector('[data-kt-calendar="title"]');
                modal = new bootstrap.Modal(element);

                const viewElement = document.getElementById('kt_modal_view_event');
                viewModal = new bootstrap.Modal(viewElement);
                viewEventName = viewElement.querySelector('[data-kt-calendar="event_name"]');
                viewAllDay = viewElement.querySelector('[data-kt-calendar="all_day"]');
                viewEventDescription = viewElement.querySelector('[data-kt-calendar="event_description"]');
                viewEventLocation = viewElement.querySelector('[data-kt-calendar="event_location"]');
                viewStartDate = viewElement.querySelector('[data-kt-calendar="event_start_date"]');
                viewEndDate = viewElement.querySelector('[data-kt-calendar="event_end_date"]');
                viewEditButton = viewElement.querySelector('#kt_modal_view_event_edit');
                viewDeleteButton = viewElement.querySelector('#kt_modal_view_event_delete');

                initCalendarApp();
                initValidator();
                initDatepickers();
                handleAddButton();
                resetFormValidator(element);
            }
        }
    }
}();

示例:

你知道这可能来自哪里吗?感谢您的帮助。

javascript symfony fullcalendar momentjs flatpickr
1个回答
0
投票

根据文档,fullcalendar 将结束日期视为排他性。您看到的结束日期是在活动结束后首次定义的。

因此如果选择22日全天,则22日结束后的第一个时刻就是23日午夜。

© www.soinside.com 2019 - 2024. All rights reserved.