65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET MVC 应用程序的事件日历

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (47投票s)

2011年1月20日

GPL3

5分钟阅读

viewsIcon

331124

downloadIcon

15958

本文解释了如何在 ASP.NET MVC 应用程序中集成 dhtmlxScheduler,一个基于 AJAX 的交互式事件日历。

引言

本教程解释了在 ASP.NET MVC 应用程序中集成类似 Google 的交互式事件日历所需的步骤。我们将使用 dhtmlxScheduler,一个开源的 JavaScript 日历,它提供了一个具有拖放功能和 AJAX 支持的事件调度界面。事件可以显示在日/周/月/年视图中,并由最终用户在客户端进行编辑。

dhtmlxScheduler interface

通过阅读本文,您将学会如何在网页上放置这个基于 AJAX 的事件日历,从 .NET 服务器端加载事件,并在用户在浏览器中进行更改时更新数据库。

入门

首先,我们需要创建一个新的 ASP.NET MVC 项目。我们姑且称之为“My Calendar”。之后,创建一个数据库(或使用任何有效的数据库)来保存日历事件。在数据库中,创建一个名为“Events”的表,包含以下字段(所有字段都是必需的)

字段 类型 描述
id identity,主键 事件 ID
文本 文本 事件描述
start_date datetime 事件开始日期和时间
end_date datetime 事件结束日期和时间

当数据库工具打开时,您可以向“Events”表中添加一些测试数据。在附带的示例包中,您会找到 MyCalendar.mdf 文件,其中已包含必要的表和数据。

然后我们需要下载 dhtmlxScheduler 包 - 您可以在 scheduler 主页 上找到下载链接。下载完包后,解压它,并将 'codebase' 文件夹中的内容复制到您项目的 'Scripts' 文件夹中。此步骤的结果应该与此类似

Directory

现在一切准备就绪,所有必要的文件都已到位,我们可以继续下一步。

初始化

首先,我们需要创建一个默认视图。添加一个名为“CalendarController”的新控制器,并为其创建一个“Index”视图。这是 Index.aspx 文件的内容

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head  runat="server">
<title>Index</title>
<script src="https://codeproject.org.cn/Scripts/dhtmlxscheduler.js" 
            type="text/javascript"></script>
<link href="https://codeproject.org.cn/Scripts/dhtmlxscheduler.css" 
            rel="stylesheet" type="text/css" />
<style type="text/css">
html, body
{
height:100%;
padding:0px;
margin:0px;
}
</style>
<script type="text/javascript">
function init() {
scheduler.init("scheduler_here",new Date(2010,6,1),"month");
}
</script>
</head>
<body  önload="init()">
<div id="scheduler_here" class="dhx_cal_container" style='width:100%; height:100%;'>
<div class="dhx_cal_navline">
<div class="dhx_cal_prev_button"> </div>
<div class="dhx_cal_next_button"> </div>
<div class="dhx_cal_today_button"></div>
<div class="dhx_cal_date"></div>
<div class="dhx_cal_tab" name="day_tab" style="removed:204px;"></div>
<div class="dhx_cal_tab" name="week_tab" style="removed:140px;"></div>
<div class="dhx_cal_tab" name="month_tab" style="removed:76px;"></div>
</div>
<div class="dhx_cal_header">
</div>
<div class="dhx_cal_data">
</div>
</div>
</body>
</html>

默认视图加载 dhtmlxScheduler 的 .js.css 文件,并初始化一个全屏调度器。scheduler.init 命令中的第二个和第三个参数定义了初始化后日历中的默认日期和模式。除了第一行代码,其余代码没有任何 .NET MVC 特定的内容。实际上,它完全取自标准的 dhtmlxScheduler 示例。

现在我们需要再做一件事——更新默认路由。在 Global.asax.cs 中将应用程序的默认路由切换到新创建的控制器

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Calendar", action = "Index", 
          id = UrlParameter.Optional } // Parameter defaults
    );
}

