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

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);
?>

解决方案

问题分析

  1. 原代码中app对象外部定义的onDrop函数未被引用,完全无效。
  2. 自定义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类型匹配。

验证方法

  1. 拖拽外部列表项到#drop区域。
  2. 查看浏览器控制台是否显示"事件保存成功"日志。
  3. 直接查询MySQL的events表,确认新事件是否已插入。

内容的提问来源于stack exchange,提问作者andernicken

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:37:19