我正在尝试从 SharePoint 网站获取事件,并使用 Josh McCarty在此处描述的方法将它们插入到FullCalendar中。
使用 Josh 文章中的片段成功显示了一个空日历,但是在查询 SharePoint 中的事件列表时似乎出现了错误。我正在对他的示例进行轻微修改,因为我的列表在主机网站中,而不是应用程序中,所以我必须使用 webURL 参数。
当我查看 Chrome 开发控制台时,我将“请求格式无法识别”视为错误。
该技术使用 SPServices 和 Caml 查询来获取事件,但我怀疑我的 Caml 有问题。
我的代码(下面)几乎是示例中的逐字记录,但在我标记的行处或附近出现错误debugger; //REQUEST FORMAT IS UNRECOGNIZED occurs here.
// Add events to the calendar. This is where the "magic" happens!
events: function( start, end, callback ) {
// Create an array to hold the events.
var events = [];
// Set the date from which to pull events based on the first visible day in the current calendar view.
// For a month view, this will usually be several days into the previous month.
// We can use FullCalendar's built-in getView method along with the formatDate utility
// function to create a date string in the format that SharePoint requires.
// It must be in the format YYYY-MM-DDTHH:MM:SSZ. Due to time zone differences,
// we will omit everything after the day.
var startDate = $.fullCalendar.formatDate( $( '#calendar' ).fullCalendar( 'getView' ).start, "u" ).split( "T" )[0];
// Get the current view of the calendar (agendaWeek, agendaDay, month, etc.).
// Then set the camlView to the appropriate value to pass to the web service.
// This way we will only retrieve events needed by the current view
// (e.g. the agendaWeek view will only retrieve events during the current week rather
// than getting all events for the current month).
var calView = $( '#calendar' ).fullCalendar( 'getView' ).title;
var camlView = "";
switch( calView ) {
case "agendaWeek":
camlView = "<Week />";
break;
case "agendaDay":
camlView = "<Week />";
break;
default: // Default to month view
camlView = "<Month />";
}
// Set the camlFields, camlQuery, and camlOptions to the appropriate values to pass to the web service.
// You can add additional <ViewFields /> or adjust the CAML query if you have some custom columns that
// you want to filter by or display data from. The values below are the pretty much the minimum you'll
// want to start from to get it working.
var camlFields = "<ViewFields><FieldRef Name='Title' /><FieldRef Name='EventDate' /><FieldRef Name='EndDate' /><FieldRef Name='Location' /><FieldRef Name='Description' /><FieldRef Name='fRecurrence' /><FieldRef Name='RecurrenceData' /><FieldRef Name='RecurrenceID' /><FieldRef Name='fAllDayEvent' /></ViewFields>";
var camlQuery = "<Query><CalendarDate>" + startDate + "</CalendarDate><Where><DateRangesOverlap><FieldRef Name='EventDate' /><FieldRef Name='EndDate' /><FieldRef Name='RecurrenceID' /><Value Type='DateTime'>" + camlView + "</Value></DateRangesOverlap></Where><OrderBy><FieldRef Name='EventDate' /></OrderBy></Query>";
var camlOptions = "<QueryOptions><CalendarDate>" + startDate + "</CalendarDate><RecurrencePatternXMLVersion>v3</RecurrencePatternXMLVersion><ExpandRecurrence>TRUE</ExpandRecurrence></QueryOptions>";
var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
debugger;
// Make the web service call to retrieve events.
$().SPServices({
operation: "GetListItems",
async: false,
webURL: hostUrl,
listName: paidTimeOffListName, // This is the GUID or display name of your calendar. If the calendar is on a different site, you can use the display name with the webURL option (see SPServices.CodePlex.com for more information).
CAMLViewFields: camlFields,
CAMLQuery: camlQuery,
CAMLQueryOptions: camlOptions,
completefunc: function( xData, Status )
{
debugger; //REQUEST FORMAT IS UNRECOGNIZED occurs here.
//.find( '[nodeName="z:row"]' ) unsupported past jQuery 1.7
$(xData.responseXML).SPFilterNode('z:row').each( function()
{
debugger;
// Check for all day events
var fADE = $( this ).attr( 'ows_fAllDayEvent' );
var thisADE = false;
var thisStart = $( this ).attr( 'ows_EventDate' );
var thisEnd = $( this ).attr( 'ows_EndDate' );
if ( typeof fADE !== "undefined" && fADE !== "0" )
{
thisADE = true;
}
// Get the list item ID and recurrence date if present. This will be used to generate the ID query string parameter to link to the event (or the specific instance of a recurring event). The ID query string parameter must be in the format "ID.0.yyyy-MM-ddTHH:mm:ssZ" for recurring events (where "ID" is the list item ID for the event). Event ID's are returned as just a number (for non-recurring events) or several numbers separated by ";#" in 2007 or "." in 2010 to indicate individual instances of recurring events. By splitting and joining the ID this way, thisID will be set to a valid query string parameter whether an event is recurring or not for both versions of SharePoint.
var thisID = $( this ).attr( 'ows_ID' ).split( ';#' ).join( '.' );
// FullCalendar documentation specifies that recurring events should all have the same id value when building the events array (the id is optional, but I'm including it for completeness). We can get the list item ID (which is the same for all instances of recurring events) without the recurrence information by simply splitting thisID.
var eventID = thisID.split( '.' )[0];
// Get the event title. This is displayed on the calendar along with the start time of the event.
var thisTitle = $( this ).attr( 'ows_Title' );
// Get the event description. I don't use it in this example, but you could use it for something, perhaps as a tooltip when hovering over the event.
var thisDesc = $( this ).attr( 'ows_Description' );
// Add the event information to the events array so FullCalendar can display it.
events.push({
title: thisTitle,
id: eventID,
start: thisStart,
end: thisEnd,
allDay: thisADE,
// Adjust this URL to link to the display form for your calendar events. You can include a Source parameter to allow users to easily return to the FullCalendar page.
url: '/Lists/Calendar/DispForm.aspx?ID=' + thisID + '&Source=' + window.location,
description: thisDesc
});
});
callback( events );
}
});
}