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";
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");
}
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.