JavaScript 事件日历用于资源调度






4.95/5 (154投票s)
每周 HTML5 事件日历,支持 CSS 主题、拖放功能和日期导航器。后端为 PHP 和 ASP.NET Core REST API。
- 下载 PHP 示例项目 - 69 KB
- 下载 ASP.NET Core (.NET 8) 示例项目 - 80 KB
- 下载 DayPilot Lite for JavaScript 2024.3 事件日历
(开源) [javascript.daypilot.org] - 在线演示
[javascript.daypilot.org]
在本文中,我们将构建一个简单的 HTML5/JavaScript 事件日历 Web 应用程序。客户端部分是通用的。我们将使用示例 PHP 和 ASP.NET Core 后端。
特点
- 每周 HTML5 事件日历/调度器
- 资源调度器模式,将资源显示为列
- 通过日期导航器(左侧)更改日历
- 拖放事件创建、移动和调整大小
- 向事件添加图标和图像(状态、分配的资源、上下文菜单提示)
- 一键更改外观,使用 CSS 主题
- PHP REST 后端
- ASP.NET Core REST 后端 (.NET 8, Entity Framework)
我们将使用开源的 DayPilot Lite for JavaScript [javascript.daypilot.org] 来构建事件日历。DayPilot Lite for JavaScript 可在 Apache License 2.0 下获得。
新功能:日期选择器(导航器)响应式模式
版本 2024.3.547 中引入的新的 响应式模式 允许 日期选择器(导航器)填充可用宽度,而不是使用固定的日期单元格宽度。
新教程:React 日历(日/周/月视图)
《React 日/周/月视图日历(开源)》教程展示了如何在 React 中集成带日期选择器的日、周和月日历视图。
- 日/周/月按钮用于切换日历视图。
- “今天”按钮方便返回当前日期。
- 与日历视图和日/周/月按钮同步的日期选择器。
- 带源代码下载的 React 应用程序。
步骤 1:事件日历 JavaScript 库
包含 daypilot-all.min.js。对于基本外观,不需要其他依赖项(默认 CSS 主题已嵌入)。
<script src="js/daypilot/daypilot-all.min.js" type="text/javascript"></script>
步骤 2:事件日历占位符
在 HTML5 页面中添加一个 <div>
占位符。
<div id="dp"></div>
步骤 3:初始化调度器
使用 Daypilot.Calendar
类初始化调度器。
<script type="text/javascript">
const dp = new DayPilot.Calendar("dp", {
viewType: "Week"
});
dp.init();
</script>
这些简单的步骤将渲染一个空的调度器。
步骤 4:加载数据
我们将通过简单的 HTTP 调用加载数据到事件日历。
async function loadEvents() {
const start = dp.visibleStart();
const end = dp.visibleEnd();
// in .NET, use "/api/CalendarEvents?start=${start}&end=${end)"
const {data} = await DayPilot.Http.get(`backend_events.php?start=${start}&end=${end)`);
dp.update({
events: data
});
}
自版本 2018.2.232 以来,您还可以使用内置的快捷方式方法加载事件。
function loadEvents() {
// in .NET, use "api/CalendarEvents"
dp.events.load("backend_events.php");
}
您可以使用 visibleStart()
和 visibleEnd()
方法检测当前可见的日期范围。events.load()
方法会自动将开始和结束日期添加到 URL 查询字符串中。
backend_event.php 端点以以下格式返回日历事件数据:
[
{
"id":"1",
"text":"Calendar Event 1",
"start":"2023-02-25T10:30:00",
"end":"2023-02-25T16:30:00"
},
{
"id":"2",
"text":"Calendar Event 2",
"start":"2023-02-24T09:00:00",
"end":"2023-02-24T14:30:00"
},
{
"id":"3",
"text":"Calendar Event 3",
"start":"2023-02-27T12:00:00",
"end":"2023-02-27T16:00:00"
}
]
PHP 后端(backend_events.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 后端(CalendarEventsController.cs)
// 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();
}
了解有关加载日历事件数据 [doc.daypilot.org] 的更多信息。
步骤 5:事件移动
调度器中默认启用了拖放用户操作(选择时间范围、事件移动、事件调整大小)。
我们只需要添加一个自定义事件处理程序,通过 AJAX 调用将更改提交到服务器端。
JavaScript 事件处理程序(针对 PHP)
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_move.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 事件处理程序(针对 ASP.NET Core)
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 后端(CalendarEventsController.cs)
// 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();
}
了解有关拖放事件移动 [doc.daypilot.org] 的更多信息。
步骤 6:事件编辑
您可以使用 DayPilot Modal 对话框来编辑事件详细信息。DayPilot Modal 是一个开源库,用于通过代码构建模态表单(还有一个在线 模态对话框生成器 应用程序,用于可视化模态对话框设计)。
首先,我们添加一个 onEventClick
事件处理程序,当用户单击现有事件时会触发该处理程序。
我们的模态对话框将只有一个表单字段(文本值,称为“Name
”)。
const form = [
{name: "Name", id: "text"}
];
现在,我们可以使用 DayPilot.Modal.form() 方法打开模态对话框。第二个参数指定源数据对象。数据对象将用于填充初始值(表单项的 id
值指定数据对象的属性/字段)。
DayPilot.Modal.form()
方法返回一个 Promise。这意味着我们可以使用 await
语法等待结果并简化代码。
const modal = await DayPilot.Modal.form(form, args.e.data);
if (modal.canceled) {
return;
}
结果可作为 modal.result
对象获得。它是原始对象的副本,并应用了更新后的值。
这是我们的 onEventClick
事件处理程序。
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 7
/*
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_update.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);
步骤 7:应用 CSS 主题
如果要使用自定义 CSS 主题,则需要包含样式表。
<link type="text/css" rel="stylesheet" href="themes/calendar_transparent.css" />
并在初始化期间设置主题属性。
<script type="text/javascript">
const dp = new DayPilot.Calendar("dp", {
viewType: "Week",
theme: "calendar_transparent"
});
dp.init();
</script>
您可以选择其中一个包含的 CSS 主题,也可以使用在线 CSS 主题设计器 创建自己的主题。
带实时预览的配置器应用程序
现在,您可以使用在线 UI 生成器 应用程序轻松配置日/周/月日历组件。该应用程序允许您在实时 DayPilot 实例中预览配置更改,并生成一个带有预配置日历组件的新项目(支持 JavaScript/HTML、JavaScript/NPM、TypeScript、Angular、React 和 Vue 项目目标)。
调度器 CSS 主题
DayPilot Lite for JavaScript 附带了几个预构建的 CSS 主题。
您可以使用在线 CSS 主题设计器 [themes.daypilot.org] 创建自己的主题。
默认 CSS 主题
绿色 CSS 主题
传统 CSS 主题
透明 CSS 主题
白色 CSS 主题
月历事件日历
DayPilot 还包括一个 月历事件日历 视图。月视图控件的 API 与日/周日历的设计相同。
<div id="dp"></div>
<script type="text/javascript">
const dp = new DayPilot.Month("dp");
dp.startDate = "2023-01-01";
dp.init();
</script>
事件日历本地化
您可以使用 .locale
属性轻松切换事件日历的语言。
<script type="text/javascript">
const dp = new DayPilot.Calendar("dp");
dp.locale = "de-de";
dp.init();
</script>
该日历内置支持许多以下 语言区域 [api.daypilot.org]。
您还可以创建和注册自己的语言区域。
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
}
));
使用日期选择器更改调度器日期
您可以使用 DayPilot.Navigator
日期选择器控件(在上图的左侧)更改调度器日期(可见周)。
<div id="nav"></div>
<script type="text/javascript">
const datePicker = new DayPilot.Navigator("nav", {
showMonths: 3,
skipMonths: 3,
selectMode: "Week",
onTimeRangeSelected: args => {
dp.update({startDate: args.day});
app.loadEvents();
}
});
datePicker.init();
</script>
持续时间条
DayPilot Lite HTML5 事件日历的 1.1 版支持持续时间条(事件左侧的实际日历事件持续时间指示器)。默认启用,您可以使用 CSS 主题进行样式设置。
事件自定义(HTML、CSS)
自 1.3 SP3 版本以来,DayPilot Lite 支持使用 onBeforeEventRender
事件处理程序进行事件自定义。
<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>
您可以使用它来自定义以下属性:
backColor
barBackColor
barColor
barHidden
borderColor
cssClass
fontColor
html
toolTip
演示
- 事件自定义演示 [javascript.daypilot.org]
月历事件自定义
在 DayPilot Lite for JavaScript 1.3 SP4 中,月历控件增加了对事件自定义的支持。
DayPilot 月历支持以下事件属性的自定义:
backColor
borderColor
cssClass
fontColor
html
toolTip
演示
- 月历事件自定义演示 [javascript.daypilot.org]
示例
<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、React 和 Vue
DayPilot Lite 2022.1 版本包括对Angular、React 和 Vue 框架的支持。有关快速入门和示例项目下载,请参阅以下教程:
- Angular 日历:日/周/月视图(开源) [code.daypilot.org]
- React 周历教程(开源) [code.daypilot.org]
- Vue.js 周历教程(开源)[code.daypilot.org]
资源日历
自 2022.2 版本以来,DayPilot Lite 包括一个资源日历视图,该视图将资源显示为列。
此视图允许您为多个资源安排事件或进行预订,并并排显示它们。
快速示例
const calendar = new DayPilot.Calendar("calendar", {
viewType: "Resources",
columns: [
{ name: "Room 1", id: "R1" },
{ name: "Room 2", id: "R2" },
{ name: "Room 3", id: "R3" },
{ name: "Room 4", id: "R4" },
]
});
calendar.init();
在用于 JavaScript、Angular、React 和 Vue 的资源日历教程中了解更多信息。
图标和上下文菜单
自 2022.4 版本以来,日历组件支持事件上下文菜单和图标。
可以使用活动区域添加图标。活动区域是向事件添加元素的通用工具 - 您可以使用它们来添加图像、状态图标、操作按钮和拖动手柄。
示例
onBeforeEventRender: args => {
args.data.areas = [
{
top: 5,
right: 5,
width: 16,
height: 16,
symbol: "icons/daypilot.svg#minichevron-down-4",
fontColor: "#666",
visibility: "Hover",
action: "ContextMenu",
style: "background-color: #f9f9f9; border: 1px solid #666;
cursor:pointer; border-radius: 15px;"
}
];
},
contextMenu: new DayPilot.Menu({
items: [
{
text: "Edit...",
onClick: args => {
app.editEvent(args.source);
}
},
{
text: "Delete",
onClick: args => {
app.deleteEvent(args.source);
}
},
{
text: "-"
},
{
text: "Duplicate",
onClick: args => {
app.duplicateEvent(args.source);
}
},
]
})
日/周/月日历视图切换
自 2023.2 版本以来,DayPilot 包含一个用于轻松切换已定义视图(日/周/月/自定义)的辅助工具,并集成了日期选择器(视图与日期选择器选择同步)。
在以下教程中了解更多信息:
资源标题自定义
自 2023.3 版本以来,DayPilot 允许自定义列标题。现在,您可以使用 onBeforeHeaderRender
事件处理程序来修改文本/HTML,更改背景颜色,向标题添加图标、操作按钮和自定义元素。
这在资源日历/调度器模式中尤其有用,您在该模式中将资源显示为列 - 您可以轻松显示资源的图像,添加状态图标或编辑按钮。
实时演示
教程:ASP.NET Core 维护调度
一篇解释如何使用 DayPilot 在 ASP.NET Core 中创建彩色编码维护计划的新教程现已推出。
此维护调度应用程序具有以下功能:
- 该应用程序处理维护类型,这些类型为每个维护任务定义一个蓝图。
- 每种维护类型都有指定的颜色,并定义了维护期间需要执行的操作清单。
- 计划的任务显示在月历视图中。
- 您可以通过拖放来调整计划,并根据需要移动计划的任务。
- 当所有清单操作都完成后,您可以轻松安排下一次维护的日期。
- 前端采用 HTML5/JavaScript 实现。
- 后端使用 ASP.NET Core、Entity Framework 和 SQL Server 实现。
Next.js 日历
自 2024.1 版本以来,DayPilot 支持在 Next.js 应用程序中集成 React 日历组件。有关介绍和示例项目下载,请参阅以下教程:
另请参阅
- DayPilot for JavaScript [
javascript.daypilot.org
] - HTML5 事件日历(开源) 教程 [
code.daypilot.org
]
历史
- 2024 年 9 月 23 日:DayPilot Lite for JavaScript 2024.3.547 发布(日期选择器带响应式模式,
- 2024 年 7 月 15 日:DayPilot Lite for JavaScript 2024.3.539 发布(支持 Angular 18,自定义 周开始日)。
- 2024 年 5 月 28 日:DayPilot Lite for JavaScript 2024.2.528 发布(引入了月历日期单元格自定义)。
- 2024 年 3 月 19 日:DayPilot Lite for JavaScript 2024.1.524 发布(引入了日历单元格自定义)。
- 2024 年 1 月 8 日:DayPilot Lite for JavaScript 2024.1.517 发布。新教程:ASP.NET Core 资源调度日历(开源),Spring Boot 资源调度日历(开源)。
- 2023 年 11 月 20 日:DayPilot Lite for JavaScript 2023.4.504 发布。附加项目已更新(样式、小改进)。提供 .NET 8 项目。
- 2023 年 9 月 11 日:DayPilot Lite for JavaScript 2023.3.499 发布。
- 2023 年 6 月 7 日:DayPilot Lite for JavaScript 2023.2.477 发布。
新教程:Spring Boot 周历事件日历(开源),Spring Boot 月历(开源)。 - 2023 年 3 月 20 日:DayPilot Lite for JavaScript 2023.1.450 发布。
新教程:ASP.NET Core 周历(开源),ASP.NET Core 月历(开源)。 - 2022 年 12 月 5 日:DayPilot Lite for JavaScript 2022.4.438 发布。
自上次发布以来的新功能:日历事件上下文菜单、图标(包含一组 SVG 图标)、更新的 CSS 主题、事件活动区域。
文章更新:CSS 主题截图、上下文菜单示例。ASP.NET Core 项目使用 .NET 7。 - 2022 年 7 月 20 日:DayPilot Lite for JavaScript 2022.3.398 发布。
自上次发布以来的新功能:日历高度规格:“BusinessHoursNoScroll
”,资源日历,日历列标题点击事件。 - 2022 年 4 月 11 日:DayPilot Lite for JavaScript 2022.1.364 发布(月历事件中的可自定义条,日期选择器组件中的自由选择范围:带拖放范围选择的 Angular 日期选择器)。
- 2022 年 1 月 26 日:DayPilot Lite for JavaScript 2022.1.355 发布(内置 XSS 攻击防护,月历的删除图标,月历的单元格标题点击事件);示例项目升级到 .NET 6。
- 2021 年 12 月 28 日:DayPilot Lite for JavaScript 2021.4.341 发布:Angular、React 和 Vue 日历组件支持,扩展的日期选择器(Navigator 组件)。
- 2021 年 6 月 2 日:DayPilot Lite for JavaScript 2021.2.261 发布;更新为 ES6 语法;添加了事件编辑部分。
- 2021 年 1 月 18 日:DayPilot Lite for JavaScript 2021.1.248 发布;ASP.NET Core 后端(.NET 5、Entity Framework);移除了 jQuery 依赖项。
- 2018 年 6 月 18 日:DayPilot Lite for JavaScript 2018.1.232 发布(API 改进,将事件删除添加到项目源代码)。
- 2018 年 2 月 27 日:DayPilot Lite for JavaScript 2018.1.228 发布(引入了事件删除)。
- 2016 年 12 月 12 日:DayPilot Lite for JavaScript 1.3 SP5 发布;Navigator CSS 样式改进。
- 2016 年 8 月 24 日:DayPilot Lite for JavaScript 1.3 SP4 发布;支持月历事件自定义。
- 2016 年 6 月 6 日:DayPilot Lite for JavaScript 1.3 SP3 发布;添加了事件自定义示例。
- 2016 年 4 月 26 日:DayPilot Lite for JavaScript 1.3 SP2 发布;添加了 AngularJS “controller as” 语法示例。
- 2016 年 1 月 3 日:修复了 CSS 主题切换问题。DayPilot Lite for JavaScript 1.3 SP1 发布。示例项目使用最新的 DayPilot Lite 版本。示例 ASP.NET MVC 项目使用 Visual Studio 2015。添加了 jQuery 部分。添加了月历视图部分。
- 2015 年 11 月 2 日:DayPilot Lite for JavaScript 1.3 发布。
- 2015 年 6 月 3 日:DayPilot Lite for JavaScript 1.2 SP2 发布。
- 2015 年 3 月 23 日:DayPilot Lite for JavaScript 1.2 SP1 发布。示例项目已更新和修复(拖放事件调整大小)。
- 2015 年 1 月 12 日:DayPilot Lite for JavaScript 1.2 发布,包含AngularJS 事件日历插件,AngularJS 月历插件。
- 2014 年 11 月 10 日:添加了文档链接。
- 2014 年 7 月 17 日:添加了用于切换可见周的 Navigator 代码。
- 2014 年 5 月 15 日:修复了 backend_events.php 代码列表(使用
$_POST
而不是$_GET
)。 - 2014 年 4 月 1 日:DayPilot Lite for JavaScript 1.1 SP1 发布,添加了本地化示例。
- 2014 年 3 月 17 日:添加了示例 ASP.NET MVC5 后端(下载和代码列表)。
- 2014 年 3 月 13 日:DayPilot Lite for JavaScript 1.1 发布。
- 2014 年 2 月 24 日:初始版本。