简体   繁体   English

FullCalendar.js - “获取事件时出错”

[英]FullCalendar.js - “there was an error while fetching events”

I'm using FullCalendar.js to display Google Calendar events from multiple sources. 我正在使用FullCalendar.js来显示来自多个来源的Google日历事件。 It's been working OK up until today. 它一直工作到今天。 For some reason FullCalendar started popping up the "there was an error while fetching events" error message and all the events are obviously gone. 由于某种原因,FullCalendar开始弹出“在获取事件时出现错误”错误消息,所有事件显然都消失了。 Here is a jsfiddle. 这是一个jsfiddle。

http://jsfiddle.net/mlk4343/1wko0z1j/1/ http://jsfiddle.net/mlk4343/1wko0z1j/1/

$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
            contentHeight: 600,

eventMouseover: function(calEvent, jsEvent) {
var tooltip = '<div class="tooltipevent">' + calEvent.title + '</div>';
$("body").append(tooltip);
$(this).mouseover(function(e) {
    $(this).css('z-index', 10000);
    $('.tooltipevent').fadeIn('500');
    $('.tooltipevent').fadeTo('10', 1.9);
}).mousemove(function(e) {
    $('.tooltipevent').css('top', e.pageY + 10);
    $('.tooltipevent').css('left', e.pageX + 20);
});
},

eventMouseout: function(calEvent, jsEvent) {
$(this).css('z-index', 8);
$('.tooltipevent').remove();
},

eventSources: [


{
        // Adele H 
        url: 'https://www.google.com/calendar/feeds/sonomaschools.org_u030vtntt1tp7gjn8cnqrr9nsk%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'yellow',   // a non-ajax option
        textColor: 'black' // a non-ajax option
    },


        {
        // Altimira 
        url: 'https://www.google.com/calendar/feeds/sonomaschools.org_e6j3ejc40g02v4sdo0n3cakgag%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'red',   // a non-ajax option
        textColor: 'white' // a non-ajax option
    },


        {
        // Charter 
        url: 'https://www.google.com/calendar/feeds/sonomacharterschool.org_0p2f56g5tg8pgugi1okiih2fkg%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'LightSalmon',   // a non-ajax option
        textColor: 'black' // a non-ajax option
    },

         {// Dunbar 
        url: 'https://www.google.com/calendar/feeds/sonomaschools.org_4tmsks5b9s70k6armb6jkvo9p0%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'green',   // a non-ajax option
        textColor: 'white' // a non-ajax option
    },

     {// El Verano 
        url: 'https://www.google.com/calendar/feeds/pv2hfl7brn6dj8ia3mqksp9fl0%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'LightBlue',   // a non-ajax option
        textColor: 'black' // a non-ajax option
    },


        { // Flowery 
        url: 'https://www.google.com/calendar/feeds/sonomaschools.org_v0a2nmtu4jrca90lui62tccbd4%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'blue',   // a non-ajax option
        textColor: 'white' // a non-ajax option
    },


                { // Prestwood 
           url:'https://www.google.com/calendar/feeds/sonomaschools.org_25rjgf4pu3vsa5i7r7itnqkigs%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'purple',   // a non-ajax option
        textColor: 'white' // a non-ajax option
    },


                { // Sassarini 
        url: 'https://www.google.com/calendar/feeds/sonomaschools.org_18a25r5mrc084gn4ekegadpfm8%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'Aqua ',   // a non-ajax option
        textColor: 'black' // a non-ajax option
    },


       { // SVHS 
        url: 'https://www.google.com/calendar/feeds/sonomaschools.org_h450occacktra5errgbhsrv3k4%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'Chartreuse',   // a non-ajax option
        textColor: 'black' // a non-ajax option
    },


 { // SVUSD
        url: 'https://www.google.com/calendar/feeds/sonomaschools.org_2i1596pg2fokba99kvatqn45bk%40group.calendar.google.com/public/basic',
        type: 'POST', 
        error: function() {
            alert('there was an error while fetching events!');
        },
        color: 'MediumVioletRed',   // a non-ajax option
        textColor: 'white' // a non-ajax option
    },


    ]
});
});

The events show OK on Google Calendar. 这些活动在Google日历上显示正常。

I tried the other solutions, which got me close to a fix but not entirely there. 我尝试了其他解决方案,这让我接近修复但不完全在那里。 The results were fetching the entire set of calendar events and not a set number in a certain date-range. 结果是获取整个日历事件集,而不是特定日期范围内的集合数。

