FullCalendar日历组件:进行任务增删改,参考gitee例子修改

博客介绍了FullCalendar开发示例,给出参考路径为zxj/FullCalendar开发示例 - 码云 - 开源中国 (gitee.com),还展示了代码,包括主页面index.php和全后端连接save_calendar.php,同时提及了数据库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果

参考路径

zxj/FullCalendar开发示例 - 码云 - 开源中国 (gitee.com)

代码

主页面:index.php

<?php
ob_start();
include('includes/session.inc');
?>
<!DOCTYPE html>
<html>

<head>
    <title>日程管理</title>
    <meta charset="UTF-8">
    <style>
        #calendar {
            max-width: 1100px;
            height: auto;
            margin: 0 auto;
        }

        .qtip-default {
            border: 1px solid #ffffff !important;
            background-color: #ffffff !important;
            color: #555;
        }


        .qtip-event-detail .qtip-content {
            width: 255px;
            background-color: #ffffff;
            border: 1px solid #e0e0e0;
            border-radius: 2px;
            border-top: 3px solid #2878f0;
            padding: 2px;
            box-shadow: 0 0 8px rgba(0, 0, 0, .2);
        }

        .event-detail-wrap {
            padding: 10px;
            font-size: 14px;
            line-height: 26px;
            color: #666
        }

        .detail-info-list {
            color: #999;
        }

        .event-detail-wrap .action-group {
            border-top: 1px solid #e0e0e0;
            padding-top: 8px;
            margin-top: 8px;
            text-align: right;
        }

        .event-detail-wrap .action-group a {
            color: #2878f0;
            text-decoration: none;
            display: inline-block;
            margin-left: 6px;
        }
    </style>
    <link href="dist/jquery.qtip.min.css" rel="stylesheet" type="text/css" />
    <link href="dist/layui/css/layui.css" rel="stylesheet" type="text/css" />
</head>

