用于资源计划的JavaScript事件日历
目录
- 下载PHP示例项目 - 69 KB
- 下载ASP.NET Core (.NET 8)的示例项目 - 80 KB
-
下载 DayPilot Lite for JavaScript 2024.1 事件日历
(开放源代码)[javascript.daypilot.org] -
在线演示
[javascript.daypilot.org]
在本文中,我们将构建一个简单的 HTML5/JavaScript事件日历 Web应用程序。客户端部分是通用的。我们将使用示例PHP和ASP.NET Core后端。
特征:
- 每周HTML5事件日历/调度程序
- 资源计划程序模式,将资源显示为列
- 使用日期导航器更改日历(左侧)
- 拖放事件创建、移动和调整大小
- 向事件添加图标和图像(状态、分配的资源、上下文菜单提示)
- 使用CSS主题单击更改外观
- PHP RES后端
- ASP.NET Core REST后端(.NET 8、Entity Framework)
我们将使用开源的DayPilot Lite for JavaScript [javascript.daypilot.org]来构建活动日历。DayPilot Lite for JavaScript在Apache许可证2.0下可用。
新功能:Next.js日历
从2024.1版本开始,DayPilot支持在Next.js应用程序中集成React日历组件。有关简介和示例项目下载,请参阅以下教程:
新教程:ASP.NET 核心维护计划
现在提供了一个新教程,解释了如何使用DayPilot在ASP.NET Core中创建颜色编码的维护计划:
此维护计划应用程序具有以下功能:
- 该应用程序使用为每个维护任务定义蓝图的维护类型。
- 每种维护类型都有指定的颜色,并定义维护期间需要执行的操作清单。
- 计划任务显示在每月计划日历视图中。
- 您可以使用拖放来调整计划,并根据需要移动计划任务。
- 完成所有清单操作后,您可以轻松安排下一次维护的日期。
- fronted是用HTML5/JavaScript实现的。
- 后端是使用ASP.NET Core、Entity Framework和SQL Server实现的。
第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" />
并在初始化期间设置theme属性:
<script type="text/javascript">
const dp = new DayPilot.Calendar("dp", {
viewType: "Week",
theme: "calendar_transparent"
});
dp.init();
</script>
您可以选择包含的CSS主题之一,也可以使用在线 CSS主题设计器创建自己的主题。
具有实时预览功能的Configurator应用程序
现在,您可以使用在线 UI Builder 应用程序轻松配置每日/每周和每月日历组件,该应用程序允许您预览实时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 Month支持自定义以下事件属性:
- 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 Weekly Calendar Tutorial (Open-Source) [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、更改背景颜色、向标题添加图标、操作按钮和自定义元素。
这在资源日历/计划程序模式下特别有用,在该模式下,您可以将资源显示为列 - 您可以轻松地显示资源的图像、添加状态图标或编辑按钮。
现场演示:
另见
- 适用于JavaScript的DayPilot [javascript.daypilot.org]
- HTML5活动日历(开源)教程 [code.daypilot.org]
https://www.codeproject.com/Articles/732679/HTML-Event-Calendar-Scheduler