What I discovered was that the names of the Parameters have also changed in the new API. 我发现的是,新API中的参数名称也发生了变化。

See: https://developers.google.com/google-apps/calendar/v3/reference/events/list 请参阅: https//developers.google.com/google-apps/calendar/v3/reference/events/list

My fix involves adding the new APIv3 parameters to the data variable. 我的修复涉及将新的APIv3参数添加到data变量。 Also the date-format for timeMin and timeMax are RFC3339/ATOM and not ISO 8601 (which Moment.js outputs by default) so I have added a format string to produce RFC3339 formatted dates. timeMintimeMax的日期格式也是RFC3339 / ATOM而不是ISO 8601(默认情况下输出Moment.js)所以我添加了一个格式字符串来生成RFC3339格式的日期。

Use the APIv3 URL format in your HTML/PHP file: 在HTML / PHP文件中使用API​​v3 URL格式:

https://www.googleapis.com/calendar/v3/calendars/CALENDAR-ID/events?key=API-KEY

Update your gcal.js to the following code. gcal.js更新为以下代码。 This is based on the fixes posted by user4263042 and Stephen (Thanks guys!) 这是基于user4263042和Stephen发布的修复程序(谢谢你们!)

(function(factory) {
    if (typeof define === 'function' && define.amd) {
        define([ 'jquery' ], factory);
    }
    else {
        factory(jQuery);
    }
})(function($) {


var fc = $.fullCalendar;
var applyAll = fc.applyAll;


fc.sourceNormalizers.push(function(sourceOptions) {

    if (sourceOptions.dataType == 'gcal' ||
        sourceOptions.dataType === undefined &&
        (sourceOptions.url || '').match(/^(http|https):\/\/www.googleapis.com\/calendar\/v3\/calendars/)) {
            sourceOptions.dataType = 'gcal';
            if (sourceOptions.editable === undefined) {
                sourceOptions.editable = false;
            }
        }
});


fc.sourceFetchers.push(function(sourceOptions, start, end, timezone) {
    if (sourceOptions.dataType == 'gcal') {
        return transformOptions(sourceOptions, start, end, timezone);
    }
});


function transformOptions(sourceOptions, start, end, timezone) {

    var success = sourceOptions.success;
    var data = $.extend({}, sourceOptions.data || {}, {
        'singleEvents' : true,
        'maxResults': 250,
        'timeMin': start.format('YYYY-MM-DD[T]HH:mm:ssZ'),
        'timeMax': end.format('YYYY-MM-DD[T]HH:mm:ssZ'),
    });

    return $.extend({}, sourceOptions, {
        url: sourceOptions.url + '&callback=?',
        dataType: 'jsonp',
        data: data,
        success: function(data) {
            var events = [];
            if (data.items) {
                $.each(data.items, function(i, entry) {
                    events.push({
                        id: entry.id,
                        title: entry.summary,
                        start:  entry.start.dateTime || entry.start.date,
                        end: entry.end.dateTime || entry.end.date,
                        url: entry.htmlLink,
                        location: entry.location,
                        description: entry.description || '', 
                    });

                });
            }
            var args = [events].concat(Array.prototype.slice.call(arguments, 1));
            var res = applyAll(success, this, args);
            if ($.isArray(res)) {
                return res;
            }
            return events;
        }
    });

}


// legacy
fc.gcalFeed = function(url, sourceOptions) {
    return $.extend({}, sourceOptions, { url: url, dataType: 'gcal' });
};


});

I believe I have the solution. 我相信我有解决方案。

After a little digging I found a this page , but written as is, the code failed to work correctly. 经过一番挖掘后,我找到了这个页面 ,但按原样编写,代码无法正常工作。 BUT after a little modification, see below, I now have things in working order again. 但经过一点修改,见下文,我现在又恢复正常工作了。

To use the new piece of code one needs to change the source URL for ones calendar to the form: 要使用新的代码,需要将某个日历的源URL更改为表单:

https://www.googleapis.com/calendar/v3/calendars/CALENDAR-ID/events?key=API-KEY https://www.googleapis.com/calendar/v3/calendars/CALENDAR-ID/events?key=API-KEY

Insert your own calendar id and public API key into the URL as indicated. 如图所示,将您自己的日历ID和公共API密钥插入到URL中。 Your API-KEY can be obtained by setting up a project inside your Google Developers Console and then creating a public access API browser key. 您可以通过在Google Developers Console中设置项目,然后创建公共访问API浏览器密钥来获取API-KEY。

