The Event Calendar lists the events date-wise in a large calendar view. The events are fetched dynamically and listed under the date cell. An event calendar makes it easier to find the events for a specific date. You can build a custom event calendar with dynamic data using PHP and MySQL. In the previous tutorial, we learn how to build an event calendar with PHP and MySQL. This tutorial will show you how to create an event calendar with PHP using the FullCalendar JavaScript library.
FullCalendar is a JavaScript library that helps to integrate a Full-sized event calendar on a website quickly. It provides a user-friendly way to add events to the calendar and display them on the date cell. We will use the FullCalendar library to build an event calendar with PHP and MySQL. Not only the event listing but also we will integrate CRUD functionality with FullCalendar.
The following functionality will be implemented to build PHP event calendar with FullCalendar.
Before getting started, take a look at the file structure of the PHP event calendar with FullCalendar JS plugin script.
php_event_calendar_with_fullcalendar/ ├── index.html ├── fetchEvents.php ├── eventHandler.php ├── dbConfig.php ├── js/ │ ├── fullcalendar/ │ └── sweetalert2.all.min.js └── css/ └── style.css
To display the dynamic events in the calendar, the event data need to be stored in the database. The following SQL creates a events
table with some basic fields in the MySQL database.
CREATE TABLE `events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`description` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
`url` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`start` date NOT NULL,
`end` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
This file is used to connect with the database using PHP and MySQL. Specify the database host (DB_HOST
), username (DB_USERNAME
), password (DB_PASSWORD
), and name (DB_NAME
) as per your database credentials.
<?php
// Database configuration
define('DB_HOST', 'MySQL_Database_Host');
define('DB_USERNAME', 'MySQL_Database_Username');
define('DB_PASSWORD', 'MySQL_Database_Password');
define('DB_NAME', 'MySQL_Database_Name');
// Create database connection
$db = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check connection
if ($db->connect_error) {
die("Connection failed: " . $db->connect_error);
}
Dialog Boxes: Include the sweetalert2 plugin library to initialize and use it for popup boxes.
<script src="js/sweetalert2.all.min.js"></script>
Calendar Plugin: Include FullCalendar JS & CSS library to build full-sized calendar using JavaScript.
<link href="js/fullcalendar/lib/main.css" rel="stylesheet" />
<script src="js/fullcalendar/lib/main.js"></script>
Calendar Container: Define an HTML element to attach the event calendar.
<div id="calendar"></div>
Initialize the FullCalendar class on the DOMContentLoaded event and render the calendar on the web page.
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
height: 650,
});
calendar.render();
});
</script>
In the following examples, we will see how to integrate event listing, details, add, and delete functionality to FullCalendar using JavaScript.
Fetch events from the server-side and list them on the Calendar:
events
option in FullCalendar configurations to set the server-side script URL (fetchEvents.php
) that the calendar will fetch the event data from.document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
height: 650,
events: 'fetchEvents.php',
});
calendar.render();
});
Add Event:
select
callback function to attach Event Add feature.selectable
option must be set to true
which makes the date cell selectable.Swal.fire()
method is used to display popup boxes.eventHandler.php
) via HTTP POST request using JavaScript Fetch API.calendar.refetchEvents()
method is called to fetch the updated events list.document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
height: 650,
events: 'fetchEvents.php',
selectable: true,
select: async function (start, end, allDay) {
const { value: formValues } = await Swal.fire({
title: 'Add Event',
html:
'<input id="swalEvtTitle" class="swal2-input" placeholder="Enter title">' +
'<textarea id="swalEvtDesc" class="swal2-input" placeholder="Enter description"></textarea>' +
'<input id="swalEvtURL" class="swal2-input" placeholder="Enter URL">',
focusConfirm: false,
preConfirm: () => {
return [
document.getElementById('swalEvtTitle').value,
document.getElementById('swalEvtDesc').value,
document.getElementById('swalEvtURL').value
]
}
});
if (formValues) {
// Add event
fetch("eventHandler.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_type:'addEvent', start:start.startStr, end:start.endStr, event_data: formValues}),
})
.then(response => response.json())
.then(data => {
if (data.status == 1) {
Swal.fire('Event added successfully!', '', 'success');
} else {
Swal.fire(data.error, '', 'error');
}
// Refetch events from all sources and rerender
calendar.refetchEvents();
})
.catch(console.error);
}
}
});
calendar.render();
});
View event details:
eventClick
callback function to attach the event view details feature.Swal.fire()
method is used to display popup boxes.info.event
object is used to get the event details set in Event Objects.info.event.extendedProps
is used to get the additional info from Event Objects.document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
height: 650,
events: 'fetchEvents.php',
eventClick: function(info) {
info.jsEvent.preventDefault();
// change the border color
info.el.style.borderColor = 'red';
Swal.fire({
title: info.event.title,
icon: 'info',
html:'<p>'+info.event.extendedProps.description+'</p><a href="'+info.event.url+'">Visit event page</a>',
});
}
});
calendar.render();
});
Edit and Delete Event:
eventHandler.php
). The info.event.id
is passed to this POST request as the DB reference ID of the selected event, along with the form input data.eventHandler.php
). The info.event.id
is passed to this POST request as the DB reference ID of the selected event.calendar.refetchEvents()
method is called to fetch the updated events list.document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
height: 650,
events: 'fetchEvents.php',
selectable: true,
select: async function (start, end, allDay) {
const { value: formValues } = await Swal.fire({
title: 'Add Event',
confirmButtonText: 'Submit',
showCloseButton: true,
showCancelButton: true,
html:
'<input id="swalEvtTitle" class="swal2-input" placeholder="Enter title">' +
'<textarea id="swalEvtDesc" class="swal2-input" placeholder="Enter description"></textarea>' +
'<input id="swalEvtURL" class="swal2-input" placeholder="Enter URL">',
focusConfirm: false,
preConfirm: () => {
return [
document.getElementById('swalEvtTitle').value,
document.getElementById('swalEvtDesc').value,
document.getElementById('swalEvtURL').value
]
}
});
if (formValues) {
// Add event
fetch("eventHandler.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_type:'addEvent', start:start.startStr, end:start.endStr, event_data: formValues}),
})
.then(response => response.json())
.then(data => {
if (data.status == 1) {
Swal.fire('Event added successfully!', '', 'success');
} else {
Swal.fire(data.error, '', 'error');
}
// Refetch events from all sources and rerender
calendar.refetchEvents();
})
.catch(console.error);
}
},
eventClick: function(info) {
info.jsEvent.preventDefault();
// change the border color
info.el.style.borderColor = 'red';
Swal.fire({
title: info.event.title,
icon: 'info',
html:'<p>'+info.event.extendedProps.description+'</p><a href="'+info.event.url+'">Visit event page</a>',
showCloseButton: true,
showCancelButton: true,
showDenyButton: true,
cancelButtonText: 'Close',
confirmButtonText: 'Delete',
denyButtonText: 'Edit',
}).then((result) => {
if (result.isConfirmed) {
// Delete event
fetch("eventHandler.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_type:'deleteEvent', event_id: info.event.id}),
})
.then(response => response.json())
.then(data => {
if (data.status == 1) {
Swal.fire('Event deleted successfully!', '', 'success');
} else {
Swal.fire(data.error, '', 'error');
}
// Refetch events from all sources and rerender
calendar.refetchEvents();
})
.catch(console.error);
} else if (result.isDenied) {
// Edit and update event
Swal.fire({
title: 'Edit Event',
html:
'<input id="swalEvtTitle_edit" class="swal2-input" placeholder="Enter title" value="'+info.event.title+'">' +
'<textarea id="swalEvtDesc_edit" class="swal2-input" placeholder="Enter description">'+info.event.extendedProps.description+'</textarea>' +
'<input id="swalEvtURL_edit" class="swal2-input" placeholder="Enter URL" value="'+info.event.url+'">',
focusConfirm: false,
confirmButtonText: 'Submit',
preConfirm: () => {
return [
document.getElementById('swalEvtTitle_edit').value,
document.getElementById('swalEvtDesc_edit').value,
document.getElementById('swalEvtURL_edit').value
]
}
}).then((result) => {
if (result.value) {
// Edit event
fetch("eventHandler.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_type:'editEvent', start:info.event.startStr, end:info.event.endStr, event_id: info.event.id, event_data: result.value})
})
.then(response => response.json())
.then(data => {
if (data.status == 1) {
Swal.fire('Event updated successfully!', '', 'success');
} else {
Swal.fire(data.error, '', 'error');
}
// Refetch events from all sources and rerender
calendar.refetchEvents();
})
.catch(console.error);
}
});
} else {
Swal.close();
}
});
}
});
calendar.render();
});
The following code snippet shows how to handle the List/View/Add/Edit/Update/Delete functionality from the server-side using PHP and MySQL.
Fetch Events (fetchEvents.php):
<?php
// Include database configuration file
require_once 'dbConfig.php';
// Filter events by calendar date
$where_sql = '';
if(!empty($_GET['start']) && !empty($_GET['end'])){
$where_sql .= " WHERE start BETWEEN '".$_GET['start']."' AND '".$_GET['end']."' ";
}
// Fetch events from database
$sql = "SELECT * FROM events $where_sql";
$result = $db->query($sql);
$eventsArr = array();
if($result->num_rows > 0){
while($row = $result->fetch_assoc()){
array_push($eventsArr, $row);
}
}
// Render event data in JSON format
echo json_encode($eventsArr);
The eventHandler.php
file is used to handle Add and Delete functionality. Based on the request_type
param, the code block is executed.
Add Event (eventHandler.php):
The request is accepted if the request_type=addEvent
.
Update Event (eventHandler.php):
The request is accepted if the request_type=editEvent
.
Delete Event (eventHandler.php):
The request is accepted if the request_type=deleteEvent
.
<?php
// Include database configuration file
require_once 'dbConfig.php';
// Retrieve JSON from POST body
$jsonStr = file_get_contents('php://input');
$jsonObj = json_decode($jsonStr);
if($jsonObj->request_type == 'addEvent'){
$start = $jsonObj->start;
$end = $jsonObj->end;
$event_data = $jsonObj->event_data;
$eventTitle = !empty($event_data[0])?$event_data[0]:'';
$eventDesc = !empty($event_data[1])?$event_data[1]:'';
$eventURL = !empty($event_data[2])?$event_data[2]:'';
if(!empty($eventTitle)){
// Insert event data into the database
$sqlQ = "INSERT INTO events (title,description,url,start,end) VALUES (?,?,?,?,?)";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("sssss", $eventTitle, $eventDesc, $eventURL, $start, $end);
$insert = $stmt->execute();
if($insert){
$output = [
'status' => 1
];
echo json_encode($output);
}else{
echo json_encode(['error' => 'Event Add request failed!']);
}
}
}elseif($jsonObj->request_type == 'editEvent'){
$start = $jsonObj->start;
$end = $jsonObj->end;
$event_id = $jsonObj->event_id;
$event_data = $jsonObj->event_data;
$eventTitle = !empty($event_data[0])?$event_data[0]:'';
$eventDesc = !empty($event_data[1])?$event_data[1]:'';
$eventURL = !empty($event_data[2])?$event_data[2]:'';
if(!empty($eventTitle)){
// Update event data into the database
$sqlQ = "UPDATE events SET title=?,description=?,url=?,start=?,end=? WHERE id=?";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("sssssi", $eventTitle, $eventDesc, $eventURL, $start, $end, $event_id);
$update = $stmt->execute();
if($update){
$output = [
'status' => 1
];
echo json_encode($output);
}else{
echo json_encode(['error' => 'Event Update request failed!']);
}
}
}elseif($jsonObj->request_type == 'deleteEvent'){
$id = $jsonObj->event_id;
$sql = "DELETE FROM events WHERE id=$id";
$delete = $db->query($sql);
if($delete){
$output = [
'status' => 1
];
echo json_encode($output);
}else{
echo json_encode(['error' => 'Event Delete request failed!']);
}
}
?>
Build an Event Calendar with PHP using jQuery, Ajax, and MySQL
This guide helps you to create an event calendar with PHP using the FullCalendar plugin. The example code shows how to integrate list/view/add/edit/update/delete functionality with the FullCalendar library using PHP and MySQL. You can allow the user to manage events on a full-sized calendar dynamically. The functionality of the event calendar can be enhanced easily with FullCalendar as per your needs.
If you want to add an event for multiple days, the event creation form requires inputs for FromDate and ToDate. Just submit the service request from the link below for functionality enhancement as needed.
Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request
Hello,
Is it possible to show a list view of all the events for a specific time period?
Let me send you a very great THANK for your tutorial and for your job.
Nice job, could you add script snippet for including drag & drop from external ?
how do i do this with datetime variable
Hi there. Thanks a lot for the article. I’m wondering what changes are required in order to add times to events that are not intended to be “all day” events?
Thanks!
Great work !