This tutorial shows how to create an AJAX monthly event calendar in JavaScript using the monthly HTML5 event calendar from DayPilot Pro for JavaScript package. It includes a sample PHP project with an SQLite database. The event calendar supports common drag and drop operations (event creating, moving and resizing) and is styled using a CSS theme.

Requirements

  • PHP 5

See Also

Features

  • Uses DayPilot monthly event calendar JavaScript component

  • Highlighting weekends

  • Full CSS styling

  • CSS theme support

  • Loading events from the server using HTTP calls

  • Drag and drop event creating

  • Drag and drop event moving

  • Drag and drop event resizing

  • Sample PHP server backend

  • Sample SQLite database

  • HTML5

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.

Setup

Include the following files from the DayPilot Pro for JavaScript package:

  • Include daypilot-all.min.js

  • The default CSS theme is built in so you don't need to include a separate stylesheet file.

<script src="js/daypilot/daypilot-all.min.js" type="text/javascript"></script>

Placeholder Div

The monthly event calendar requires a placeholder div on the page.

<div id="dp"></div>

JavaScript Initialization Code

The monthly event calendar widget must be created using DayPilot.Month class.

<script type="text/javascript">
  const dp = DayPilot.Month("dp");
  dp.init();
</script>

This will create the monthly calendar using the placeholder div.

CSS Theme

There are several CSS themes included in DayPilot Pro for JavaScript:

We will use the default CSS theme. You can switch to a custom CSS theme using the theme property:

<script type="text/javascript">
  const dp = DayPilot.Month("dp");
  dp.theme = "month_white";
  dp.init();
</script>

You can also design your own CSS theme using the online theme designer.

Loading Events

The monthly calendar events can be loaded using events.add() method.

A sample loadEvents() method that loads the data using an HTTP call:

<script type="text/javascript">
  const dp = DayPilot.Month("dp");
  dp.init();

  loadEvents();

  async function loadEvents() {
    const {data: events} = await DayPilot.Http.get("backend_events.php");
    dp.updat({events});
  }
</script>

backend_events.php

<?php
require_once '_db.php';
    
$result = $db->query('SELECT * FROM events');

class Event {}
$events = array();

foreach($result as $row) {
  $e = new Event();
  $e->id = $row['id'];
  $e->text = $row['name'];
  $e->start = $row['start'];
  $e->end = $row['end'];
  $events[] = $e;
}

header('Content-Type: application/json');
echo json_encode($events);

Highlighting Weekends

You can customize the day cells of the monthly event calendar using onBeforeCellRender event.

<script>
  const dp = DayPilot.Month("dp");
  dp.onBeforeCellRender = (args) => {
      if (args.cell.start.getDayOfWeek() === 6 || args.cell.start.getDayOfWeek() === 0) {
          args.cell.backColor = "#eee";
      }
  };
  dp.init();
</script>

Moving Calendar Events using Drag and Drop

Drag and drop moving is enabled for the calendar events by default. The drag and drop event moving invokes two events:

  • onEventMove (after the event is dropped at the target location but before the event is actually moved; it is possible to cancel the move by calling args.preventDefault() here)

  • onEventMoved (after the update is finished)

We will use onEventMoved to notify the PHP server backend about the update.

After the server response is received we will display a message to the user using message() method.

<script type="text/javascript">
  const dp = DayPilot.Month("dp");
  dp.onEventMoved = async (args) => {
    const data = {
      id: args.e.id(),
      start: args.newStart.toString(),
      end: args.newEnd.toString()
    };
    const {data: result} = await DayPilot.Http.post("backend_move.php", data);
    dp.message("Moved: " + result.message);
  };
  dp.init();
</script>

backend_move.php

<?php
require_once '_db.php';

$json = file_get_contents('php://input');
$params = json_decode($json);

$stmt = $db->prepare("UPDATE events SET start = :start, end = :end WHERE id = :id");
$stmt->bindParam(':start', $params->start);
$stmt->bindParam(':end', $params->end);
$stmt->bindParam(':id', $params->id);
$stmt->execute();

class Result {}

$response = new Result();
$response->result = 'OK';
$response->message = 'Update successful';

header('Content-Type: application/json');
echo json_encode($response);

Resizing Calendar Events using Drag and Drop

The monthly calendar event resizing works the same way as moving.

<script type="text/javascript">
  const dp = DayPilot.Month("dp");
  dp.onEventResized = async (args) => {
    const data = {
      id: args.e.id(),
      start: args.newStart.toString(),
      end: args.newEnd.toString()
    };
    const {data: result} = await DayPilot.Http.post("backend_move.php", data);
    dp.message("Resized: " + result.message);
  };
  dp.init();
</script>

backend_resize.php

<?php
require_once '_db.php';

$json = file_get_contents('php://input');
$params = json_decode($json);

$stmt = $db->prepare("UPDATE events SET start = :start, end = :end WHERE id = :id");
$stmt->bindParam(':start', $params->start);
$stmt->bindParam(':end', $params->end);
$stmt->bindParam(':id', $params->id);
$stmt->execute();

class Result {}

$response = new Result();
$response->result = 'OK';
$response->message = 'Update successful';

header('Content-Type: application/json');
echo json_encode($response);

Adding Calendar Events using Drag and Drop

It is possible to create new events by selecting a time range (by dragging a mouse). This action will fire onTimeRangeSelect and onTimeRangeSelected events.

We will use onTimeRangeSelected to display a simple modal dialog and ask for the name of the new calendar event.

<script type="text/javascript">
  const dp = DayPilot.Month("dp");

  dp.onTimeRangeSelected = async (args) => {

    const modal = await DayPilot.Modal.prompt("New event name:", "Event");

    dp.clearSelection();
    if (modal.canceled) {
      return;
    }

    const data = {
      start: args.start.toString(),
      end: args.end.toString(),
      text: modal.result
    };
    const {data: result} = await DayPilot.Http.post("backend_create.php", data);
    var e = {
      start: args.start,
      end: args.end,
      id: result.id,
      text: modal.result
    };
    dp.events.add(e);
    dp.message(result.message);
  };

  dp.init();
</script>

backend_create.php

<?php
require_once '_db.php';

$json = file_get_contents('php://input');
$params = json_decode($json);

$stmt = $db->prepare("INSERT INTO events (name, start, 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->message = 'Created with id: '.$db->lastInsertId();
$response->id = $db->lastInsertId();

header('Content-Type: application/json');
echo json_encode($response);