【问题标题】:Fullcalendar recurring events limits (using dow)Fullcalendar 重复事件限制(使用 dow)
【发布时间】:2015-09-29 17:41:15
【问题描述】:

我一直在尝试在 fullcalendar 中制作重复事件,我真的觉得 dow 功能很有帮助,但我真的想为其添加日期范围。

换句话说,dow : [1] 将在每个星期一重复一个任务,问题是,我想让它只在我设置的日期范围内可见。

【问题讨论】:

标签: fullcalendar


【解决方案1】:
function createCalendar() {
        vm.uiConfig = timeProfileFactory.getCalendarConfig();
        vm.uiConfig.calendar.eventClick = eventClick;
        vm.uiConfig.calendar.eventDrop = alertOnDrop;
        vm.uiConfig.calendar.eventResize = alertOnResize;
        vm.uiConfig.calendar.eventRender = eventRender;
        vm.uiConfig.calendar.select = selectSlot;
        vm.uiConfig.calendar.header.center = "title";

        vm.events = function(start, end, timezone, callback) {
            callback(repeatingEvents);
        }
        vm.eventSources = [vm.events];
    };

function selectSlot(start, end, jsEvent, view) {
        var allDay = !start.hasTime() && !end.hasTime();
        var offset = ((new Date()).getTimezoneOffset())/60;
        var dateStart = (new Date(start)).setHours(0, 0, 0, 0);      
        dateStart = new Date(dateStart);
        dateStart.setHours(dateStart.getHours() - offset);
        dateStart = dateStart.toISOString();

        var timeStart = (new Date(start)).toISOString();
        var timeEnd = (new Date(end)).toISOString();
        timeStart = timeStart.split('T')[0];
        timeEnd = timeEnd.split('T')[0];

        var length = repeatingEvents.length;
        if(positionEvent == -1 || repeatingEvents.length == 0) {
            positionEvent = 0;
        } else {
            positionEvent = repeatingEvents[length - 1].position + 1;
        }

        repeatingEvents.push({
            title: "From: " + start.format("DD/MM/YYYY"),
            start: start.format("HH:mm"),
            end: end.format("HH:mm"),
            dow: [new Date(start).getDay()],
            ranges: [{
                start: dateStart,
                end: null
            }],
            position: positionEvent,
            allDay: false
        });

        length++;
        if(repeatingEvents[length - 1].end == "00:00") {
            repeatingEvents[length - 1].end = "24:00";
        }
        if(allDay) {
            repeatingEvents[length - 1].allDay = true;
            repeatingEvents[length - 1].start = null;
            repeatingEvents[length - 1].end = null;
        }
        $("#calendar").fullCalendar("refetchEvents");
    };

function eventClick(event, date, jsEvent, view) {
        isOpenDialog = true;
        for(var i = 0; i < repeatingEvents.length; i++) {
            if(repeatingEvents[i].position == event.position && isOpenDialog) {
                selectIndex = i;
                vm.timeStart = repeatingEvents[i].start;
                vm.timeFinish = repeatingEvents[i].end;
                vm.dateStart = repeatingEvents[i].title.split(' ')[1];

                if(repeatingEvents[i].ranges[0].end == null) {
                    vm.dateFinish = "";
                    vm.radioValue = "never";
                } else {
                    vm.dateFinish = repeatingEvents[i].title.split(' ')[3];
                    vm.radioValue = "on";
                }

                angular.forEach(vm.checkDays, function(item) {
                    item.checked = false;
                });

                angular.forEach(event.dow, function(index) {
                    vm.checkDays[index].checked = true;
                })

                openDialog();    
                break;
            }
        }
    };

function alertOnResize(event, delta, revertFunc, jsEvent, ui, view) {
        for(var i in repeatingEvents) {
            if(repeatingEvents[i].position == event.position) {
                var timeFinish = event.end.format("HH:mm");
                if(timeFinish == "00:00") {
                    timeFinish = "24:00";
                }
                repeatingEvents[i].end = timeFinish;
                break;
            }
        }
        $("#calendar").fullCalendar("refetchEvents");
    };