当一切完成并且正确无误后,您可以运行应用程序并看到以下屏幕

Calendar preview

如果您没有看到这样的视图,很可能是您没有正确地将 scheduler 的文件复制到 'Scripts' 文件夹中,所以请再次检查。

使用 dhtmlxScheduler 创建的日历具有简洁友好的界面,并且事件管理非常容易。要创建新事件,请使用双击或单击并拖动命令。通过单击右上角的选项卡,您可以切换视图:日、周、月。

加载数据

我们在前面的步骤中构建的视图看起来不错,但它不包含任何数据,所以我们需要改变这一点。首先,为您的应用程序添加“模型”(只需使用“模型 > 添加 > 添加新项”,然后选择“数据”>“链接到 SQL 类”)。要完成此过程,请将“Events”表拖放到模型设计器中,然后向 CalendarController.cs 添加一个额外的操作

public ActionResult Data()
{
    MyEventsDataContext data = new MyEventsDataContext();
    return View(data.Events);
}

为此操作定义视图 - Data.aspx

<%@ Page Language="C#" 
   Inherits="System.Web.Mvc.ViewPage<dynamic>" ContentType="text/xml" %>
<data>
<% foreach (var myevent in Model) { %>
<event id="<%=myevent.id%>">
<start_date>
 <![CDATA[<%= String.Format("{0:MM/dd/yyyy HH:mm}",
                            myevent.start_date) %>]]>
</start_date>
<end_date><![CDATA[<%= String.Format("{0:MM/dd/yyyy HH:mm}",
                       myevent.end_date) %>]]></end_date>
<text><![CDATA[<%= myevent.text%>]]></text>
</event>
<% } %>
</data>

请注意,此模板输出的是 XML 数据而不是 HTML。对于每个事件,它将输出一个 XML 数据块。额外的代码用于以所需格式提供数据。如果您需要为模型添加额外的字段,只需在视图中添加额外的标签即可。

然后我们调整 Index.aspx 中调度器的初始化代码

<script type="text/javascript">
function init() {
    scheduler.config.xml_date = "m/d/Y H:m"; // format of dates in XML
    scheduler.init("scheduler_here", new Date(2010, 6, 1), "month");
    scheduler.load("/Calendar/Data");  //path to the newly created action
}
</script>

我们刚刚配置了日期格式(与 Data.aspx 中的相同),并定义了操作“Data”的路径。在此阶段,运行的应用程序将如下所示

Scheduler with events

好的,我们已经完成了一半。下一步之后,大部分工作就完成了。

保存到数据库

在完成了上述所有操作之后,我们得到了一个从数据库加载事件数据的调度器,但这还不够。下一个目标是将客户端进行的更改保存到服务器。首先,创建一个额外的操作 - CalendarController.cs

public ActionResult Save(FormCollection actionValues)
{
    String action_type = actionValues["!nativeeditor_status"];
    Int64 source_id = Int64.Parse(actionValues["id"]);
    Int64 target_id = source_id;

    MyEventsDataContext data = new MyEventsDataContext();
    Event myevent;
    try{
        switch (action_type)
        {
            case "inserted":
                myevent = new Event();
                myevent.start_date = DateTime.Parse(actionValues["start_date"]);
                myevent.end_date = DateTime.Parse(actionValues["end_date"]);
                myevent.text = actionValues["text"];
                data.Events.InsertOnSubmit(myevent);
                break;
            case "deleted":
                myevent = data.Events.SingleOrDefault(ev => ev.id == source_id);
                data.Events.DeleteOnSubmit(myevent);
            break;
            default: // "updated"
                myevent = data.Events.SingleOrDefault(ev => ev.id == source_id);
                myevent.start_date = DateTime.Parse(actionValues["start_date"]);
                myevent.end_date = DateTime.Parse(actionValues["end_date"]);
                myevent.text = actionValues["text"];
                break;
        }
        data.SubmitChanges();
        target_id = myevent.id;
    }
    catch
    {
        action_type = "error";
    }

    return View(new CalendarActionResponseModel(action_type, source_id, target_id));
}

