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

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. Buy a license.

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

javascript-event-calendar-widget-php-week.png

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

javascript-event-calendar-widget-php-day.png

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

javascript-event-calendar-widget-php-move.png

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

javascript-event-calendar-widget-php-resize.png

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

javascript-event-calendar-widget-php-create.png

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

javascript-event-calendar-widget-php-lunch-break.png

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
);