0
votes

I'm in the middle of developing a drag and drop event fullcalendar with a resource column. I'm able to drag and drop events on the calendar and save it to the database. For the resource column, I have an add room button that allows users to add the room which also gets saved in the database. The resources and events are successfully being fetched and displayed on the calendar. Now, I'm working on developing the delete functionality for the same. For now, I'm stuck at deleting the events using a double click.

Here's the code:

main.js

document.addEventListener("DOMContentLoaded", function() {
var containerEl = document.getElementById("external-events");
var checkbox = document.getElementById("drop-remove");
new FullCalendarInteraction.Draggable(containerEl, {
 itemSelector: ".fc-event",
  eventData: function(eventEl) {
    return {
      title: eventEl.innerText
   };
 }
 });

 var calendarEl = document.getElementById("calendar");
 var calendar = new FullCalendar.Calendar(calendarEl, {
 schedulerLicenseKey: "GPL-My-Project-Is-Open-Source",
 plugins: ["interaction", "resourceTimeline", 'dayGrid', 'timeGrid' ],
header: {
  left: "promptResource today prev,next",
  center: "title",
  right: 'dayGridMonth,resourceTimelineDay,resourceTimelineWeek'
 },
customButtons: {
  promptResource: {
    text: "+ room",
    click: function() {
      var title = prompt("Room name");
      console.log(title);
      if (title) {
        fetch("add_resources.php", {
            method: "POST",
             headers: {
                 'Accept': 'text/html' 
             },
             body: encodeFormData({"title": title}),
              }) 
                .then(response => response.text())
             .then(response => { 
            calendar.addResource({
          id: response,
          title: title
        });

        })
          .catch(error => console.log(error));
      }
    }
  }
},
editable: true,
aspectRatio: 1.5,
defaultView: "resourceTimelineDay",
resourceLabelText: "Rooms",
resources: "all_resources.php",
droppable: true,
drop: function(info) {
  if (checkbox.checked) {
    info.draggedEl.parentNode.removeChild(info.draggedEl);
  }
},
eventLimit: true,
events: "all_events.php",
displayEventTime: false,
eventRender: function(event, element, view) {

  if (event.allDay === "true") {
    event.allDay = true;
  } else {
    event.allDay = false;
  }
},


selectable: true,
selectHelper: true,
eventClick: function (info) {    
        var confimit = confirm("Do you really want to delete?");
        if (confimit) {             
            $.ajax({
                type: "POST",
                url: "delete_event.php",
                  data: "&id=" + info.event.id,
                success: function (response) {

                    if(parseInt(response) > 0) {
                        $('#calendar').fullCalendar('removeEvents', info.event.id);
                        displayMessage("Deleted Successfully");
                    }
                }
            });
        }
    },
eventReceive: function(info) {
  console.log(calendar.getResources());
  console.log(info.event);
  var eventData = {
    title: info.event.title,
    start: moment(info.event.start).format("YYYY-MM-DD HH:mm"),
    end: moment(info.event.start).format("YYYY-MM-DD HH:mm"),
    resourceid: info.event._def.resourceIds[0]
  };

  console.log(eventData);
  //send the data via an AJAX POST request, and log any response which comes from the server
  fetch("add_event.php", {
    method: "POST",
    headers: {
      Accept: "application/json"
    },
    body: encodeFormData(eventData)
  })

    .then(response => console.log(response))
    .catch(error => console.log(error));    
}        
});
calendar.render();
 });

 const encodeFormData = data => {
     var form_data = new FormData();
   for (var key in data) {
     form_data.append(key, data[key]);
   }
  return form_data;
 };

delete_event.php

<?php
require "connection.php";
$id = $_POST['id'];
$conn = DB::databaseConnection();
$sql = "DELETE FROM Events WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
 if ($stmt->execute()) {
    return $stmt->fetch(PDO::FETCH_ASSOC);
    } else {
    return null;
   }
 ?> 

When I'm trying to delete an event using the above code, I double click on the event, I see the message asking if I really want to delete the event, but it doesn't really get deleted. I don't see the delete_event.php being called in the network panel. The console has the error "ReferenceError: $ is not defined". I'm not sure what is wrong in the code above.

1
"ReferenceError: $ is not defined" means you didn't include jQuery in your page, but tried to use some jQuery code. You seem to have tried to use $.ajax({ instead of fetch for some reason, even though in your previous questions we have discussed the fact that you aren't using jQuery any more, and therefore cannot use jQuery functions. I also showed you how to use fetch.ADyson
P.S. eventClick responds to a single-click on the event, not double-click.ADyson
I didn't just copy paste someone else's code. But yes, I had built in fullcalendar version 3 earlier, and used the same code. I should have looked the documentation before.AAM
Okay. But I can use the eventClick function right? In that case, I would be unsure on how to define the id in there?AAM
Tried something like this. It's incomplete though. Can you please check? eventClick: function (info) { var confimit = confirm("Do you really want to delete?"); if (confimit) { fetch("delete_event.php", { method: "POST", headers: { Accept: "application/json" } }); } }, The above code loads the delete_events.php file in the network panel. But gives an error "id undefined". Clearly, it's not being defined there.AAM

1 Answers

1
votes

You need to make a few modifications to your code.

1) use fetch() instead of $.ajax, then you won't get any error messages about jQuery being missing. Ensure you put the event ID into the body of the request.

2) use the fullCalendar v4 syntax for eventClick, instead of v3 - see https://fullcalendar.io/docs/eventClick.

3) Remove the $stmt->fetch command from your PHP - a SQL DELETE operation doesn't return any results, so there is nothing to fetch. I also removed the meaningless return statements, because you're not inside a function, and your script doesn't have any further code which needs to be prevented from executing.

eventClick:

eventClick: function (info) { 
  var confimit = confirm("Do you really want to delete?");
  if (confimit) {
    fetch("delete_event.php", {
      method: "POST",
      body: encodeFormData({"id": info.event.id}) }); 
    }
  }
}

delete_event.php:

<?php
require "connection.php";
$id = $_POST['id'];
$conn = DB::databaseConnection();
$sql = "DELETE FROM Events WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
if ($stmt->execute()) {
    echo true;
    } else {
    echo false;
   }
 ?>