You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel模态框中FullCalendar无法选择日期问题排查

Laravel项目中模态框内FullCalendar初始无法选择日期的问题排查与解决

问题描述

在Laravel项目里,点击输入框会弹出包含FullCalendar的Bootstrap模态框,但打开模态框后无法直接选择日期,必须点击切换月份按钮后才能正常选择日期。已尝试调整FullCalendar配置项和模态框的z-index属性,均未解决问题。

相关代码

JavaScript代码

var calendarEl = document.getElementById('calendario');

calendar = new FullCalendar.Calendar(calendarEl, {
    showNonCurrentDates: true,
    locale: 'es',
    selectable: true,
    editable: true,
    eventColor: 'red',
    eventTextColor: '#fff',
    height: 'auto',
    buttonText: {
        today: 'Hoy',
    },
    eventOverlap: false,
    dateClick: function (info) {
        // 获取日历中选中的日期
        var fechaSeleccionada = info.dateStr;
        // 更新输入框的值为选中的日期
        document.getElementById("fechaCita").value = fechaSeleccionada;
    },
    dayCellContent: function (info) {
        info.dayNumberText = info.dayNumberText.replace(/^0+/,
            ''); // 去除左侧的零
        return {
            html: '<span class="fc-day-number">' + info.dayNumberText + '</span>'
        };
    },
    dayCellDidMount: function (info) {
        var el = info.el;
        var num = el.querySelector('.fc-day-number');
        if (num) {
            num.style.color = '#000'; // 将日期数字颜色改为黑色
        }
        el.style.backgroundColor = '#fff'; // 将日期单元格背景改为白色
    },
    dayHeaderContent: function (info) {
        return {
            html: "<span style='color: black'>" + info.text + "</span>"
        };
    },
});

calendar.render();

fechaCita.addEventListener("click", function () {
    var modalEl = document.getElementById('calendarioModal');
    var modal = new bootstrap.Modal(modalEl);
    modal.show();
});

HTML代码

<div class="modal fade" tabindex="-1" id="calendarioModal" aria-labelledby="modal-fecha-label" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-body">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <br>
                <div id="calendario"></div>
            </div>
        </div>
    </div>
</div>

问题原因

核心问题是FullCalendar在模态框处于隐藏状态(display: none)时完成了初始化渲染。此时日历的DOM元素没有实际尺寸,FullCalendar无法正确绑定日期单元格的点击事件,也无法计算交互区域的位置。只有当点击月份切换按钮触发日历重新渲染时,DOM已经处于可见状态,交互逻辑才会正常工作。

解决办法

方法一:模态框显示后再初始化/渲染日历

将日历的初始化或渲染逻辑移到Bootstrap模态框的shown.bs.modal事件回调中,确保模态框完全显示后再处理日历:

var calendar = null;
var modalEl = document.getElementById('calendarioModal');

// 绑定模态框显示完成事件
modalEl.addEventListener('shown.bs.modal', function() {
    if (!calendar) {
        // 首次显示时初始化日历
        var calendarEl = document.getElementById('calendario');
        calendar = new FullCalendar.Calendar(calendarEl, {
            showNonCurrentDates: true,
            locale: 'es',
            selectable: true,
            editable: true,
            eventColor: 'red',
            eventTextColor: '#fff',
            height: 'auto',
            buttonText: {
                today: 'Hoy',
            },
            eventOverlap: false,
            dateClick: function (info) {
                var fechaSeleccionada = info.dateStr;
                document.getElementById("fechaCita").value = fechaSeleccionada;
            },
            dayCellContent: function (info) {
                info.dayNumberText = info.dayNumberText.replace(/^0+/, '');
                return {
                    html: '<span class="fc-day-number">' + info.dayNumberText + '</span>'
                };
            },
            dayCellDidMount: function (info) {
                var el = info.el;
                var num = el.querySelector('.fc-day-number');
                if (num) {
                    num.style.color = '#000';
                }
                el.style.backgroundColor = '#fff';
            },
            dayHeaderContent: function (info) {
                return {
                    html: "<span style='color: black'>" + info.text + "</span>"
                };
            },
        });
    }
    // 强制渲染日历
    calendar.render();
}, { once: true }); // 确保事件只绑定一次

fechaCita.addEventListener("click", function () {
    var modal = new bootstrap.Modal(modalEl);
    modal.show();
});

方法二:模态框显示后强制重新渲染日历

如果不想调整初始化时机,直接在模态框显示后调用calendar.render()刷新日历:

fechaCita.addEventListener("click", function () {
    var modalEl = document.getElementById('calendarioModal');
    var modal = new bootstrap.Modal(modalEl);
    
    // 模态框显示完成后重新渲染日历
    modalEl.addEventListener('shown.bs.modal', function() {
        calendar.render();
    });
    
    modal.show();
});

注意事项

  • 避免重复绑定事件:使用{ once: true }选项或全局绑定事件,防止每次点击输入框都添加新的事件监听。
  • 不要提前渲染日历:移除原代码中提前执行的calendar.render(),确保日历在模态框可见后才完成渲染。

内容的提问来源于stack exchange,提问作者Martín Yanes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:10:01