<body>
    <div class="layui-three-main">
        <div class="layui-card">
            <div class="layui-card-body zgui-marginTop10">
                <div id="calendar"></div>
            </div>
        </div>

        <div id="add-wrapper" style="display: none;padding: 10px">
            <form class="layui-form" id="add-filter" lay-filter="add-filter">
                <div class="layui-row">
                    <div class="layui-form-item">
                        <label class="layui-form-label">任务标题<text style="color:red">*</text></label>
                        <div class="layui-input-block">
                            <input autocomplete="off" required="required" class="layui-input" lay-verify="required" name="title" placeholder="请输入" type="text">
                        </div>
                    </div>
                </div>
                <div class="layui-row">
                    <div class="layui-form-item">
                        <label class="layui-form-label">任务内容<text style="color:red">*</text></label>
                        <div class="layui-input-block">
                            <textarea class="layui-textarea" required="required" name="content" placeholder="请输入内容"></textarea>
                        </div>
                    </div>
                </div>
                <div class="layui-row">
                    <div class="layui-form-item">
                        <label class="layui-form-label">开始时间<text style="color:red">*</text></label>
                        <div class="layui-input-block">
                            <input autocomplete="off" class="layui-input" id="start" lay-verify="required|date" name="start" placeholder="请选择任务开始时间">
                        </div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label">结束时间<text style="color:red">*</text></label>
                        <div class="layui-input-block">
                            <input autocomplete="off" class="layui-input" id="end" lay-verify="required|date" name="end" placeholder="请选择任务结束时间">
                        </div>
                    </div>
                </div>
                <div class="layui-row">
                    <div class="layui-form-item">
                        <label class="layui-form-label">整天事件</label>
                        <div class="layui-input-block">
                            <input lay-skin="switch" name="allDay" title="是|否" type="checkbox" value="1">
                        </div>
                    </div>
                </div>
            </form>
        </div>
        <div id="edit-wrapper" style="display: none;padding: 10px">
            <form class="layui-form" id="edit-filter" lay-filter="edit-filter">
                <div class="layui-row">
                    <div class="layui-form-item">
                        <label class="layui-form-label">任务标题<text style="color:red">*</text></label>
                        <div class="layui-input-block">
                            <input autocomplete="off" required="required" class="layui-input" lay-verify="required" name="title" placeholder="请输入" type="text">
                        </div>
                    </div>
                </div>
                <div class="layui-row">
                    <div class="layui-form-item">
                        <label class="layui-form-label">任务内容<text style="color:red">*</text></label>
                        <div class="layui-input-block">
                            <textarea class="layui-textarea" required="required" name="content" placeholder="请输入内容"></textarea>
                        </div>
                    </div>
                </div>
                <div class="layui-row">
                    <div class="layui-form-item">
                        <label class="layui-form-label">开始时间<text style="color:red">*</text></label>
                        <div class="layui-input-block">
                            <input autocomplete="off" class="layui-input" id="start" lay-verify="required|date" name="start" placeholder="请选择任务开始时间">
                        </div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label">结束时间<text style="color:red">*</text></label>
                        <div class="layui-input-block">
                            <input autocomplete="off" class="layui-input" id="end" lay-verify="required|date" name="end" placeholder="请选择任务结束时间">
                        </div>
                    </div>
                </div>
                <div class="layui-row">
                    <div class="layui-form-item">
                        <label class="layui-form-label">整天事件</label>
                        <div class="layui-input-block">
                            <input lay-skin="switch" name="allDay" title="是|否" type="checkbox" value="1">
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
</body>
<script src="dist/index.global.min.js"></script>
<script src="dist/jquery-3.7.1.min.js"></script>
<script src="dist/jquery.qtip.min.js"></script>
<script src="dist/zh-cn.global.min.js"></script>
<script src="dist/layui/layui.js"></script>
<script type="text/javascript">
    layui.use(['layer', 'laydate', 'form', 'jquery'], function() {
        let layer = layui.layer; //创建各种弹出式窗口。
        let $ = layui.jquery; //可以通过 $ 来使用 jQuery 的功能
        let laydate = layui.laydate; //引入 layui 框架中的日期选择器模块,用于方便地选择日期和时间。
        let form = layui.form;
        //这行代码是调用 laydate 模块的 render 方法来渲染一个日期选择器,指定了要渲染的 HTML 元素为 id 为 start 的元素,
        //并且设置日期选择器的类型为 datetime,即包括日期和时间
        laydate.render({
            elem: '#start',
            type: 'datetime',
        });
        //这行代码也是渲染一个日期选择器,但是针对的是 id 为 end 的元素。
        laydate.render({
            elem: '#end',
            type: 'datetime',
        });
        //这里使用 layui 的 form 模块的 val 方法,通过传入表单的 id 或 class(这里是 'add-filter')和一个对象来设置对应字段的值。
        //这是一个对象字面量(Object Literal),表示要设置的字段名和对应的值。在这里,start 和 end 是表单字段的名称,startTime 和 endTime 是传入函数的参数,表示要设置的值。
        function setData(startTime, endTime) {
            // 格式化日期时间为年月日时分秒格式
            var currentDateTimeString = formatDate(new Date(startTime));
            var nextDayDateTimeString = formatDate(new Date(endTime));

            // 填充到表单字段中
            form.val('add-filter', {
                "start": currentDateTimeString,
                "end": nextDayDateTimeString,
            });
        }

        function formatDate(date) {
            var year = date.getFullYear();
            var month = (date.getMonth() + 1 < 10 ? '0' : '') + (date.getMonth() + 1);
            var day = (date.getDate() < 10 ? '0' : '') + date.getDate();
            var hours = (date.getHours() < 10 ? '0' : '') + date.getHours();
            var minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
            var seconds = (date.getSeconds() < 10 ? '0' : '') + date.getSeconds();

            return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
        }

        //新增任务
        function addTask(arg) {
            //调用函数 setData() 并传入上述三个参数,用于将事件的开始时间、结束时间填充到表单中。
            setData(arg.startStr, arg.endStr, arg.allDay);
            let index = layer.open({ //layui 的 layer.open() 方法创建一个弹出层,并将返回的索引值赋给变量 index。该方法接收一个配置对象作为参数,用于指定弹出层的各种属性和行为。
                type: 1, //弹出层的类型为普通层,即内容区域为一个固定大小的盒子。
                title: "新增任务",
                shade: false, //用于设置弹出层不显示遮罩层。
                area: ["800px", "600px"], //配置对象中的属性,用于设置弹出层的宽度为 800 像素,高度为 600 像素。
                btn: ['保存', '取消'], //配置对象中的属性,用于设置弹出层的底部按钮,第一个按钮显示文本 "保存",第二个按钮显示文本 "取消"。
                content: $('#add-wrapper'), // 用于设置弹出层的内容区域为 id 为 "add-wrapper" 的元素。该元素可能是一个表单或者其他需要展示的内容。
                //保存
                yes: function() {
                    let data = form.val('add-filter');
                    // 判断必填项是否已填写
                    if (data.title && data.content && data.start && data.end) {
                        // 发送数据到后端进行保存
                        $.ajax({
                            type: "POST",
                            url: "save_calendar.php", // 后端 PHP 文件的路径
                            data: {
                                action: 'save_event', // 指定要执行的方法
                                title: data.title,
                                content: data.content,
                                start: data.start,
                                end: data.end,
                                allDay: data.allDay ? 1 : ''
                            },
                            success: function(response) {
                                var response = JSON.parse(response);
                                if (response == 'success') {
                                    calendar.addEvent({
                                        action: 'save_event', // 指定要执行的方法
                                        title: data.title,
                                        content: data.content,
                                        start: data.start,
                                        end: data.end,
                                        allDay: data.allDay ? 1 : ''
                                    });
                                    calendar.unselect();
                                    layer.msg("保存成功", {
                                        time: 1000
                                    }, function() {
                                        // 删除成功后刷新整个页面
                                        location.reload();
                                    });
                                } else {
                                    layer.msg("保存失败");
                                }
                            }
                        });
                    } else {
                        layer.msg("请填写必填项", {
                            icon: 5
                        }); // 给出提示
                        return false; // 阻止提交
                    }
                },
                end: function() {
                    document.getElementById("add-filter").reset(); //来重置表单的字段值,将其恢复到初始状态
                }
            });
        };
        //日历组件
        let calendarEl = document.getElementById('calendar');
        //通过 new 关键字创建一个 FullCalendar 的日历对象。
        //第一个参数 calendarEl 是一个表示日历要插入的 DOM 元素的选择器或者元素对象。第二个参数是一个配置对象,用于设置日历的各种属性和行为
        let calendar = new FullCalendar.Calendar(calendarEl, {
            locale: 'zh-cn', //设置日历的语言为中文,即使用中文的月份和星期名称。
            headerToolbar: { //配置日历头部的工具栏,用于显示导航按钮和标题。
                left: 'prev,next today', //在左侧显示上一个、下一个和今天的导航按钮
                center: 'title', //在中间显示当前日期范围的标题。
                // right: 'multiMonthYear,dayGridMonth,timeGridWeek,timeGridDay' //在右侧显示多月份选择器、月视图、周视图和日视图的切换按钮。
                right: 'dayGridMonth,timeGridWeek'
            },
            // initialDate: "2023-09-13",//设置初始日期为 "2023-09-13",即日历加载时所显示的日期。
            navLinks: true, //启用导航链接功能,即当用户点击日期时可以跳转到对应的日视图。
            selectable: true, //启用选择功能,允许用户通过拖动鼠标选择日期范围。
            selectMirror: true, //启用选择镜像效果,即在用户拖动鼠标选择日期范围时,会显示一个半透明的镜像效果来预览选择的范围。
            select: function(arg) { //当用户完成选择日期范围时,执行的回调函数。在这段代码中,调用了 addTask(arg) 函数来处理新增任务的逻辑。参数 arg 包含了用户选择的日期范围信息。
                //新增任务
                addTask(arg);
            },
            eventClick: function(args) { //当用户点击日历中的事件时,执行的回调函数

            },
            eventDidMount: function(args) {

                // console.log(endFormatted)
                // var timeRange = args.event.startStr + ' - ' + args.event.endStr;
                if (args.event.allDay == 1) {
                    var timeRange = args.event.startStr + ' - ' + args.event.endStr;
                } else {
                    var start = new Date(args.event.start);
                    var end = new Date(args.event.end);
                    var options = {
                        year: 'numeric',
                        month: '2-digit',
                        day: '2-digit',
                        hour: '2-digit',
                        minute: '2-digit',
                        second: '2-digit'
                    };
                    var startFormatted = start.toLocaleString('zh-CN', options); // 格式化开始时间为本地日期时间字符串
                    var endFormatted = end.toLocaleString('zh-CN', options); // 格式化结束时间为本地日期时间字符串
                    var timeRange = startFormatted + ' - ' + endFormatted;
                }
                $(args.el).qtip({ //将 jQuery 对象 $(args.el) 转换为 qTip2 插件对象,并设置相关配置选项。
                    content: { //设置提示框的内容,包括日期范围、团队名称、科目和教师等信息,以及编辑和删除操作的链接。
                        text: `
							<div class="event-detail-wrap">
								<div class="detail-info-list">
									<div class="js_event_detail_time">${timeRange}</div>
									<div class="js_event_detail_team">${args.event.title}</div>
									<div class="js_event_detail_subject"></div>
									<div class="js_event_detail_teacher"></div>
								</div>
							
								<div class="action-group">
									<a href="#" id="edit">编辑</a>
									<a href="#" id="delete">删除</a>
								</div>
							</div>
							` //要提示的内容,就是上面创建的那个浮层
                    },
                    position: { //设置提示框在事件元素下方居中显示。
                        my: 'bottom center',
                        at: 'top center'
                    },
                    show: { //设置提示框只能单独显示,而不会同时出现多个。
                        solo: true //保证每次只显示一个提示框
                    },
                    hide: { //设置提示框隐藏的方式,包括是否可以操作提示框、隐藏延迟时间和触发隐藏的事件
                        fixed: true, //能够操作提示框
                        delay: 100, //多久之后隐藏提示框
                        event: ' mouseleave',
                    },
                    style: { //设置提示框的样式,这里使用了自定义的样式类 qtip-event-detail
                        classes: 'qtip-event-detail' //自定义的弹层样式
                    },
                    events: {
                        visible: function(event, api) {
                            // 在提示框显示完成后给删除按钮绑定点击事件
                            api.elements.content.find('#delete').on('click', function(e) {
                                e.preventDefault();
                                var eventId = args.event.id; // 获取事件的唯一标识符,用于指定要删除的事件
                                // 发送 AJAX 请求删除事件
                                $.ajax({
                                    url: 'save_calendar.php', // 后端处理删除事件的接口地址
                                    method: 'POST',
                                    data: {
                                        action: 'del_event',
                                        eventId: eventId
                                    }, // 传递要删除的事件ID
                                    success: function(response) {
                                        var response = JSON.parse(response);
                                        console.log(response)
                                        // 处理删除成功的情况
                                        if (response == 'success') {
                                            layer.msg("删除成功", {
                                                time: 1000
                                            }, function() {
                                                // 删除成功后刷新整个页面
                                                location.reload();
                                            });
                                        } else {
                                            layer.msg("删除失败");
                                        }
                                    },
                                });
                            });
                            //编辑
                            // 在提示框显示完成后给编辑按钮绑定点击事件
                            api.elements.content.find('#edit').on('click', function(e) {
                                e.preventDefault();
                                var eventId = args.event.id; // 获取事件的唯一标识符,用于指定要编辑的事件
                                $.ajax({
                                    url: 'save_calendar.php', // 后端处理获取事件详细信息的接口地址
                                    method: 'POST',
                                    data: {
                                        action: 'details_event',
                                        eventId: eventId
                                    }, // 传递要获取详细信息的事件ID
                                    success: function(response) {
                                        var eventDetails = JSON.parse(response);
                                        // 将事件详细信息填充到编辑表单中
                                        $('#edit-filter input[name="title"]').val(eventDetails.title);
                                        $('#edit-filter textarea[name="content"]').val(eventDetails.content);
                                        $('#edit-filter input[name="start"]').val(eventDetails.start);
                                        $('#edit-filter input[name="end"]').val(eventDetails.end);
                                        // 设置整天事件的默认值并更新复选框状态
                                        var form = layui.form;
                                        $('#edit-filter input[name="allDay"]').prop('checked', eventDetails.allDay === '1');
                                        form.render('checkbox'); // 重新渲染复选框,确保样式正确显示

                                        // 打开弹窗,显示填充好信息的编辑表单
                                        let index = layer.open({
                                            type: 1,
                                            title: "编辑任务",
                                            shade: false,
                                            area: ["800px", "600px"],
                                            btn: ['保存', '取消'],
                                            content: $('#edit-wrapper'),
                                            yes: function() {
                                                // 获取编辑表单中的数据并保存到后端
                                                var editedData = form.val('edit-filter');
                                                if (editedData.title && editedData.content && editedData.start && editedData.end) {
                                                    console.log(editedData)
                                                    // 发送数据到后端进行保存
                                                    $.ajax({
                                                        type: "POST",
                                                        url: "save_calendar.php",
                                                        data: {
                                                            action: 'edit_event',
                                                            eventId: eventId, // 传递要编辑的事件ID
                                                            title: editedData.title,
                                                            content: editedData.content,
                                                            start: editedData.start,
                                                            end: editedData.end,
                                                            allDay: editedData.allDay ? 1 : '',
                                                        },
                                                        success: function(response) {
                                                            var response = JSON.parse(response);
                                                            if (response == 'success') {
                                                                layer.msg("修改成功", {
                                                                    time: 1000
                                                                }, function() {
                                                                    // 删除成功后刷新整个页面
                                                                    location.reload();
                                                                });
                                                            } else {
                                                                layer.msg("修改失败");
                                                            }
                                                        }
                                                    });
                                                } else {
                                                    layer.msg("请填写必填项", {
                                                        icon: 5
                                                    }); // 给出提示
                                                    return false; // 阻止提交
                                                }
                                            },
                                        });
                                    }
                                });
                            });
                        }
                    }
                });
            },
            editable: true, //启用可编辑功能,允许用户通过拖拽事件元素来修改事件的时间和日期等信息。
            dayMaxEvents: true, // 启用“更多”链接功能,当某一天的事件数量过多时,会在日历中显示一个“更多”链接,点击链接可以查看所有事件。
            //静态数据
            events: [], // 初始时先为空,后续通过 AJAX 请求获取事件数据
        });
        // 发送 AJAX 请求获取数据库中的事件数据
        $.ajax({
            type: "POST",
            url: "save_calendar.php", // 后端 PHP 文件的路径
            data: {
                action: 'get_event', // 指定要执行的方法
            },
            success: function(response) {
                if (response) {
                    var eventsData = JSON.parse(response);
                    // console.log(eventsData)
                    // 将获取到的事件数据填充到日历组件中
                    calendar.addEventSource(eventsData);
                    // 重新渲染日历,显示最新的事件数据
                    calendar.render();
                }
            }
        });
        calendar.render();
    })
