This tutorial shows how to create an interactive event calendar in JavaScript using the event calendar widget from DayPilot Pro for JavaScript package. It includes a sample PHP project with an SQLite database. The event calendar supports drag and drop operations (event creating, moving and resizing), switching daily and weekly view and is styled using a CSS theme.
Included
Requirements
PHP 5+
See Also
Tutorial: AJAX Scheduler for JavaScript/PHP (displaying events for multiple resources side-by-side)
Features
JavaScript event calendar widget
Switching day and week view
Drag and drop support (event creating, moving, resizing)
PHP backend
Sample database (SQLite)
Full CSS styling (themes)
HTML5 support
License
Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript.
Event Calendar Setup
Include daypilot-all.min.js
script:
<script src="js/daypilot/daypilot-all.min.js"></script>
Add a <div>
element that will serve as a placeholder for the event calendar widget:
<div id="dp"></div>
Add the event calendar initialization code:
var dp = new DayPilot.Calendar("dp");
dp.init();
This will display the event calendar with default configuration. In the default configuration, the calendar displays a day view.
CSS Theme
The calendar widget includes a built-in CSS theme. You can also create your own theme using the online theme designer.
Visible Date
Set the visible date using startDate property:
dp.startDate = new DayPilot.Date("2020-09-01"); // or just dp.startDate = "2020-09-01";
Load Events
We will load the events after the initialization is complete using events.load() method:
function loadEvents() {
dp.events.load("backend_events.php");
}
Source of backend_events.php
file that returns the event data in JSON format:
<?php
require_once '_db.php';
$stmt = $db->prepare("SELECT * FROM events WHERE NOT (event_end <= :start OR event_start >= :end)");
$stmt->bindParam(':start', $_GET['start']);
$stmt->bindParam(':end', $_GET['end']);
$stmt->execute();
$result = $stmt->fetchAll();
class Event {}
$events = array();
foreach($result as $row) {
$e = new Event();
$e->id = $row['id'];
$e->text = $row['name'];
$e->start = $row['event_start'];
$e->end = $row['event_end'];
$events[] = $e;
}
echo json_encode($events);
Weekly Event Calendar View
You can switch the event calendar to week view using viewType property:
dp.update({viewType: "Week"});
After switching the calendar view, we need to load the event data for the new date range:
elements.week.addEventListener("click", function() {
dp.update({viewType: "Week"});
dp.events.load("backend_events.php");
});
Daily Event Calendar View
You can switch the event calendar to day view by setting viewType
property to "Day"
.
elements.day.addEventListener("click", function() {
dp.update({viewType: "Day"});
dp.events.load("backend_events.php");
});
Drag and Drop Event Moving
Drag and drop event moving is enabled by default. Weed need to add a custom handler that will save the changes in a database on the server side using PHP.
dp.onEventMoved = function (args) {
DayPilot.Http.ajax({
url: "backend_move.php",
data: args,
success: function(ajax) {
var response = ajax.data;
dp.message("Moved: " + response.message);
}
});
};
The backend_move.php
script saves the changes in the database;
<?php
require_once '_db.php';
$json = file_get_contents('php://input');
$params = json_decode($json);
$stmt = $db->prepare("UPDATE events SET event_start = :start, event_end = :end WHERE id = :id");
$stmt->bindParam(':id', $params->e->id);
$stmt->bindParam(':start', $params->newStart);
$stmt->bindParam(':end', $params->newEnd);
$stmt->execute();
class Result {}
$response = new Result();
$response->result = 'OK';
$response->message = 'Update successful';
echo json_encode($response);
Drag and Drop Event Resizing
The calendar event resizing handler is very similar:
dp.onEventResized = function (args) {
DayPilot.Http.ajax({
url: "backend_move.php",
data: args,
success: function(ajax) {
var response = ajax.data;
dp.message("Resized: " + response.message);
}
});
};
Drag and Drop Event Creating
dp.onTimeRangeSelected = function (args) {
DayPilot.Modal.prompt("New event name:", "Event").then(function(modal) {
dp.clearSelection();
if (modal.canceled) {
return;
}
var name = modal.result;
var params = {
start: args.start,
end: args.end,
text: name
};
DayPilot.Http.ajax({
url: "backend_create.php",
data: params,
success: function(ajax) {
params.id = ajax.data.id;
dp.events.add(params);
var response = ajax.data;
dp.message("Created: " + response.message);
}
});
});
};
The backend_create.php
PHP script creates a new record in the database and returns the ID.
<?php
require_once '_db.php';
$json = file_get_contents('php://input');
$params = json_decode($json);
$stmt = $db->prepare("INSERT INTO events (name, event_start, event_end) VALUES (:name, :start, :end)");
$stmt->bindParam(':start', $params->start);
$stmt->bindParam(':end', $params->end);
$stmt->bindParam(':name', $params->text);
$stmt->execute();
class Result {}
$response = new Result();
$response->result = 'OK';
$response->id = $db->lastInsertId();
$response->message = 'Created with id: '.$db->lastInsertId();
echo json_encode($response);
Highlighting Lunch Break
You can highlight selected grid cells using onBeforeCellRender
event handler (see Calendar cell customization):
dp.onBeforeCellRender = function(args) {
if (args.cell.start.getHours() === 13) {
args.cell.backColor = "#eee";
}
};
Database Schema
This project uses a simple SQLite database schema:
CREATE TABLE events (
id INTEGER PRIMARY KEY,
name TEXT,
event_start DATETIME,
event_end DATETIME
);