Click here to Skip to main content
15,353,676 members
Articles / Web Development / HTML
Article
Posted 24 Feb 2014

Stats

682.1K views
2.6K downloads
393 bookmarked

HTML5 Event Calendar/Scheduler

Rate me:
Please Sign up or sign in to vote.
4.93/5 (133 votes)
11 Apr 2022Apache7 min read
Weekly HTML5 event calendar with CSS themes, drag and drop support, date navigator. PHP and ASP.NET Core REST API backends.
In this article, we will build a simple HTML5 event calendar web application. The client-side (HTML5/JavaScript) part is universal. We will use sample PHP and ASP.NET Core backends. This article will look at: changing the calendar date using a date picker (on the left side), drag and drop event creating, moving and resizing, changing the look in a single click using a CSS theme, PHP backend, and ASP.NET Core backend (REST API).

HTML5 Event Calendar/Scheduler (Open-Source)

In this article, we will build a simple HTML5 event calendar web application. The client-side (HTML5/JavaScript) part is universal. We will use sample PHP and ASP.NET Core backends.

Features:

  • Weekly HTML5 event calendar/scheduler
  • Changing the calendar using a date navigator (on the left side)
  • Drag and drop event creating, moving and resizing
  • Changing the look in a single click using a CSS theme
  • PHP REST backend
  • ASP.NET Core REST backend (.NET 6, Entity Framework)

We will use DayPilot Lite for JavaScript [javascript.daypilot.org] to build the event calendar. DayPilot Lite for JavaScript is open-source - available under Apache License 2.0.

New Version with Support for Angular, React, and Vue

Version 2022.1 of DayPilot Lite includes support for Angular, React, and Vue frameworks. See the following tutorials for a quick introduction and a sample project download:

Scheduler CSS Themes

DayPilot Lite for JavaScript comes with several pre-built CSS themes.

You can create your own theme using the online CSS theme designer [themes.daypilot.org].

Default CSS Theme

HTML5 Event Calendar - Default CSS Theme

Green CSS Theme

HTML5 Event Calendar - Green CSS Theme

Google-Like CSS Theme

HTML5 Event Calendar - Google-Like CSS Theme

Traditional CSS Theme

HTML5 Scheduler - Traditional CSS Theme

Transparent CSS Theme

HTML5 Scheduler - Transparent CSS Theme

White CSS Theme

HTML5 Scheduler - White CSS Theme

Step 1: Event Calendar JavaScript Library

Include daypilot-all.min.js. No other dependencies are required for the basic look (the default CSS theme is embedded).

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

Step 2: Event Calendar Placeholder

Add a placeholder <div> to the HTML5 page:

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

Step 3: Initialize the Scheduler

Initialize the scheduler using Daypilot.Calendar class:

HTML
<script type="text/javascript">
  const dp = new DayPilot.Calendar("dp", {
    viewType: "Week"
  });
  dp.init();
</script>

These simple steps will render an empty scheduler:

HTML5 Event Calendar (Empty)

Step 4: Load Data

We will load the data to the event calendar using a simple HTTP call:

JavaScript
async function loadEvents() {
  const start = dp.visibleStart();
  const end = dp.visibleEnd();
  const {data} = await DayPilot.Http.get(`backend_events.php?start=${start}&end=${end)`);    // in .NET, use "/api/CalendarEvents?start=${start}&end=${end)"
  dp.update({
    events: data
  });
}

Since version 2018.2.232, you can also use a built-in shortcut method to load events:

JavaScript
function loadEvents() {
  dp.events.load("backend_events.php"); // in .NET, use "api/CalendarEvents"
}

You can detect the currently-visible date range using visibleStart() and visibleEnd() methods. The events.load() method adds the start and end to the URL query string automatically.

The backend_event.php endpoint returns the calendar event data in the following format:

JavaScript
[
  {
    "id":"1",
    "text":"Calendar Event 1",
    "start":"2022-02-25T10:30:00",
    "end":"2022-02-25T16:30:00"
  },
  {
    "id":"2",
    "text":"Calendar Event 2",
    "start":"2022-02-24T09:00:00",
    "end":"2022-02-24T14:30:00"
  },
  {
    "id":"3",
    "text":"Calendar Event 3",
    "start":"2022-02-27T12:00:00",
    "end":"2022-02-27T16:00:00"
  }
]

PHP backend (backend_events.php):

PHP
<?php
require_once '_db.php';
    
$stmt = $db->prepare('SELECT * FROM events WHERE NOT ((end <= :start) OR (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['start'];
  $e->end = $row['end'];
  $events[] = $e;
}

echo json_encode($events);

?>

ASP.NET Core backend (CalendarEventsController.cs):

