Creating Dynamic PHP Event Management Calander using AJAX and Bootstrap
Managing events effectively frequently requires dealing with dates and times. Using a calendar component comes out as the best technique to display events within a visual framework in this scenario. Its convenience outperforms alternative perspectives like card view and list view.
The FullCalendar JavaScript library is used in this example to manage and show events. The events are retrieved from a database using PHP and MySQL.
The following script describes a simple PHP event management system augmented with AJAX capability. The AJAX handlers improve event management by facilitating connections between the PHP endpoint and the database.
What is inside?
- Use case of the Event management system
- About Ajax Based Event management system
- Folder Structure
- Creating a calendar interface using Bootstrap
- Add new, Edit, update, or load existing events onto the calendar
- PHP Code to create, update, delete and fetch events
- Database script
- Example output Screenshot, download button, and live demo
FullCalendar properties
Use case of the Event management system
The main objective of an event management system is to use software to automate the process of creating and managing event data. This simplifies the event management workflow, ensuring consistency and control.
A system like this allows for the categorization of events based on a variety of parameters. Events, for example, can be categorized by organizers, locations, timings, and other characteristics.
The software's characteristics and features have been thoroughly created to be useful to its core users, both event organizers and attendees.
About Ajax Based Event management system
This code snippet allows users to easily create events via a calendar interface. Events are saved in a database and shown on the calendar according to their dates.
When you click on a date box, a user-friendly JavaScript popup appears for you to enter event details. After confirmation, the data is delivered via AJAX and processed via PHP.
For calendar creation, the system makes use of the jQuery-powered FullCalendar library with Bootstrap styling. It incorporates simple library directives for easy navigation and editing.
The dynamic data from the database is retrieved via AJAX and shown in JSON format on the calendar view.
Folder Structure:
Creating a calendar interface using Bootstrap
This PHP event management sample includes a simple calendar interface for event creation and maintenance. The HTML structure contains a container for presenting the calendar, which is accomplished by using FullCalendar.
The libraries jQuery AJAX, Bootstrap, and FullCalendar were used in the implementation. The provided code snippet demonstrates the HTML layout, along with the necessary library dependencies.
<!DOCTYPE html>
<html>
<head>
<title> AJAX-Based Event Management System with Bootstrap 4.6</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<link rel="stylesheet" href="fullcalendar/fullcalendar.min.css" />
<script src="fullcalendar/lib/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
<script src="fullcalendar/lib/moment.min.js"></script>
<script src="fullcalendar/fullcalendar.min.js"></script>
<style>
h1#demo-title {
margin: 30px 0px 80px 0px;
text-align: center;
}
table tr {
position: relative;
}
#event-action-response {
background-color: #c4c6fb;
border: #0ab53f 1px solid;
padding: 10px 20px;
border-radius: 3px;
margin-bottom: 15px;
color: #333;
display: none;
}
.fc-day-grid-event .fc-content {
background: #617cff;
color: #FFF;
margin-bottom: 4px;
padding: 3px;
border-radius: 5px;
}
/* .fc-event,
.fc-event-dot {
background-color: #586e75;
} */
.fc-event,
.fc-event-dot {
background-color: #ededed;
}
.fc-event {
border: 1px solid #fff;
}
.delete-event-icon {
position: absolute;
top: 1px;
right: 3px;
cursor: pointer;
z-index: 9;
color: white;
background: #ff5252;
width: 20px;
height: 20px;
border-radius: 50%;
text-align: center;
line-height: 20px;
}
/*Right modal*/
.modal.left_modal .modal-dialog,
.modal.right_modal .modal-dialog {
position: fixed;
margin: auto;
width: 32%;
height: 100vh;
-webkit-transform: translate3d(0%, 0, 0);
-ms-transform: translate3d(0%, 0, 0);
-o-transform: translate3d(0%, 0, 0);
transform: translate3d(0%, 0, 0);
}
.right_modal .modal-content {
height: 100%;
}
.modal.right_modal.fade .modal-dialog {
right: -50%;
-webkit-transition: opacity 0.3s linear, right 0.3s ease-out;
-moz-transition: opacity 0.3s linear, right 0.3s ease-out;
-o-transition: opacity 0.3s linear, right 0.3s ease-out;
transition: opacity 0.3s linear, right 0.3s ease-out;
}
.modal.right_modal.fade.show .modal-dialog {
right: 0;
box-shadow: 0px 0px 19px rgba(0, 0, 0, .5);
}
/* ----- MODAL STYLE ----- */
.modal-content {
border-radius: 0;
border: none;
}
.modal-header.left_modal,
.modal-header.right_modal {
padding: 10px 15px;
border-bottom-color:
#EEEEEE;
background-color:
#FAFAFA;
}
.modal_outer .modal-body {
/*height:90%;*/
overflow-y: auto;
overflow-x: hidden;
height: 91vh;
}
</style>
</head>
<body>
<!-- <div class="container">
<h1 id="demo-title">AJAX-Based Event Management System with
Bootstrap</h1>
<div id="event-action-response"></div>
<div id="calendar"></div>
</div> -->
<div class="container">
<h1 id="demo-title">AJAX-Based Event Management System with
Bootstrap 4.6</h1>
<div id="event-action-response"></div>
<div id="calendar"></div>
</div>
<!-- Display event details in a modal -->
<div id="eventDetailsModal" class="modal modal_outer right_modal fade " tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit Selected Event</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="eventDetails"></div>
</div>
<div class="modal-footer d-flex justify-content-between">
<button id="updateEvent" class="btn btn-primary">Update</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal modal_outer right_modal fade " id="addEventModal" tabindex="-1" role="dialog" aria-labelledby="addEventModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addEventModalLabel">Add Event</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form id="addEventForm">
<div class="form-group">
<label for="eventTitle">Event Title</label>
<input type="text" class="form-control" id="eventTitle" name="eventTitle" required>
</div>
<div class="form-group">
<label for="eventDate">Event Date</label>
<input type="date" class="form-control" id="eventDate" name="eventDate" required>
</div>
<button type="submit" class="btn btn-primary">Add Event</button>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
Example output Screenshot:
FullCalendar properties :
- editable: Allows events to be draggable and resizable.
- eventLimit: Limits the number of events displayed per day.
- droppable: Allows external elements to be dropped onto the calendar to create events.
- eventColor: Sets the background color of events.
- eventTextColor: Sets the text color of events.
- eventBorderColor: Sets the border color of events.
- eventResize: Allows events to be resized.
- header: Defines the navigation buttons and their positions.
- events: Specifies the URL to fetch events from using AJAX.
- displayEventTime: Controls whether event times are displayed.
- eventRender: Callback function to customize event rendering.
Header options that you can use for the header configuration:
- title: Displays the current view's title, such as the month or week name.
- prev: Displays the previous button to navigate to the previous period.
- next: Displays the next button to navigate to the next period.
- prevYear: Displays the previous year button to navigate to the previous year.
- nextYear: Displays the next year button to navigate to the next year.
- today: Displays the today button to jump to the current date.
- basicDay: Displays the "Day" button to switch to the basic day view.
- agendaDay: Displays the "Day" button to switch to the agenda day view.
- basicWeek: Displays the "Week" button to switch to the basic week view.
- agendaWeek: Displays the "Week" button to switch to the agenda week view.
- month: Displays the "Month" button to switch to the month view.
- listYear: Displays the "Year" button to switch to the year list view.
- listMonth: Displays the "Month" button to switch to the month list view.
- listWeek: Displays the "Week" button to switch to the week list view.
- listDay: Displays the "Day" button to switch to the day list view.
You can customize the header by including any combination of these options. For example, if you want to display the previous and next buttons, the title, and the month view button, you can use the following configuration:
header: {
left: 'prev, next',
center: 'title',
right: 'month, listYear'
}
You can also change the header buttonText:
header: {
left: 'prev,next',
center: 'title',
right: 'month'
},
buttonText: {
prev: 'Previous', // Text for the previous button
next: 'Next', // Text for the next button
today: 'Today', // Text for the today button
month: 'Month' // Text for the month button
}
Add new, Edit, update, or load existing events onto the calendar
Once the calendar interface is displayed on the landing page, existing events are neatly organized within the corresponding day cells. When a day is selected, a bootstrap modal will appears, enabling the user to input the event title. Upon clicking 'add event', the event is then added to the database for the chosen date. When a user clicks on the existing event then a bootstrap modal will open with the selected event title here you can change the event title and update it, To enable this functionality, ensure 'selectable: true' is set in the configuration, allowing day selection.
The given script initializes the FullCalendar library and handles AJAX-based tasks such as requesting, creating, and modifying events. The script dynamically updates event info by generating a calendar object. Additionally, because of the 'editable: true' setting, events added to the calendar can be changed, allowing drag-and-drop actions to change event dates.
FullCalendar provides customizable header options for Month, Week, and Day views. This customization enhances control placement within the calendar header, aiding user navigation.
$(document).ready(function() {
var calendar = $('#calendar').fullCalendar({
editable: true,
events: 'getEvent.php',
selectable: true,
selectHelper: true,
header: {
right: 'prevYear, prev, next, nextYear, today',
left: 'title',
center: 'listMonth, listYear, month, basicWeek'
},
buttonText: {
listMonth: 'List Month',
listYear: 'List Year',
},
displayEventTime: true,
// select: function(start, allDay) {
// var Event = prompt("Add Event");
// if (Event) {
// var Date = $.fullCalendar.formatDate(start, "Y-MM-DD");
// $("#event-action-response").hide();
// $.ajax({
// url: "addEvent.php",
// type: "POST",
// data: {
// title: Event,
// start: Date
// },
// success: function() {
// calendar.fullCalendar('refetchEvents');
// $("#event-action-response").html("Event added Successfully");
// $("#event-action-response").show();
// }
// });
// }
// },
select: function(start, allDay) {
var selectedDate = start.format('YYYY-MM-DD');
// Set the selected date in the modal input
$("#eventDate").val(selectedDate);
$("#addEventModal").modal('show'); // Open the modal
},
eventRender: function(event, element) {
// Add a delete icon to each event listing
var deleteIcon = $("<span class='delete-event-icon' data-event-id='" + event.id + "'>×</span>");
element.append(deleteIcon);
// Attach a click event to the delete icon
deleteIcon.click(function(event) {
event.stopPropagation(); // Prevent event propagation to parent elements
var eventId = $(this).data("event-id"); // Get the event ID from the data attribute
if (confirm("Are you sure you want to delete this event?")) {
deleteEvent(eventId);
}
});
},
eventDrop: function(event, delta, revertFunc) {
if (!confirm("Are you sure about to move this event?")) {
revertFunc();
} else {
var editedDate = $.fullCalendar.formatDate(event.start, "Y-MM-DD");
$("#event-action-response").hide();
$.ajax({
url: "editevent.php",
type: "POST",
data: {
event_id: event.id,
start: editedDate
},
success: function(resource) {
calendar.fullCalendar('refetchEvents');
$("#event-action-response").html("Event moved Successfully");
$("#event-action-response").show();
}
});
}
},
eventClick: function(event) {
if (!$(event.target).hasClass('delete-event-icon')) {
$.ajax({
url: "getEventDetailSingle.php",
type: "GET",
data: {
event_id: event.id
},
success: function(data) {
$("#eventDetails").html(data);
$("#eventDetailsModal").modal('show');
// Update event functionality
$("#updateEvent").click(function() {
var updatedTitle = $("#editTitle").val();
var updatedStartDate = $("#editStartDate").val();
var event_id = $("#event_id").val();
$.ajax({
url: "updateEvent.php",
type: "POST",
data: {
event_id: event_id,
updatedTitle: updatedTitle,
updatedStartDate: updatedStartDate
},
success: function(response) {
if (response === "Event updated successfully.") {
calendar.fullCalendar('refetchEvents');
$("#eventDetailsModal").modal('hide');
} else {
// Handle error
}
},
error: function() {
// Handle error
}
});
});
}
});
}
}
});
// Handle form submission
$("#addEventForm").submit(function(event) {
event.preventDefault();
var eventTitle = $("#eventTitle").val();
var eventDate = $("#eventDate").val();
$.ajax({
url: "addEvent.php",
type: "POST",
data: {
title: eventTitle,
start: eventDate
},
success: function() {
calendar.fullCalendar('refetchEvents');
$("#event-action-response").html("Event added Successfully");
$("#event-action-response").show();
$("#addEventModal").modal('hide'); // Close the modal
$("#addEventForm").trigger('reset');
}
});
});
// Function to delete an event
function deleteEvent(eventId) {
$("#event-action-response").hide();
$.ajax({
url: "deleteEvent.php",
type: "POST",
data: {
event_id: eventId
},
success: function(response) {
if (response === "deleted") {
calendar.fullCalendar('refetchEvents');
$("#event-action-response").html("<span class='text-danger'>Event Deleted Successfully</span>");
$("#event-action-response").show();
} else {
// Handle error
console.log('error');
}
},
error: function() {
// Handle error
}
});
}
});
SQL Code to create a table into your database
--
-- Table structure for table `events`
--
DROP TABLE IF EXISTS `events`;
CREATE TABLE IF NOT EXISTS `events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`event_date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;
PHP Code to create, update, delete, and fetch events
The PHP code below manages event data, reading from or storing it in the database. The 'db.php' file, utilized in the following code snippets, establishes the MySQL connection.
Prepared statements are employed to execute database queries in this example. This practice helps safeguard the application against SQL injection, enhancing security.
PHP Code to Create Database Connection
<?php
$connect = new PDO('mysql:host=localhost;dbname=event_management_php', 'root', '');
PHP Code to fetch all exsisting event
Create getEvent.php and past the below code
<?php
require_once "db.php";
$data = array();
$query = "SELECT * FROM events ORDER BY id";
$statement = $connect->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
foreach ($result as $row) {
$data[] = array(
'id' => $row["id"],
'title' => $row["title"],
'start' => $row["event_date"]
);
}
echo json_encode($data);
PHP Code to store event
<?php
require_once "db.php";
if (isset($_POST["title"])) {
$query = "INSERT INTO events (title, event_date) VALUES (:title, :event_date)";
$statement = $connect->prepare($query);
$statement->execute(array(
':title' => $_POST['title'],
':event_date' => $_POST['start']
));
}
PHP Code to fetch single event
Create getEventDetailSingle.php and past the below code
<?php
require_once "db.php";
if (isset($_GET['event_id'])) {
$event_id = $_GET['event_id'];
// Fetch event details from the database
$query = "SELECT * FROM events WHERE id = :event_id";
$statement = $connect->prepare($query);
$statement->bindParam(':event_id', $event_id, PDO::PARAM_INT);
$statement->execute();
$event = $statement->fetch(PDO::FETCH_ASSOC);
if ($event) {
// Display event details and update form
echo "<input type='hidden' id='event_id' value='{$event_id}'>";
echo "Event Title: <input type='text' id='editTitle' value='{$event['title']}' class='form-control'><br>";
echo "Start Date: <input type='date' id='editStartDate' value='{$event['event_date']}' class='form-control'><br>";
} else {
echo "Event not found.";
}
}
PHP Code to update a single event
Create updateEvent.php and past the below code
<?php
require_once "db.php";
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$event_id = $_POST['event_id'];
$updatedTitle = $_POST['updatedTitle'];
$updatedStartDate = $_POST['updatedStartDate'];
// Update the event in the database
$query = "UPDATE events SET title = :updatedTitle, event_date = :updatedStartDate WHERE id = :event_id";
$statement = $connect->prepare($query);
$statement->bindParam(':event_id', $event_id, PDO::PARAM_INT);
$statement->bindParam(':updatedTitle', $updatedTitle, PDO::PARAM_STR);
$statement->bindParam(':updatedStartDate', $updatedStartDate, PDO::PARAM_STR);
if ($statement->execute()) {
echo "Event updated successfully.";
} else {
echo "Failed to update event.";
}
}
PHP Code to delete single event
Create deleteEvent.php and past the below code
<?php
require_once "db.php";
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['event_id'])) {
$event_id = $_POST['event_id'];
// Perform the necessary database query to delete the event
// For example: DELETE FROM events WHERE id = $event_id
// Replace the following line with your actual database query
$query = "DELETE FROM events WHERE id = $event_id";
$statement = $connect->prepare($query);
if ($statement->execute()) {
echo "deleted";
} else {
echo "Failed to delete event.";
}
}