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

ASP.NET MVC3:创建一个自定义日历/日期选择器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (8投票s)

2012年4月6日

CPOL

4分钟阅读

viewsIcon

52570

downloadIcon

2629

为您的项目创建您自己的自定义日历/日期选择器

下载 Calendar.zip 

引言

在本文中,我们将向您展示如何在 ASP.NET MVC3 中创建一个自定义日历。这些步骤很简单,遵循 MVC 范例,从创建模型到在月份之间导航。 

背景

社区中存在一些日期选择器插件,开发人员可以在他们的应用程序中使用,一个流行的例子是 Jquery 日期选择器插件。然而,我们可能会遇到需要自定义日期选择器(或者我们称之为日历)以合并要显示的数据甚至样式的场景。当然,您可以修改任何插件的代码以适应您的场景;但是,构建您自己的自定义日历更容易,它可以使您的应用程序与众不同。一个场景的例子是,HIS 应用程序需要在每个日期显示每日患者和治疗,开发人员首先想到的就是我们需要构建自己的日期选择器。

如果自定义日历以显示数据,例如插入每天的简单通知。

使用代码

  • 创建一个模型 - CalendarModel。
  • 创建一个服务类,用于日期的逻辑和转换。
  • 创建一个控制器和调用服务的操作。
  • 创建一个视图,可以显示当前月份。
  • 创建一个 JavaScript(jQuery 库)来在月份之间导航

让我们从创建一个名为 CalendarModel 的新模型开始,该模型定义了此项目所需的类。

public class WeekForMonth
{
    public List<Day> Week1 { get; set; } //days for week1
    public List<Day> Week2 { get; set; } //days for week2
    public List<Day> Week3 { get; set; } //days for week3
    public List<Day> Week4 { get; set; } //days for week4
    public List<Day> Week5 { get; set; } //days for week5
    public List<Day> Week6 { get; set; } //days for week6
    public string nextMonth { get; set; }
    public string prevMonth { get; set; }
}

public class Day
{
    public DateTime Date { get; set; }
    public string _Date { get; set; }
    public string dateStr { get; set; }
    public int dtDay { get; set; }
    public int? daycolumn { get; set; }
   
}

创建一个服务文件夹和类(我们称之为 CalendarManager.cs)来执行日期的后端逻辑和转换。服务类包含几个用于计算日历中日期、日期和日期列的函数。首先,我们需要调用 getDates(year,month) 函数来获取所选月份和年份的每个日期,然后通过 GetWeekOfMonth(DateTime date) 知道该日期属于该月的哪一周。通过使用 getCalendar 函数返回 WeekForMonth 的模型来完成我们的服务,该函数将每个月的每一天和星期数映射起来。

//main function to arrange each details of day into a month, function returns a list of weeks for a month
public WeekForMonth getCalender(int month, int year)
{

    WeekForMonth weeks = new WeekForMonth();
    weeks.Week1 = new List<Day>();
    weeks.Week2 = new List<Day>();
    weeks.Week3 = new List<Day>();
    weeks.Week4 = new List<Day>();
    weeks.Week5 = new List<Day>();
    weeks.Week6 = new List<Day>();

    List<DateTime> dt = new List<DateTime>();
    dt = GetDates(year, month);

    foreach (DateTime day in dt)
    {
        switch (GetWeekOfMonth(day))
        {
            case 1:
                Day dy1 = new Day();
                        
                dy1.Date = day;
                dy1._Date = day.ToShortDateString();
                dy1.dateStr = day.ToString("MM/dd/yyyy");
                dy1.dtDay = day.Day;
                dy1.daycolumn = GetDateInfo(dy1.Date);
                weeks.Week1.Add(dy1);
                break;
            case 2:
                Day dy2 = new Day();
                dy2.Date = day;
                dy2._Date = day.ToShortDateString();
                dy2.dateStr = day.ToString("MM/dd/yyyy");
                dy2.dtDay = day.Day;
                dy2.daycolumn = GetDateInfo(dy2.Date);
                weeks.Week2.Add(dy2);
                break;
            case 3:
                Day dy3 = new Day();
                dy3.Date = day;
                dy3._Date = day.ToShortDateString();
                dy3.dateStr = day.ToString("MM/dd/yyyy");
                dy3.dtDay = day.Day;
                dy3.daycolumn = GetDateInfo(dy3.Date);
                weeks.Week3.Add(dy3);
                break;
            case 4:
                Day dy4 = new Day();
                dy4.Date = day;
                dy4._Date = day.ToShortDateString();
                dy4.dateStr = day.ToString("MM/dd/yyyy");
                dy4.dtDay = day.Day;
                dy4.daycolumn = GetDateInfo(dy4.Date);
                weeks.Week4.Add(dy4);
                break;
            case 5:
                Day dy5 = new Day();
                dy5.Date = day;
                dy5._Date = day.ToShortDateString();
                dy5.dateStr = day.ToString("MM/dd/yyyy");
                dy5.dtDay = day.Day;
                dy5.daycolumn = GetDateInfo(dy5.Date);
                weeks.Week5.Add(dy5);
                break;
            case 6:
                Day dy6 = new Day();
                dy6.Date = day;
                dy6._Date = day.ToShortDateString();
                dy6.dateStr = day.ToString("MM/dd/yyyy");
                dy6.dtDay = day.Day;
                dy6.daycolumn = GetDateInfo(dy6.Date);
                weeks.Week6.Add(dy6);
                break;
        };
    }

    while (weeks.Week1.Count < 7) // not starting from sunday
    {
        Day dy = null;
        weeks.Week1.Insert(0, dy);
    }

    if (month == 12)
    {
        weeks.nextMonth = (01).ToString() + "/" + (year + 1).ToString();
        weeks.prevMonth = (month - 1).ToString() + "/" + (year).ToString();
    }
    else if (month == 1)
    {
        weeks.nextMonth = (month + 1).ToString() + "/" + (year).ToString();
        weeks.prevMonth = (12).ToString() + "/" + (year - 1).ToString();
    }
    else
    {
        weeks.nextMonth = (month + 1).ToString() + "/" + (year).ToString();
        weeks.prevMonth = (month - 1).ToString() + "/" + (year).ToString();
    }

    return weeks;
}