C#
// GET: api/CalendarEvents
[HttpGet]
public async Task<ActionResult<IEnumerable<CalendarEvent>>> 
       GetEvents([FromQuery] DateTime start, [FromQuery] DateTime end)
{
    return await _context.Events
        .Where(e => !((e.End <= start) || (e.Start >= end)))
        .ToListAsync();
} 

Read more about loading the calendar event data [doc.daypilot.org].

Step 5: Event Moving

HTML5 Event Calendar - Drag and Drop Moving

The drag and drop user actions (selecting a time range, event moving, event resizing) are enabled by default in the scheduler.

We just need to add custom handler to submit the changes to the server side using an AJAX call.

JavaScript event handler (for PHP):

JavaScript
const dp = new DayPilot.Calendar("dp", {
  // ...
  onEventMoved: async (args) => {
    const data = {
      id: args.e.id(),
      newStart: args.newStart,
      newEnd: args.newEnd,
    };
    await DayPilot.Http.post(`backend_move.php`, data);
    console.log("The calendar event was moved.");
  }
});

PHP backend (backend_move.php):

PHP
<?php

require_once '_db.php';

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

$insert = "UPDATE events SET start = :start, end = :end WHERE id = :id";

$stmt = $db->prepare($insert);

$stmt->bindParam(':start', $params->newStart);
$stmt->bindParam(':end', $params->newEnd);
$stmt->bindParam(':id', $params->id);

$stmt->execute();

class Result {}

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

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

JavaScript event handler (for ASP.NET Core):

JavaScript
const dp = new DayPilot.Calendar("dp", {
  // ...
  onEventMoved: async (args) => {
    const id = args.e.id();
    const data = {
        id: args.e.id(),
        start: args.newStart,
        end: args.newEnd,
        text: args.e.text()
    };
    await DayPilot.Http.put(`/api/CalendarEvents/${id}`, data);
    console.log("The calendar event was moved.");
  }
});

ASP.NET Core backend (CalendarEventsController.cs):

C#
// PUT: api/CalendarEvents/5
[HttpPut("{id}")]
public async Task<IActionResult> PutCalendarEvent(int id, CalendarEvent calendarEvent)
{
    if (id != calendarEvent.Id)
    {
        return BadRequest();
    }

    _context.Entry(calendarEvent).State = EntityState.Modified;

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!CalendarEventExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }

    return NoContent();
} 

Read more about drag and drop event moving [doc.daypilot.org].

Step 6: Event Editing

Image 10

You can use DayPilot Modal dialog to edit the events details. DayPilot Modal is an open-source library for building modal forms from code (online Modal Dialog Builder application for visual modal dialog design is also available).

First, we add an onEventClick event handler that is fired when users click an existing event.

Our modal dialog will have just a single form field (text value called "Name"):

JavaScript
const form = [
  {name: "Name", id: "text"}
];

Now we can open the modal dialog using DayPilot.Modal.form() method. The second parameter specifies the source data object. The data object will be used to fill the initial values (the id value of the form item specifies the property/field of the data object).

The DayPilot.Modal.form() method returns a promise. That means we can use the await syntax to wait for the result and simplify the code:

JavaScript
const modal = await DayPilot.Modal.form(form, args.e.data);
if (modal.canceled) {
  return;
}

The result is available as modal.result object. It's a copy of the original object, with the updated values applied.

This is our onEventClick event handler:

JavaScript
const dp = new DayPilot.Calendar("dp", {
  // ...
  onEventClick: async (args) => {
    const form = [
      {name: "Name", id: "text"}
    ];

    const modal = await DayPilot.Modal.form(form, args.e.data);
    if (modal.canceled) {
      return;
    }

    // PHP

    const data = {
      id: args.e.id(),
      text: modal.result.text
    };
    await DayPilot.Http.post(`backend_update.php`, data);
    
    // .NET 6
    /*

    const id = args.e.id();
    const data = {
        id: args.e.id(),
        start: args.e.start(),
        end: args.e.end(),
        text: modal.result.text
    };
    await DayPilot.Http.put(`/api/CalendarEvents/${id}`, data);

    */

    dp.events.update({
      ...args.e.data,
      text: modal.result.text
    });
    console.log("The calendar event was updated.");

  }
});

PHP backend (backend_update.php)

PHP
<?php
require_once '_db.php';

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

$insert = "UPDATE events SET name = :text WHERE id = :id";

$stmt = $db->prepare($insert);

$stmt->bindParam(':text', $params->text);

$stmt->execute();

class Result {}

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

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

Step 7: Apply the CSS Theme

HTML5 Event Calendar - CSS Theme

