Features

This tutorial uses the event calendarmonthly calendar, and date navigator controls from DayPilot Pro package to build a simple HTML5/JavaScript calendar application with day, week, and month views that can be switched by the user.

  • day view
  • week view
  • month view
  • date navigator
  • drag and drop event creating, moving and resizing enabled
  • loading events using built-in .event.load()
  • PHP backend
  • SQLite sample database

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.

Daily Calendar

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

The day view is built using DayPilot.Calendar class with viewType set to "Day".

HTML5

<div id="dpDay"></div>

JavaScript

<script type="text/javascript">

  var day = new DayPilot.Calendar("dpDay");
  day.viewType = "Day";
  day.init();

</script>

Weekly Calendar

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

The week view is built using DayPilot.Calendar class with viewType set to "Day".

HTML5

<div id="dpWeek"></div>

JavaScript

<script type="text/javascript">

  var day = new DayPilot.Calendar("dpWeek");
  day.viewType = "Week";
  day.init();

</script>

Monthly Calendar

html5-event-calendar-javascript-php-month.png

The month view is built using DayPilot.Month class.

HTML5

<div id="dpMonth"></div>

JavaScript

<script type="text/javascript">

  var day = new DayPilot.Month("dpMonth");
  day.init();

</script>

Loading Calendar Event Data

The day/week and month calendar controls support a shortcut method for loading events:

dp.events.load("backend_events.php");

You can use this method to load events from a remote data source. It expects a JSON array with calendar event data as a response.

PHP ("backend_events.php")

<?php
require_once '_db.php';

$json = file_get_contents('php://input');  // .events.load() passes start and end using JSON: {"start": "2015-06-15T09:00:00", "end": "2015-06-15T13:00:00"}
$params = json_decode($json);
    
$stmt = $db->prepare('SELECT * FROM events WHERE NOT ((end <= :start) OR (start >= :end))');

$stmt->bindParam(':start', $params->start);
$stmt->bindParam(':end', $params->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['start'];
  $e->end = $row['end'];
  $events[] = $e;
}

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

?>

The sample SQLite database uses a simple schema with just one table called "events":

CREATE TABLE events (
    id       INTEGER      PRIMARY KEY,
    name     TEXT,
    start    DATETIME,
    [end]    DATETIME,
    resource VARCHAR (30) 
);

How Does .events.load() Work

This dp.events.load() method is a shortcut method that updates the calendar data using an AJAX call

The calendar event data is stored in dp.events.list array. Example:

dp.events.list = [
  { id: "1" start: "2015-06-01T09:00:00", end: "2015-06-01T13:00:00", text: "Event 1" }
];

You can load the data during the initial page load:

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

<script type="text/javascript">

  var dp = new DayPilot.Calendar("dp");
  dp.viewType = "Week";
  dp.events.list = [
  { id: "1" start: "2015-06-01T09:00:00", end: "2015-06-01T13:00:00", text: "Event 1" }
]; dp.init(); </script>

You can also load the data using a separate AJAX call (this example uses jQuery $.post):

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

<script type="text/javascript">

  var dp = new DayPilot.Calendar("dp");
  dp.viewType = "Week";
  dp.init();

  $.post(
    "backend_events.php",
    {
      start: dp.visibleStart().toString(),
      end: dp.visibleEnd().toString()
    },
    function(data) {
      dp.events.list = data;
      dp.update();
    }
   );

</script>

The jQuery $.post call can be replaced with dp.events.load():

  1. It sends a POST AJAX request that loads the calendar data in JSON format. It sends the .visibleStart() date as "start" POST parameters and .visibleEnd() date as "end" POST parameter.
  2. It assigns the data to dp.events.list
  3. It updates the calendar using dp.update()

JavaScript

dp.events.load("backend_events.php");

Calendar Drag and Drop Support - Adding Event Handlers

We will add four events handlers:

  • onEventMoved
  • onEventResized
  • onTimeRangeSelected
  • onEventClick