//get all dates for a month for the year specified
public static List<DateTime> GetDates(int year, int month)
{
    return Enumerable.Range(1, DateTime.DaysInMonth(year, month))  // Days: 1, 2 ... 31 etc.
    .Select(day => new DateTime(year, month, day)) // Map each day to a date
    .ToList();
}

//get number of week for the selected month by passing in a date value
public static int GetWeekOfMonth(DateTime date)
{
    DateTime beginningOfMonth = new DateTime(date.Year, date.Month, 1);
    while (date.Date.AddDays(1).DayOfWeek != DayOfWeek.Sunday)
        date = date.AddDays(1);
    return (int)Math.Truncate((double)date.Subtract(beginningOfMonth).TotalDays / 7f) +           1;
}

//translate each day to a day number for mapping to week
public int GetDateInfo(DateTime now)
{
    int dayNumber = 0;
    DateTime dt = now.Date;
    string dayStr = Convert.ToString(dt.DayOfWeek);

    if (dayStr.ToLower() == "sunday")
    {
        dayNumber = 0;
    }
    else if (dayStr.ToLower() == "monday")
    {
        dayNumber = 1;
    }
    else if (dayStr.ToLower() == "tuesday")
    {
        dayNumber = 2;
    }
    else if (dayStr.ToLower() == "wednesday")
    {
        dayNumber = 3;
    }
    else if (dayStr.ToLower() == "thursday")
    {
        dayNumber = 4;
    }
    else if (dayStr.ToLower() == "friday")
    {
        dayNumber = 5;
    }
    else if (dayStr.ToLower() == "saturday")
    {
        dayNumber = 6;
    }
    return dayNumber;
}

在我们的 Home Controller 中创建一个控制器并调用服务。我们需要一个用于初始页面的操作结果和一个异步控制器,用于 ajax 调用以返回我们下个月/上个月的日历模型。

public ActionResult Index()
{
    var model = _calendar.getCalender(DateTime.Now.Month, DateTime.Now.Year);
    return View(model);
}

//for ajax request
public ActionResult AsyncUpdateCalender(int month, int year)
{
    if (HttpContext.Request.IsAjaxRequest())
    {
        var model = _calendar.getCalender(month, year);
        return Json(model, JsonRequestBehavior.AllowGet);
    }
    else
    {
        return View();
    }
}

创建一个视图页面,生成日历 html 表格形式。视图页面需要强类型模型 WeekForMonth。视图页面必须添加 C# 代码来循环模型中的项目到我们的表格中,id="component-table"用于显示。注意:请参考显示的图像以获得我们的日历显示,以便更清楚地查看 html 的结果。我们有标题(用于月份名称和导航)和内容(用于日期显示)。

@model Calendar.Models.WeekForMonth
<div id="component-header">
<a id="@Model.prevMonth" 
  class="month" style="float:left;margin-left:10px;">Prev</a> 
    @DateTime.Now.ToString("MMM") @DateTime.Now.Year <a id="@Model.nextMonth" 
    class="month" style="float:right;margin-right:10px;">Next</a>
</div>