If you want to use a custom CSS theme, you need to include the stylesheet:

HTML
<link type="text/css" rel="stylesheet" href="themes/calendar_transparent.css" /> 

And set the theme property during initialization:

HTML
<script type="text/javascript">
  const dp = new DayPilot.Calendar("dp", {
    viewType: "Week",
    theme: "calendar_transparent"
  });
  dp.init();
</script> 

You can choose one of the included CSS themes or you can create your own using the online CSS theme designer.

Monthly Event Calendar

HTML5 Monthly Event Calendar

DayPilot also includes a monthly event calendar view. The API of the monthly view control uses the same design as the daily/weekly calendar:

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

<script type="text/javascript">
  const dp = new DayPilot.Month("dp");
  dp.startDate = "2022-01-01";
  dp.init();
</script>

Event Calendar Localization

HTML5 Event Calendar Localization

You can switch the event calendar locale easily using .locale property:

HTML
<script type="text/javascript">
  const dp = new DayPilot.Calendar("dp");
  dp.locale = "de-de";
  dp.init();
</script>  

The calendar includes built-in support for many following locales [api.daypilot.org].

You can also create and register your own locale:

JavaScript
DayPilot.Locale.register(
  new DayPilot.Locale('en-us', 
  {
    'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
    'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],
    'monthNames':['January','February','March','April','May',
                  'June','July','August','September','October','November','December'],
    'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun',
                       'Jul','Aug','Sep','Oct','Nov','Dec'],
    'timePattern':'h:mm tt',
    'datePattern':'M/d/yyyy',
    'dateTimePattern':'M/d/yyyy h:mm tt',
    'timeFormat':'Clock12Hours',
    'weekStarts':0
  }
)); 

Changing the Scheduler Date

Image 14

You can use the DayPilot.Navigator control (on the left side in the screenshot above) to change the scheduler dates (the visible week):

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

<script type="text/javascript">
  const nav = new DayPilot.Navigator("nav", {
    showMonths: 3,
    skipMonths: 3,
    selectMode: "Week",
    onTimeRangeSelected: args => {
      dp.update({startDate: args.day});
      app.loadEvents();
    }
  });
  nav.init();
</script>

Duration Bar

HTML5 event calendar with duration bar support

Version 1.1 of the DayPilot Lite HTML5 event calendar supports a duration bar (an indicator of real calendar event duration on the left side of the event). It is enabled by default and you can style it using the CSS theme.

Event Customization (HTML, CSS)

HTML5 Event Calendar Customization

Since version 1.3 SP3, DayPilot Lite supports event customization using onBeforeEventRender event handler:

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

<script type="text/javascript">

    const dp = new DayPilot.Calendar("dp");

    // view
    dp.startDate = "2016-06-06";
    dp.viewType = "Week";
    dp.durationBarVisible = false;

    dp.events.list = [
        {
            "start": "2016-06-07T10:00:00",
            "end": "2016-06-07T13:00:00",
            "id": "29b7a553-d44f-8f2c-11e1-a7d5f62eb123",
            "text": "Event 3",
            "backColor": "#B6D7A8",
            "borderColor": "#6AA84F"
        },
        {
            "start": "2016-06-07T14:00:00",
            "end": "2016-06-07T17:00:00",
            "id": "ff968cfb-eba1-8dc1-7396-7f0d4f465c8a",
            "text": "Event 4",
            "backColor": "#EA9999",
            "borderColor": "#CC0000",
            "tags": {
                "type": "important"
            }
        }
    ];

    dp.onBeforeEventRender = args => {
        if (args.data.tags && args.data.tags.type === "important"){
            args.data.html = "<b>Important Event</b><br>" + args.data.text;
            args.data.fontColor = "#fff";
            args.data.backColor = "#E06666";
        }
    };

    dp.init();


</script>

You can use it to customize the following properties:

  • backColor
  • barBackColor
  • barColor
  • barHidden
  • borderColor
  • cssClass
  • fontColor
  • html
  • toolTip

Demo:

Monthly Calendar Event Customization

HTML5 Monthly Event Calendar Customization

Event customization support was added to the monthly calendar control in DayPilot Lite for JavaScript 1.3 SP4.

DayPilot Month supports customization of the following event properties:

  • backColor
  • borderColor
  • cssClass
  • fontColor
  • html
  • toolTip

Demo:

Example:

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

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

    // ...
    
    dp.events.list = [
        {
            "start": "2021-03-03T00:00:00",
            "end": "2021-03-03T12:00:00",
            "id": "5a8376d2-8e3d-9739-d5d9-c1fba6ec02f9",
            "text": "Event 3"
        },
        {
            "start": "2021-02-25T00:00:00",
            "end": "2021-02-27T12:00:00",
            "id": "1fa34626-113a-ccb7-6a38-308e6cbe571e",
            "text": "Event 4",
            "tags": {
                "type": "important"
            }
        },
        // ...
    ];

    dp.onBeforeEventRender = args => {
        var type = args.data.tags && args.data.tags.type;
        switch (type) {
            case "important":
                args.data.fontColor = "#fff";
                args.data.backColor = "#E06666";
                args.data.borderColor = "#E06666";
                break;
            // ...
        }
    };

    dp.init();

</script>

Angular Event Calendar/Scheduler

Since version 2021.4.341, DayPilot Lite includes an Angular Event Calendar component which supports day/week/month views:

See Also

History

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

Share

About the Author

Dan Letecky
Czech Republic Czech Republic
My open-source event calendar/scheduling web UI components:

DayPilot for JavaScript, Angular, React and Vue
DayPilot for ASP.NET

Comments and Discussions

 
QuestionLocalization and header format Pin
Member 1047687316-Oct-15 7:28
MemberMember 1047687316-Oct-15 7:28 
AnswerRe: Localization and header format Pin
Dan Letecky2-Nov-15 4:56
MemberDan Letecky2-Nov-15 4:56 
QuestionMy vote of 5 Pin
Gloold4-Oct-15 22:12
MemberGloold4-Oct-15 22:12 
AnswerRe: My vote of 5 Pin
Dan Letecky2-Nov-15 4:59
MemberDan Letecky2-Nov-15 4:59 
QuestionDayPilot Calendar cannot Update clientState If i Navigate... Pin
Victor Ebe21-May-15 6:12
MemberVictor Ebe21-May-15 6:12 
GeneralPHP Worked great! - 5 stars Pin
Jan Zumwalt4-Apr-15 7:13
MemberJan Zumwalt4-Apr-15 7:13 
GeneralRe: PHP Worked great! - 5 stars Pin
Dan Letecky6-Apr-15 3:27
MemberDan Letecky6-Apr-15 3:27 
Generalcomment Pin
boredkoala13-Jan-15 20:37
Memberboredkoala13-Jan-15 20:37 
GeneralRe: comment Pin
Dan Letecky14-Jan-15 0:50
MemberDan Letecky14-Jan-15 0:50 
BugI think I found a bug in your MVC version Pin
Hardy Wang8-Dec-14 7:38
MemberHardy Wang8-Dec-14 7:38 
GeneralRe: I think I found a bug in your MVC version Pin
Dan Letecky23-Mar-15 6:54
MemberDan Letecky23-Mar-15 6:54 
GeneralMy vote of 5 Pin
Sibeesh KV23-Sep-14 23:19
professionalSibeesh KV23-Sep-14 23:19 
GeneralRe: My vote of 5 Pin
Dan Letecky9-Nov-14 22:58
MemberDan Letecky9-Nov-14 22:58 
GeneralRe: My vote of 5 Pin
Sibeesh KV9-Nov-14 23:16
professionalSibeesh KV9-Nov-14 23:16 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun19-May-14 20:22
MemberHumayun Kabir Mamun19-May-14 20:22 
GeneralRe: My vote of 5 Pin
Dan Letecky19-May-14 20:43
MemberDan Letecky19-May-14 20:43 
GeneralMy vote of 5 Pin
JasonMacD1-Apr-14 7:52
MemberJasonMacD1-Apr-14 7:52 
GeneralRe: My vote of 5 Pin
Dan Letecky1-Apr-14 8:38
MemberDan Letecky1-Apr-14 8:38 
QuestionHow to set an upper limit of an event Pin
franva00823-Mar-14 5:04
Memberfranva00823-Mar-14 5:04 
AnswerRe: How to set an upper limit of an event Pin
Dan Letecky31-Mar-14 22:57
MemberDan Letecky31-Mar-14 22:57 
Questionpop-up modal does not show at the center of my screen Pin
franva00820-Mar-14 1:40
Memberfranva00820-Mar-14 1:40 
AnswerRe: pop-up model does not show at the center of my screen Pin
Dan Letecky20-Mar-14 2:13
MemberDan Letecky20-Mar-14 2:13 
GeneralRe: pop-up model does not show at the center of my screen Pin
franva00820-Mar-14 3:43
Memberfranva00820-Mar-14 3:43 
GeneralRe: pop-up model does not show at the center of my screen Pin
Dan Letecky20-Mar-14 4:10
MemberDan Letecky20-Mar-14 4:10 
GeneralRe: pop-up model does not show at the center of my screen Pin
franva00821-Mar-14 12:24
Memberfranva00821-Mar-14 12:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.