Here is the actual code one needs to use in place of ones in the current gcal.js file. 以下是当前gcal.js文件中需要使用的实际代码。

(function(factory) {
    if (typeof define === 'function' && define.amd) {
        define([ 'jquery' ], factory);
    } else {
        factory(jQuery);
    }
})
(function($) {


    var fc = $.fullCalendar;
    var applyAll = fc.applyAll;

    fc.sourceNormalizers.push(function(sourceOptions) {
        if (sourceOptions.dataType == 'gcalv3'
        || (sourceOptions.dataType === undefined
            && (sourceOptions.url || '').match(/^(http|https):\/\/www.googleapis.com\/calendar\/v3\/calendars\//))) {
                sourceOptions.dataType = 'gcalv3';
                if (sourceOptions.editable === undefined) {
                    sourceOptions.editable = false;
            }
        }
    });

    fc.sourceFetchers.push(function(sourceOptions, start, end, timezone) {
        if (sourceOptions.dataType == 'gcalv3') {
            return transformOptionsV3(sourceOptions, start, end, timezone);
        }
    });

    function transformOptionsV3(sourceOptions, start, end, timezone) {

        var success = sourceOptions.success;
        var data = $.extend({}, sourceOptions.data || {}, {
            singleevents: true,
            'max-results': 9999
        });

        return $.extend({}, sourceOptions, {
            url: sourceOptions.url,
            dataType: 'json',
            data: data,
            startParam: 'start-min',
            endParam: 'start-max',
            success: function(data) {
                var events = [];
                if (data.items) {
                    $.each(data.items, function(i, entry) {
                        events.push({
                            id: entry.id,
                            title: entry.summary || '', // must allow default to blank, if it's not set it doesn't exist in the json and will error here
                            start: entry.start.dateTime || entry.start.date,
                            end: entry.end.dateTime || entry.start.date,  // because end.date may be the next day, cause a '2-all-day' event, we use start.date here.
                            url: entry.htmlLink,
                            location: entry.location || '', // must allow default to blank, if it's not set it doesn't exist in the json and will error here
                            description: entry.description || '' // must allow default to blank, if it's not set it doesn't exist in the json and will error here
                        });

                    });
                }
                var args = [events].concat(Array.prototype.slice.call(arguments, 1));
                var res = applyAll(success, this, args);
                if ($.isArray(res)) {
                    return res;
                }
                return events;
            }
        });

    }
});

Here's the fix everyone: 这是每个人的修复:

https://github.com/jonnyhweiss/fullcalendar/commit/520022a4da81ded61f3a1cc7020df4df54726fbc?diff=split https://github.com/jonnyhweiss/fullcalendar/commit/520022a4da81ded61f3a1cc7020df4df54726fbc?diff=split

It requires editing of gcal.js and gcal.html to get the demo's working; 它需要编辑gcal.js和gcal.html以使演示工作; from those demos you should be able to fix your own broken calendars, hopefully ; 从那些演示中,你应该能够修复自己破碎的日历,希望如此; )

Please note: 请注意:

Requires Full-Calendar 2.2.0 需要完整日历2.2.0

I quickly discovered it will not work on Full Calendar 1.xx, or if it will, I'm not code savvy enough to figure it out. 我很快发现它不能在完整日历1.xx上运行,或者如果它会,我不够精通代码,不能弄明白。 Full Calendar 2.2.0 adds moment.js as a dependent JS link, which is not a part of Full Calendar 1.xx, so copy and pasting what is available on the link above into your Full Calendar 1.xx files will not work. 完整日历2.2.0将moment.js添加为依赖JS链接,这不是完整日历1.xx的一部分,因此将上面链接上可用的内容复制并粘贴到完整日历1.xx文件中将不起作用。

Happy coding and fixing your Google Calendars! 快乐编码和修复您的Google日历!

To fix comment out the Google Holiday feed if you are using it. 如果您正在使用它,请修复Google Holiday Feed中的注释。 That fixed it for us. 这为我们解决了。 Evidently they are having feed issues. 显然他们有饲料问题。 That is the only feed from Google I use, so other Google feeds may be impacted also. 这是我使用的Google提供的唯一Feed,因此其他Google Feed也可能会受到影响。

API的第2版今天已弃用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM