首页 > 解决方案 > 在页面加载时从模型向 FullCalendar 添加事件

问题描述

我正在尝试在页面加载时向日历的所有日期添加事件,并且它们需要根据每天连接的一些数据具有三种颜色(红色、黄色、绿色)中的一种。三天活动的简单示例:

带有颜色编码事件的完整日历示例

我有一个模型,其中包含有关给定日期的订单有多少免费托盘的数据。如果空闲托盘少于 10 个,事件应该是红色的,如果它在 10 到 149 之间,它必须是黄色等等(如示例所示)。

这是当前的“FullCalendar”脚本:

<script type="text/javascript">
    var calendar = new FullCalendar.Calendar($("#calendar")[0], {
        plugins: ['interaction', 'dayGrid'],
        height: 'auto',
        defaultView: 'dayGridMonth',
        weekNumberCalculation: 'ISO',
        weekNumbers: true,
        events: [
            {
            title: '150-300',
                start: '2020-07-16',
            color: 'green'
            },
            {
            title: '10-149',
                start: '2020-07-15',
            color: 'yellow'
            },
            {
            title: '<10',
                start: '2020-07-14',
            color: 'red'
            }],
        dateClick: function (info) {
            window.location.href = "Incoming?date=" + info.dateStr;
        }
    });
    calendar.render();
    calendar.select('@(Model.Date?.ToString("yyyy-MM-dd"))');
</script>

硬编码的事件仅用于示例。

我想,当页面加载时,根据免费托盘数量的数据,在该月的每个日期用彩色事件填充日历。如何根据我的 MVC (.Net) 应用程序中的模型给出的数据动态创建这些事件?

我已经从这个论坛尝试了几个关于动态添加事件的建议解决方案,但它们要么不起作用,要么与发布操作相关联,我认为在这种情况下没有必要这样做。

更新

我试图在我的控制器中创建一个 JsonResult 操作,它似乎创建了一个有效的 Json 字符串,我可以提供我的 FullCalendar。然而,它似乎不起作用。我有这个动作:

public JsonResult GetCalendarEvents(string id, DateTime? date)
        {
         //Database related code to get dates and their amount of free pallets (this is where I use the id and date parameters)
                var idEvent = 1;
                foreach (var v in days)
                {
                    var title = "";
                    var color = "";
                    var freecap = (v.DayOfWeek == DayOfWeek.Friday ? 200 : 300) - model.Incomings.Where(x => x.ExpectedDate == v &&
                            x.ExpectedPallets.HasValue).Sum(x => x.ExpectedPallets);


                    if(freecap >= 150)
                    {
                        title = "150-300";
                        color = "green";
                    } else if(freecap < 150 && freecap >= 10)
                    {
                        title = "10-149";
                        color = "yellow";
                    } else
                    {
                        title = "<10";
                        color = "red";
                    }

                    events.Add(new CalendarEvent { id = idEvent, title = title, allDay = "", start = v.Date.ToString().Substring(0,10), end = v.Date.ToString().Substring(0, 10), color = color });
                    
                    idEvent++;
                }
            }

            return Json(events, JsonRequestBehavior.AllowGet);

Json 结果如下所示:

[{"id":1,"title":"150-300","allDay":"","start":"19-07-2019","end":"19-07-2019","color":"green"},{"id":2,"title":"150-300","allDay":"","start":"22-08-2019","end":"22-08-2019","color":"green"},{"id":3,"title":"150-300","allDay":"","start":"30-08-2019","end":"30-08-2019","color":"green"}]

添加属性 id、allDay 和 end 是因为这篇文章的最佳答案:Jquery Full Calendar json event source syntax,但这并没有帮助。

日历中没有显示任何事件,但页面和日历加载得很好(没有事件)。我在这里想念什么?

标签: javascriptjsonasp.net-mvcfullcalendarfullcalendar-4

解决方案


在用户@ADyson 的帮助下,我找到了解决问题的方法。如果其他人碰巧遇到相同的问题或希望通过在 MVC 上下文中提供 JSON 来处理 FullCalender 事件,这里有一个比较完整的示例和答案。

