0

I am trying out demo of Daypilot Calendar and I can't solve this last problem I have. I am trying to save "external events" in a MySQL DB using PHP when they are dropped in a calendar. But I am really stuck and would appreciate if anyone could help me or guide me?

Everything in the code works perfectly with no errors. I can't figure out how to save the dragged events in datbase? I have marked the code with the place I have tried various codes, but nothing had worked.

<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>
This is the code for backend_create.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);

Using Daypilot, PHP and MySQL.

When dragging an event from an external list, I can't figure out to save the data in the database. Creating an event with drag on calendar works fine.

see demo here: https://code.daypilot.org/90296/javascript-calendar-custom-drop-target-for-external-items

  • It seems like you would need to make an AJAX request to the server to send the data to it. Is that what you're stuck on? It wasn't 100% clear what the issue is or what you've tried. – ADyson Apr 17 '23 at 20:47
  • @ADyson I think Ajax is the best solution? I did manage the code for deleting events. But I don't know how to get the data from external drop. The external drop looks like this:
    Item 1
    . The data should be filled in DB: name (Item 1), start, end, resource_id (depending on where its dropped in calendar)
    – andernicken Apr 18 '23 at 11:02
  • It looks like the data would be available in `args.data` in the onDrop event? https://doc.daypilot.org/scheduler/external-drag-and-drop/ also suggests you can get this info via the `onEventMove` event of the calendar too. You may need to define this data in the `data: { id: e.getAttribute("data-id"), text: e.innerText, duration: duration, }` bit when you're creating the draggable item, so that it's then available later on. – ADyson Apr 18 '23 at 11:27
  • AJAX is good if you want to send the data asynchronously without reloading the page. I notice elsewhere in the code you've got `DayPilot.Http.post("backend_move.php", params);`...I don't know this library but I'm guessing that's maybe DayPilot wrapping an AJAX call into its own simple function call...so perhaps you should consider utilising that again. – ADyson Apr 18 '23 at 11:28

0 Answers0