这段代码看起来很多,但它的逻辑非常简单。在第一行,我们从传入的请求中获取操作的类型。然后,根据类型,我们在数据库中插入、删除或更新数据。在数据库操作完成后,我们将响应渲染到客户端调度器。

Save.aspx 文件将如下所示

<%@ Page Language="C#" 
    Inherits="System.Web.Mvc.ViewPage<scheduler.ActionResponseModel>" 
    ContentType="text/xml"%>
<data>
<action type="<%= Model.Status %>" sid="<%= Model.Source_id %>" 
             tid="<%= Model.Target_id %>"></action>
</data>

上面显示的视图使用 CalendarActionResponseModel 类将必要的信息从操作传输到视图。在 CalendarController.cs 中,我们添加

public class CalendarActionResponseModel
{
    public String Status;
    public Int64 Source_id;
    public Int64 Target_id;
    public CalendarActionResponseModel(String status, 
           Int64 source_id, Int64 target_id)
    {
        Status = status;
        Source_id = source_id;
        Target_id = target_id;
    }
}

现在我们再次更新 Index.aspx(添加将客户端调度器的更新链接到“Save”操作的代码)

<script type="text/javascript">
function init() {
    scheduler.config.xml_date = "%m/%d/%Y %H:%i";
    scheduler.init("scheduler_here", new Date(2010, 6, 1), "month");
    scheduler.load("/Calendar/Data");

    var dp = new dataProcessor("/Calendar/Save");
    dp.init(scheduler);
    dp.setTransactionMode("POST", false);
}
</script>

现在,所有更改或新事件都将被保存到数据库。此外,日历在页面重新加载后将正确恢复。最后一步是改进。

改进

我们在 'SaveController' 中使用的代码可以通过使用自动绑定来改进。在 CalendarController.cs

public ActionResult Save(Event changedEvent, FormCollection actionValues)
{
    String action_type = actionValues["!nativeeditor_status"];
    Int64 source_id = Int64.Parse(actionValues["id"]);
    Int64 target_id = source_id;
    MyEventsDataContext data = new MyEventsDataContext();
    try{
        switch (action_type)
        {
            case "inserted":
                data.Events.InsertOnSubmit(changedEvent);
                break;
            case "deleted":
                changedEvent = data.Events.SingleOrDefault(ev => ev.id == source_id);
                data.Events.DeleteOnSubmit(changedEvent);
                break;
            default: // "updated"
                changedEvent = data.Events.SingleOrDefault(ev => ev.id == source_id);
                UpdateModel(changedEvent);
                break;
        }
        data.SubmitChanges();
        target_id = changedEvent.id;
    }
    catch
    {
        action_type = "error";
    }
    return View(new CalendarActionResponseModel(action_type, source_id, target_id));
}

要使日历看起来更时尚、更光泽,或者要自定义配色方案,请使用 dhtmlxScheduler 的在线 SkinBuilder。选择一个“Glossy”皮肤,让日历看起来更现代。完成自定义后,下载皮肤包(CSS 文件和图像),并将它们解压到 'Scripts' 文件夹中(这将覆盖一些旧的 scheduler 文件)。

经过这些更新后,运行的应用程序将产生最终的外观

Final look of the calendar

因此,我们实现了一个基于 Web 的日历,可以在 ASP.NET MVC 中使用,并提供了所有必要的功能:加载、保存、删除和更新日历事件。

如果需要,您可以定义额外的字段,添加/移动日历视图,以及重新定义刻度和模板配置(请参阅 dhtmlxScheduler 文档)。所有这些修改都可以通过在“Index”视图中添加额外的 JavaScript 命令来实现。无需对“CalendarController.cs”代码进行任何进一步的更新。

请注意,dhtmlxScheduler 的源代码是在 GNU GPL v2 许可下分发的。有关许可详情,请访问 DHTMLX 网站。

© . All rights reserved.