首先,我有一个具有必要属性的事件类(我实际上只使用标题、开始和颜色属性,但其余的可能也是必需的,这就是我添加它们的原因,根据这篇文章Jquery Full Calendar json event source syntax ):

public class CalendarEvent
    {
        public int id { get; set; }
        public string title { get; set; }
        public string allDay { get; set; }
        public string start { get; set; }
        public string end { get; set; }
        public string color { get; set; }
    }

然后我在我的控制器中有这样的动作 GetCalendarEvents:

public JsonResult GetCalendarEvents(string id, DateTime? date)
        {
         //Database related code to get dates and their amount of free pallets (this is where I use the id and date parameters)
                var idEvent = 1;
                foreach (var v in days)
                {
                    var title = "";
                    var color = "";
                    var freecap = (v.DayOfWeek == DayOfWeek.Friday ? 200 : 300) - model.Incomings.Where(x => x.ExpectedDate == v &&
                            x.ExpectedPallets.HasValue).Sum(x => x.ExpectedPallets);


                    if(freecap >= 150)
                    {
                        title = "150-300";
                        color = "green";
                    } else if(freecap < 150 && freecap >= 10)
                    {
                        title = "10-149";
                        color = "yellow";
                    } else
                    {
                        title = "<10";
                        color = "red";
                    }

                    events.Add(new CalendarEvent { id = idEvent, title = title, allDay = "", start = v.Date.ToString().Substring(0,10), end = v.Date.ToString().Substring(0, 10), color = color });
                    
                    idEvent++;
                }
            }

            return Json(events, JsonRequestBehavior.AllowGet);
}

操作中的逻辑主要是从我们的数据库中获取正确的数据并确定事件应该具有的颜色和名称(这取决于给定日期我们仓库中的空闲托盘数量)。这个方法可以做任何你需要做的事情,它的本质是它创建一个事件列表并将它们作为 Json 结果返回。

在我的视图中,FullCalendar 脚本和小部件所在的位置我将事件引用到这样的操作(请记住更改路由、控制器、操作和 id 字符串以适合您自己的):

events: '@Url.HttpRouteUrl("Default", new { controller = "Home", action = "GetCalendarEvents", id = "DOD" })'

在所有事件的标题前可能会出现一个字符串“12a”。这是因为它指示了事件的开始时间(我没有设置)。无论哪种情况,如果您想摆脱它,可以将这两行添加到脚本中:

timeFormat: 'H(:mm)', // uppercase H for 24-hour clock
displayEventTime: false

我的完整 FullCalendar 脚本如下所示:

<script type="text/javascript">
    var calendar = new FullCalendar.Calendar($("#calendar")[0], {
        plugins: ['interaction', 'dayGrid'],
        height: 'auto',
        defaultView: 'dayGridMonth',
        weekNumberCalculation: 'ISO',
        weekNumbers: true,
        events: '@Url.HttpRouteUrl("Default", new { controller = "Home", action = "GetCalendarEvents", id = "DOD" })',
        timeFormat: 'H(:mm)', // uppercase H for 24-hour clock
        displayEventTime: false,
        dateClick: function (info) {
                window.location.href = "Incoming?date=" + info.dateStr;
            }
        });
    calendar.render();
    calendar.select('@(Model.Date?.ToString("yyyy-MM-dd"))');
</script>

返回的 JSON 结果应如下所示:

[{"id":1,"title":"150-300","allDay":"","start":"2019-07-19","end":"2019-07-19","color":"green"},{"id":2,"title":"150-300","allDay":"","start":"2019-08-22","end":"2019-08-22","color":"green"},{"id":3,"title":"150-300","allDay":"","start":"2019-08-30","end":"2019-08-30","color":"green"}]

正如@ADyson 指出的那样,这里需要注意的是,日期格式必须是 yyyy-MM-dd (这就是我更新的帖子不起作用的原因)。如果您需要更多信息,请查看 FullCalendar 文档,@ADyson 还链接了该文档: 事件解析事件(作为 json 提要)


推荐阅读