FullCalendar, how do I allow users to edit/delete

2019-03-22 09:57发布

问题:

I am having a little bit of trouble controlling the Full Calendar module as I would like. At the moment I have it so that the calendars getEvents method contacts an SQL table and returns all of the events for a user - that part works perfectly.

The functionality I would like to add is to allow users to edit/delete events and have these changes be reflected in the database as they are made! By this I mean that in my table the user can drag and drop events to change their times, and when they click on an event, I wish for a dialog to appear asking them if they wish to delete this event. I would like these changes to be represented in the SQL table.

How can I do this? I am new to JQuery, JavaScript and DatePicker. From my googling and attempts to learn, I have found a similar thread here

function (calEvent) {
  removeRequestedEvent($(this), calEvent);
},
It just passes in the calendar event and the calendar itself.

removeRequestedBooking: function (cal, calEvent) {
    if (!confirm("Delete?"))
        return;

    cal.fullCalendar("removeEvents", calEvent.id);
    cal.fullCalendar("rerenderEvents");

    // Re-show draggable element
    $("#requests #" + calEvent.id).show();
}

which gives this code, which I believe is similar to what I need, however I wish to remove the event from the database when removeEvents is called. I assume I need some code similar to what I have when events are retrieved from the database (code shown below) but I am not sure how the code should be structured. Can anyone help me out with this ?

var db = Database.Open("users");
            var result = db.Query("SELECT * FROM events");
            var data = result.Select(x => new 
            {
                id = x.id,
                title = x.title,
                start = x.start.ToString("s"),
                end = x.end.ToString("s"),
                allDay = false            
            }).ToArray();

            Json.Write(data, Response.Output);
            Response.ContentType = "application/json";

回答1:

I remove events from the calendar and database through an AJAX call. Here is some sample code

On event click

eventClick: function(event){
            var start = $.fullCalendar.formatDate(event.start, "yyyy-MM-dd HH:mm");
            var end = $.fullCalendar.formatDate(event.end, "yyyy-MM-dd HH:mm");
            var id = event.id;
            var title = event.title;
            $("#edit_start").val(start);   //this just populates the value into my dialog form
            $("#edit_end").val(end);
            $("#edit_title").val(title);
            $("#edit_event_id").val(id);
            $("#edit_class" ).dialog( "open" );   //open the dialog

this is the dialog info

        $( "#edit_class" ).dialog({
        autoOpen: false,
        height: 300,
        width: 350,
        modal: true,
        buttons: {
            "Delete Class": function() {
                var event_id = $("#edit_event_id").val();
                $.ajax({
                    type:"POST",
                    url: "delete_class.php",
                    data: "event_id=" + event_id,

                });
                $('#calendar').fullCalendar('refetchEvents'); //the event has been removed from the database at this point so I just refetch the events
                $( this ).dialog( "close" );
            },

        },

    });

Edit class div that shows when I open the dialog

<div id="edit_class" title="Edit Class">

    <form action="">
<fieldset>
    </select>
    <p>
    </p>
    <label for="edit_start">Start</label>
    <input type="text" name="edit_start" id="edit_start" class="text ui-widget-content ui-corner-all" />
    <p>
    </p>
    <label for="edit_end">End</label>
    <input type="text" name="edit_end" id="edit_end" class="text ui-widget-content ui-corner-all" />
    <p>
    </p>
    <label for="title">Class Name</label>
    <input type="text" name="edit_title" id="edit_title" class="text ui-widget-content ui-corner-all" />
    <p>
    </p>
    <label for="edit_event_id"></label>
    <input type="hidden" name="edit_event_id" id="edit_event_id" class="text ui-widget-content ui-corner-all" />
</fieldset>

And then on the delete_class.php page I have something like the following

 $event_id = $_POST['event_id'];
try
{
    $dbh = new PDO("mysql:host=$mysql_hostname;dbname=$mysql_dbname", $mysql_username, $mysql_password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $dbh->prepare(
                "DELETE FROM events 
                WHERE event_id = :event_id ");
    $stmt->bindParam(':event_id', $event_id, PDO::PARAM_STR);
    $stmt->execute();   
}
catch(Exception $e)
{
echo ("error");
}


回答2:

The best way to do this would be using AJAX with jQuery

function deleteEvent(id)
{
    // The URL to which we will make the AJAX call
    var url = "MyCalendar.aspx";
    // Setup the data to send to the server
    var sendData =
    {
        "action":"deleteEvent",
        "id":id
    };
    // Make the AJAX call
    var xhr = $.post(url, sendData, function(result)
    {
        // The response is up to the method you implement in the server side, be it json or text.
        // For simplicity's sake let's assume you return a '0' for OK or '1' for ERROR
        if(result == '0')
        {
            // Remove the event from the calendar since we know it all went well server-side
            cal.fullCalendar("removeEvents", id);
            cal.fullCalendar("rerenderEvents");
        }
        else
        {
            // There was an error server-side, put a message or something...
            alert("Could not remove event. Try again later.");
        }
    });
    xhr.error = function()
    {
        // There was an error trying to complete the request
        alert("Could not complete request.");
    }
}

On the server side, I'll assume you are going to use the same page to process the AJAX request, in this case you would do something like this in your PageLoad event:

protected void Page_Load(object sender, EventArgs e)
{
    // Check if we received a POST value with name 'action'
    string action = Request["action"];
    if(action != null)
    {
        // It's an AJAX Call
        if(action == "deleteEvent")
        {
            // At this point we should expect a POST value with name 'id'
            int id = int.Parse(Request["id"]);
            // Execute action
            DoActionDeleteEvent(id);
            // Do nothing else since it's an AJAX call
            return;
        }
    }

}

private void DoActionDeleteEvent(int id)
{
    Response.ContentType = "text/plain";
    try
    {
        // ToDo: Delete the event from the database
        // All went well, write 0 in the response.
        Response.Write("0");
    }
    catch
    {
        // There was an error, write 1 in the response
        Response.Write("1");
    }
    // End the response
    Response.End();
}

That way all changes should reflect in the database and the calendar.

As for the edition, you would be doing something very similar, but instead of returning a 0 or 1, you would return a JSON object with the new edited event.