<div>
        <table id="component-table">
            <thead>
            <tr>
                <th>
                    Sun
                </th>
                <th>
                    Mon
                </th>
                <th>
                    Tue
                </th>
                <th>
                    Wed
                </th>
                <th>
                    Thurs
                </th>
                <th>
                    Fri
                </th>
                <th>
                    Sat
                </th>
            </tr>
            </thead>
            <tbody>
                <tr id="week1">
                @foreach (var item in Model.Week1)
                {
                    if (item != null)
                    {
                        if (item.daycolumn == 0 || item.daycolumn == 6)
                        {
                            <td class="weekend"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else if (item.Date != DateTime.Today)
                        {
                            <td><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else
                        {
                            <td class="selected"><a id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                    }
                    else
                    {
                        <td></td>
                    }
                }
                </tr>
                <tr id="week2">
                @foreach (var item in Model.Week2)
                {
                    if (item != null)
                    {
                        if (item.daycolumn == 0 || item.daycolumn == 6)
                        {
                            <td class="weekend"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else if (item.Date != DateTime.Today)
                        {
                            <td><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else
                        {
                            <td class="selected"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                    }
                    else
                    {
                        <td></td>
                    }
                }
                </tr>
                <tr id="week3">
                @foreach (var item in Model.Week3)
                {
                    if (item != null)
                    {
                        if (item.daycolumn == 0 || item.daycolumn == 6)
                        {
                            <td class="weekend"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else if (item.Date != DateTime.Today)
                        {
                            <td><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else
                        {
                            <td class="selected"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                    }
                    else
                    {
                        <td></td>
                    }
                }
                </tr>
                <tr id="week4">
                @foreach (var item in Model.Week4)
                {
                    if (item != null)
                    {
                        if (item.daycolumn == 0 || item.daycolumn == 6)
                        {
                            <td class="weekend"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else if (item.Date != DateTime.Today)
                        {
                            <td><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else
                        {
                            <td class="selected"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                    }
                    else
                    {
                        <td></td>
                    }
                }
                </tr>
                 <tr id="week5">
                @foreach (var item in Model.Week5)
                {
                    if (item != null)
                    {
                        if (item.daycolumn == 0 || item.daycolumn == 6)
                        {
                            <td class="weekend"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else if (item.Date != DateTime.Today)
                        {
                            <td><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                        else
                        {
                            <td class="selected"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                        }
                    }
                    else
                    {
                        <td></td>
                    }
                }                    
                </tr>
                <tr id="week6">
                @if (Model.Week6 != null)
                {
                    foreach (var item in Model.Week6)
                    {
                        if (item != null)
                        {
                            if (item.daycolumn == 0 || item.daycolumn == 6)
                            {
                            <td class="weekend"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                            }
                            else if (item.Date != DateTime.Today)
                            {
                            <td><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3></a></td>
                            }
                            else
                            {
                            <td class="selected"><a  id="@item.dateStr" 
                              class="dt"><h3>@item.dtDay</h3> </a></td>
                            }
                        }
                        else
                        {
                        <td></td>
                        }
                    }
                }          
                </tr>
            </tbody>
            </table>
</div>

JavaScript(jquery 库)使用 ajax 调用在单击上个月或下个月时进行即时更新。该脚本的示例也可以在项目文件中找到。该脚本通过异步调用操作结果来获取下个月/上个月的数据,清空初始表中的数据,最后将新数据分配到表中来实现。

单击上一个/下一个链接将触发一个事件到 AsyncUpdateCalendar,通过 ajax 调用。我们清空现有表的每一周,循环遍历收到的结果,并按周数追加结果。

$(".month").live('click', function () {
    var object = $(this).attr("id");
    var str = object.split('/');
    // str[0] contains "month"
    // str[1] contains "year"
    $.ajax
    ({
        url: '../../Home/AsyncUpdateCalender',
        type: 'GET',
        traditional: true,
        contentType: 'application/json',
        data: { month: str[0], year: str[1] },
        success: function (result) {
            if (!jQuery.isEmptyObject(result)) {
                var week1 = $("#week1");
                week1.empty();
                var week2 = $("#week2");
                week2.empty();
                var week3 = $("#week3");
                week3.empty();
                var week4 = $("#week4");
                week4.empty();
                var week5 = $("#week5");
                week5.empty();
                var week6 = $("#week6");
                week6.empty();
                var newHeader = $('<a id=' + result.prevMonth + ' class="month" ' + 
                  'style="float:left">Prev</a>' + getMonth(str[0]) + ' ' + 
                  str[1] + '<a id=' + result.nex	            tMonth + 
                  ' class="month" style="float:right">Next</a>');
                $("#component-header").empty();
                $("#component-header").append(newHeader);
                $.each(result.Week1, function (i, item) {
                    var htmlStr = null;
                    if (jQuery.isEmptyObject(item)) {
                        htmlStr = $('<td></td>');
                        week1.append(htmlStr);
                    } else {
                        if (item.daycolumn == 0 || item.daycolumn == 6) {
                            htmlStr = $('<td class="weekend"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3></a>');
                        }
                                                
                        else if (item._Date != getTodayDate()) {                                
                            htmlStr = $('<td></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3></a>');
                        } else {
                            htmlStr = $('<td class="selected"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3></a>');
                        }
                        week1.append(htmlStr);
                    }
                });
                $.each(result.Week2, function (i, item) {
                    var htmlStr = null;
                    if (jQuery.isEmptyObject(item)) {
                        htmlStr = $('<td></td>');
                        week2.append(htmlStr);
                    } else {
                        if (item.daycolumn == 0 || item.daycolumn == 6) {
                            htmlStr = $('<td class="weekend"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        else if (item.Date != getTodayDate()) {
                            htmlStr = $('<td></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        } else {
                            htmlStr = $('<td class="selected"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        week2.append(htmlStr);
                    }
                });
                $.each(result.Week3, function (i, item) {
                    var htmlStr = null;
                    if (jQuery.isEmptyObject(item)) {
                        htmlStr = $('<td></td>');
                        week3.append(htmlStr);
                    } else {
                        if (item.daycolumn == 0 || item.daycolumn == 6) {
                            htmlStr = $('<td class="weekend"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        else if (item.Date != getTodayDate()) {
                            htmlStr = $('<td></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        } else {
                            htmlStr = $('<td class="selected"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + 
                              item.dtDay + '</h3> </a>');
                        }
                        week3.append(htmlStr);
                    }
                });
                $.each(result.Week4, function (i, item) {
                    var htmlStr = null;
                    if (jQuery.isEmptyObject(item)) {
                        htmlStr = $('<td></td>');
                        week4.append(htmlStr);
                    } else {
                        if (item.daycolumn == 0 || item.daycolumn == 6) {
                            htmlStr = $('<td class="weekend"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        else if (item.Date != getTodayDate()) {
                            htmlStr = $('<td></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        } else {
                            htmlStr = $('<td class="selected"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        week4.append(htmlStr);
                    }
                });
                $.each(result.Week5, function (i, item) {
                    var htmlStr = null;
                    if (jQuery.isEmptyObject(item)) {
                        htmlStr = $('<td></td>');
                        week5.append(htmlStr);
                    } else {
                        if (item.daycolumn == 0 || item.daycolumn == 6) {
                            htmlStr = $('<td class="weekend"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        else if (item.Date != getTodayDate()) {
                            htmlStr = $('<td></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        } else {
                            htmlStr = $('<td class="selected"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        week5.append(htmlStr);
                    }
                });
                $.each(result.Week6, function (i, item) {
                    var htmlStr = null;
                    if (jQuery.isEmptyObject(item)) {
                        htmlStr = $('<td></td>');
                        week6.append(htmlStr);
                    } else {
                        if (item.daycolumn == 0 || item.daycolumn == 6) {
                            htmlStr = $('<td class="weekend"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        else if (item.Date != getTodayDate()) {
                            htmlStr = $('<td></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        } else {
                            htmlStr = $('<td class="selected"></td>');
                            htmlStr.append('<a   id=' + item.dateStr + 
                              ' class="dt"><h3>' + item.dtDay + '</h3> </a>');
                        }
                        week6.append(htmlStr);
                    }
                });
                $("#component-table").trigger("update");
            } else {
                alertMsg('Oops, errors occur in retrieving calender');
            }
        }
    });
});

最终输出必须使用 css 进行样式设置,并可能在 html 属性中进行分配。创建自己的自定义日历/日期选择器的主要挑战包括正确计算周数,将日期映射到日期和周,以及根据所选月份更新日历。注意:要在同一图块中为每一天进行通知,您可能需要在 getCalendar 函数中添加更多服务逻辑,并修改 html 中的每一行周以显示项目。

关注点

我们想强调的主要观点是,使用 C# 和 jquery 构建自定义日历/日期选择器并不难。它为您的应用程序增加了独特性,并且我们的方法可以应用于构建约会/日程安排应用程序。例如,我们将日历设计成带有数据的图块,并且日期位于同一图块上,您可以根据您的场景在任何图块上添加通知消息。

贷方

感谢 RabbitChemo 团队的 Dwee Chee Siong 先生(实习生)和 Kenovan Cheok 先生(后端工程师)编译所有必要的开源贡献信息。

© . All rights reserved.