function alertOnDrop(event, delta, revertFunc, jsEvent, ui, view) {
        for(var i in repeatingEvents) {
            if(repeatingEvents[i].position == event.position) {
                if(repeatingEvents[i].allDay || event.allDay) {
                    revertFunc();
                } else {
                    var timeStart = event.start.format("HH:mm");
                    var timeFinish = event.end.format("HH:mm");
                    var dateStart = repeatingEvents[i].ranges[0].start;
                    var dateFinish = repeatingEvents[i].ranges[0].end;
                    var oldTimeStart = repeatingEvents[i].start.split(':')[0]*3600 + repeatingEvents[i].start.split(':')[1]*60;
                    var newTimeStart = timeStart.split(':')[0]*3600 + timeStart.split(':')[1]*60;
                    var deltaHour = newTimeStart - oldTimeStart;
                    var deltaDay = (delta/1000 - deltaHour)/86400;
                    dateStart = new Date(dateStart);
                    dateStart.setDate(dateStart.getDate() + deltaDay);
                    dateStart = dateStart.toISOString();
                    var title;

                    if(dateFinish != null) {
                        dateFinish = new Date(dateFinish);
                        dateFinish.setDate(dateFinish.getDate() + deltaDay);
                        dateFinish = dateFinish.toISOString();
                        title = "From: " + moment(dateStart).format("DD/MM/YYYY") + " To: " + moment(dateFinish).format("DD/MM/YYYY");
                    } else {
                        title = "From: " + moment(dateStart).format("DD/MM/YYYY");
                    }

                    for(var j in event.dow) {
                        repeatingEvents[i].dow[j] = parseInt(repeatingEvents[i].dow[j]) + deltaDay;
                        if(repeatingEvents[i].dow[j] > 6) {
                            repeatingEvents[i].dow.splice(j, 1);
                        }
                    }

                    repeatingEvents[i].start = timeStart;
                    repeatingEvents[i].end = timeFinish;
                    repeatingEvents[i].ranges[0].start = dateStart;
                    repeatingEvents[i].ranges[0].end = dateFinish;
                    repeatingEvents[i].title = title;

                    if(timeFinish == "00:00") {
                        repeatingEvents[i].end = "24:00";
                    }
                    $("#calendar").fullCalendar("refetchEvents");
                }
                break;
            }
        }
    };

function eventRender(event, element, view) {
        var removeEvent = $("<i class='removeEvent icons8-delete pull-right'></i>");
        removeEvent.on("click", function() {
            isOpenDialog = false;
            vm.removeEvent(event);
        });
        element.find(".fc-content").prepend(removeEvent);

        var result;
        if(event.ranges[0].end == null) {
            result = (event.ranges.filter(function(range) {
                var startConvert = (new Date(event.start)).toISOString();
                return (event.start.isAfter(range.start) || startConvert == range.start);
            }).length) > 0;
        } else {
            result = (event.ranges.filter(function(range) {
                return (event.start.isBefore(range.end) && event.end.isAfter(range.start));
            }).length) > 0;
        }
        return result;
    };

【讨论】:

    【解决方案2】:

    您不能使用 dow 设置范围,您必须执行一些自定义功能。

    假设您已从包含多个事件对象的数据库中获取事件数据。每个event 对象都有start 日期end 日期属性以及包含日期范围的tofrom 属性,isRecurring 是一个布尔属性,我们将添加true 以防重复事件,否则它将是false

    记住重复事件的开始和结束时间没有日期,你只需要给他们时间段,比如start = "16:00" and end = "20:00"你可以像我在初始化我的事件时那样使用moment js来提取时间对象

                    {
                      title:'Recurring Event',
                      start: moment.utc(event.start).format('HH:mm'),
                      end: moment.utc(event.end).format('HH:mm'),
                      isRecurrring: event.isRecurring,
                      ranges: [{
                          start: moment(event.from),
                          end: moment(event.to),
                        }],
                    }
    

    我使用 moment.utc() 来忽略时区。

    现在在初始化 fullCalendar 时覆盖 eventRender 函数。您的 eventRender 函数将是

    eventRender: function(event, element, view){
        if (event.isRecurrring) {
          return (event.ranges.filter(function(range){
            return (moment(event.start).isBefore(range.end) &&
            moment(event.end).isAfter(range.start));
          }).length) > 0;
        }
      }
    

    【讨论】:

      【解决方案3】:

      你可以像这个例子一样设置范围:

      repeatingEvents.push({
              title: "From: " + inputDateStart + " To: " + inputDateFinish,
              start: vm.timeStart,
              end: vm.timeFinish,
              dow: listDay,
              ranges: [{
                  start: dateStart,
                  end: dateFinish
              }]
          })
      
          $("#calendar").fullCalendar("refetchEvents");
      

      因此,您可以同时使用“道”和“范围”。希望对你有所帮助!

      【讨论】:

      • 你试过了吗?你有什么例子吗?对我来说,上述解决方案不起作用。
      • 哦,它对我有用!我只能发布这些功能相关
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 2015-03-26
      • 2017-04-20
      相关资源
      最近更新 更多