Daypilot日历:拖拽外部事件至日历后无法保存到MySQL数据库求助
DayPilot外部拖拽事件无法保存到MySQL的解决方案
问题描述
我正在试用DayPilot日历Demo,目前所有功能运行正常无报错,但无法将外部列表拖拽的事件通过PHP保存到MySQL数据库。我已经在代码里标记了预期添加保存逻辑的位置,但试了多种代码都无效。使用技术栈为DayPilot、PHP及MySQL。
现有代码
前端代码
<script> const dp = new DayPilot.Calendar("dp", { eventDeleteHandling: "Update", viewType: "Resources", onTimeRangeSelected: async (args) => { const modal = await DayPilot.Modal.prompt("Add event:", "Event 1"); dp.clearSelection(); if (modal.canceled) { return; } const params = { start: args.start, end: args.end, text: modal.result, resource: args.resource }; const {data} = await DayPilot.Http.post("backend_create.php", params); params.id = data.id; dp.events.add(params); }, onEventMoved: async (args) => { const params = { id: args.e.id(), start: args.newStart, end: args.newEnd, resource: args.newResource }; await DayPilot.Http.post("backend_move.php", params); }, ////////////////// onEventDeleted: async (args) => { const data = { id: args.e.id() }; await DayPilot.Http.post(`backend_delete.php`, data); console.log("Deleted."); }, ////////////////// onEventResized: async (args) => { const params = { id: args.e.id(), start: args.newStart, end: args.newEnd, resource: args.newResource }; await DayPilot.Http.post("backend_move.php", params); }, onEventClick: async (args) => { const colors = [ {name: "Blue", id: "#3c78d8"}, {name: "Green", id: "#6aa84f"}, {name: "Yellow", id: "#f1c232"}, {name: "Red", id: "#cc0000"}, ]; const form = [ {name: "Name", id: "text"}, {name: "Color", id: "color", type: "select", options: colors} ]; const modal = await DayPilot.Modal.form(form, args.e.data); if (modal.canceled) { return; } const data = { id: args.e.id(), text: modal.result.text, color: modal.result.color }; await DayPilot.Http.post(`backend_update.php`, data); dp.events.update({ ...args.e.data, text: modal.result.text, color: modal.result.color }); console.log("Updated."); }, onBeforeEventRender: args => { args.data.barColor = args.data.color; } }); dp.init(); dp.columns.load("backend_resources.php", function success() { // wait for columns to load dp.events.load("backend_events.php"); }); const app = { elements: { queue: document.querySelector("#queue"), drop: document.querySelector("#drop") }, initialize() { this.activateExternalItems(); this.activateDropTarget(); }, activateExternalItems() { const items = this.elements.queue.querySelectorAll(".queue-item"); for (let i = 0; i < items.length; i++) { const e = items[i]; const duration = DayPilot.Duration.ofMinutes(e.getAttribute("data-duration") || 60); const item = { element: e, data: { id: e.getAttribute("data-id"), text: e.innerText, duration: duration, } }; DayPilot.Calendar.makeDraggable(item); } }, activateDropTarget() { const drop = this.elements.drop; DayPilot.Calendar.registerDropTarget({ element: drop, onDrop: args => { drop.innerText += " " + args.data.text; drop.classList.remove("active"); ///// // This is where I think saving code should be. ///// }, onDragOver: args => { drop.classList.add("active"); }, onDragLeave: args => { drop.classList.remove("active"); } }); } }; // 冗余无效代码,需删除 // onDrop: async (args) => { // const params = { // id: args.e.id(), // start: args.newStart, // end: args.newEnd, // resource: args.newResource // }; // await DayPilot.Http.post("backend_drop.php", params); // }, app.initialize(); </script>
backend_create.php代码
<?php require_once '_db.php'; $json = file_get_contents('php://input'); $params = json_decode($json); $stmt = $db->prepare("INSERT INTO events (name, start, end, resource_id) VALUES (:name, :start, :end, :resource)"); $stmt->bindParam(':start', $params->start); $stmt->bindParam(':end', $params->end); $stmt->bindParam(':name', $params->text); $stmt->bindParam(':resource', $params->resource); $stmt->execute(); class Result {} $response = new Result(); $response->result = 'OK'; $response->message = 'Created with id: '.$db->lastInsertId(); $response->id = $db->lastInsertId(); header('Content-Type: application/json'); echo json_encode($response); ?>
解决方案
问题分析
- 原代码中
app对象外部定义的onDrop函数未被引用,完全无效。 - 自定义Drop目标的
onDrop回调未添加异步保存逻辑,也未构造正确的保存参数。
修改步骤
1. 修正前端Drop回调逻辑
将activateDropTarget中的onDrop回调改为异步函数,添加保存逻辑:
activateDropTarget() { const drop = this.elements.drop; DayPilot.Calendar.registerDropTarget({ element: drop, onDrop: async (args) => { drop.innerText += " " + args.data.text; drop.classList.remove("active"); // 构造事件参数:默认以当前时间为开始,拖拽项时长为结束 const start = DayPilot.Date.today(); const end = start.add(args.data.duration); // 默认选择第一个资源,可根据需求修改为用户选择或固定值 const resource = dp.columns.first().id(); const params = { text: args.data.text, start: start.toString(), end: end.toString(), resource: resource }; try { // 调用后端保存接口 const {data} = await DayPilot.Http.post("backend_create.php", params); params.id = data.id; // 将保存的事件添加到日历中 dp.events.add(params); console.log("事件保存成功"); } catch (error) { console.error("事件保存失败:", error); } }, onDragOver: args => { drop.classList.add("active"); }, onDragLeave: args => { drop.classList.remove("active"); } }); }
2. 删除无效代码
移除app对象外部的冗余onDrop函数,避免代码混乱。
3. 确认后端配置
- 确保
_db.php中的数据库连接信息正确,能正常连接MySQL。 - 确认
events表结构正确:包含name、start、end、resource_id字段,其中start和end建议用DATETIME类型,resource_id需与资源表ID类型匹配。
验证方法
- 拖拽外部列表项到
#drop区域。 - 查看浏览器控制台是否显示"事件保存成功"日志。
- 直接查询MySQL的
events表,确认新事件是否已插入。
内容的提问来源于stack exchange,提问作者andernicken
相关产品推荐
相关产品推荐