</script>

</html>

全后端连接:save_calendar.php

<?php
// 数据库连接参数
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "tianhao";
// 创建连接
$conn = mysqli_connect($servername, $username, $password, $dbname);
//执行保存事件
if ($_POST['action'] === 'save_event') {
    $title = $_POST['title'];
    $content = $_POST['content'];
    $start = strtotime($_POST['start']);
    $end = strtotime($_POST['end']);
    $allDay = $_POST['allDay'];
    $sql = "INSERT INTO calendar_info (title,content, start, end,allDay) VALUES ('$title', '$content', '$start', '$end', '$allDay')";
    $sql_result = mysqli_query($conn, $sql);
    if ($sql_result) {
        // 插入成功
        $response = 'success';
    } else {
        // 插入失败
        $response = 'failed';
    }
    // 返回处理结果给前端
    echo json_encode($response);
}
//获取事件
if ($_POST['action'] === 'get_event') {
    $sql_get = "select * from calendar_info";
    $sqlget_result = mysqli_query($conn, $sql_get);
    while ($row = mysqli_fetch_assoc($sqlget_result)) {
        $event = array(
            'id' => $row['id'],
            'title' => $row['title'],
            'content' => $row['content'],
            'start' => ($row['start'] ? date('Y-m-d H:i:s', $row['start']) : ''),
            'end' => ($row['end'] ? date('Y-m-d H:i:s', $row['end']) : ''),
            'allDay' => $row['allDay']
        );
        $events[] = $event; // 将每个事件添加到事件数组中
    }
    // 如果有数据,输出数组$events;如果没有数据,输出为0
    if (!empty($events)) {
        echo json_encode($events);
    } else {
        echo 0;
    }
}
//删除事件
if ($_POST['action'] === 'del_event') {
    $eventId = $_POST['eventId'];
    $sql_del = "DELETE FROM calendar_info WHERE id = $eventId";
    if (mysqli_query($conn, $sql_del)) { // 假设你使用的是 MySQL 数据库,$conn 是数据库连接对象
        $response = 'success';
    } else {
        // 插入失败
        $response = 'failed';
    }
    // 返回处理结果给前端
    echo json_encode($response);
}
//详细信息事件
if ($_POST['action'] === 'details_event') {
    $eventId = $_POST['eventId'];
    $sql_details = "SELECT * FROM calendar_info WHERE id = $eventId LIMIT 1";
    $sqldetails_result = mysqli_query($conn, $sql_details);

    if ($row = mysqli_fetch_assoc($sqldetails_result)) {
        $event = array(
            'id' => $row['id'],
            'title' => $row['title'],
            'content' => $row['content'],
            'start' => ($row['start'] ? date('Y-m-d H:i:s', $row['start']) : ''),
            'end' => ($row['end'] ? date('Y-m-d H:i:s', $row['end']) : ''),
            'allDay' => $row['allDay']
        );

        echo json_encode($event);
    } else {
        echo 0;
    }
}
//编辑事件
if ($_POST['action'] === 'edit_event') {
    $eventId = $_POST['eventId'];
    $title = $_POST['title'];
    $content = $_POST['content'];
    $start = strtotime($_POST['start']);
    $end = strtotime($_POST['end']);
    $allDay = $_POST['allDay'];
    // 更新数据库中对应事件ID的记录
    $sql_edit = "UPDATE calendar_info SET title = '$title ', content = '$content', start = '$start', end = '$end', allDay = '$allDay' WHERE id = $eventId";
    // 执行更新操作
    $result_edit = mysqli_query($conn, $sql_edit);
    if ($result_edit) {
        $response = 'success';
    } else {
        $response = 'failed';
    }
    echo json_encode($response);
}

数据库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

25号底片~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值