The syntax of all event handlers is the same in the DayPilot.Calendar and DayPilot.Month. We can use a help method that will add the event handlers to all views.

JavaScript

function addEventHandlers(dp) {
  dp.onEventMoved = function (args) {
      $.post("backend_move.php", 
              {
                  id: args.e.id(),
                  newStart: args.newStart.toString(),
                  newEnd: args.newEnd.toString()
              }, 
              function() {
                  console.log("Moved.");
              });
  };

  dp.onEventResized = function (args) {
      $.post("backend_resize.php", 
              {
                  id: args.e.id(),
                  newStart: args.newStart.toString(),
                  newEnd: args.newEnd.toString()
              }, 
              function() {
                  console.log("Resized.");
              });
  };

  // event creating
  dp.onTimeRangeSelected = function (args) {
      var name = prompt("New event name:", "Event");
      dp.clearSelection();
      if (!name) return;
      var e = new DayPilot.Event({
          start: args.start,
          end: args.end,
          id: DayPilot.guid(),
          resource: args.resource,
          text: name
      });
      dp.events.add(e);

      $.post("backend_create.php", 
              {
                  start: args.start.toString(),
                  end: args.end.toString(),
                  name: name
              }, 
              function() {
                  console.log("Created.");
              });

  };

  dp.onEventClick = function(args) {
      alert("clicked: " + args.e.id());
  };
}

Date Navigator

html5-event-calendar-javascript-php-date-navigator.png

The last UI control is the date navigator that will let the users switch the visible date.

HTML5

<div id="nav"></div>

JavaScript

<script type="text/javascript">
  var nav = new DayPilot.Navigator("nav");
  nav.showMonths = 3;
  nav.skipMonths = 3;
  nav.init();
</script>

Switching the Day/Week/Month Views

html5-event-calendar-day-week-month-switching.png

Now it's time to assemble all controls and views into a complex calendar view.

We have the following components:

Components:

  • view triggers (simple <a> links with "Day", "Week", and "Month" text)
  • day, week, and month views (DayPilot.Calendar, DayPilot.Month objects)
  • navigator (DayPilot.Navigator)

We will use the DayPilot.Switcher helper to bind all calendar components together.

HTML5

<div style="float:left; width: 160px;">
    <div id="nav"></div>
</div>
<div style="margin-left: 160px;">
    <div class="space buttons">
        <a id="buttonDay" href="#">Day</a>
        <a id="buttonWeek" href="#">Week</a>
        <a id="buttonMonth" href="#">Month</a>
    </div>
    <div id="dpDay"></div>
    <div id="dpWeek"></div>
    <div id="dpMonth"></div>
</div>

JavaScript

<script type="text/javascript">

  // initialize the date navigator
  var nav = new DayPilot.Navigator("nav");
  nav.showMonths = 3;
  nav.skipMonths = 3;
  nav.init();
                 
  // initialize the day view
  var day = new DayPilot.Calendar("dpDay");
  day.viewType = "Day";
  addEventHandlers(day);
  day.init();

  // initialize the week view
  var week = new DayPilot.Calendar("dpWeek");
  week.viewType = "Week";
  addEventHandlers(week);
  week.init();

  // initialize the month view
  var month = new DayPilot.Month("dpMonth");
  addEventHandlers(month);
  month.init();

  // ...

  var switcher = new DayPilot.Switcher({
      triggers: [
          {id: "buttonDay", view: day },    // link buttonDay to day view
          {id: "buttonWeek", view: week},   // link buttonWeek to week view
          {id: "buttonMonth", view: month}  // link buttonMonth to month view
      ],
      navigator: nav,
      selectedClass: "selected-button",  // add this class to the selected trigger
      onChanged: function(args) {
          switcher.events.load("backend_events.php");   // action to be performed when the view or date changes - reload the events for the current view
      }
  });
  
  switcher.select("buttonWeek");

</script>