问题
I have a SharePoint calendar list, and I'm looking for a script to retrieve the number of events on a day. For example, for today, 10 August, I want to just retrieve the number of events stored in my calendar.
Any suggestion will be very helpful.
回答1:
The Problem with Querying Calendars in JavaScript: Recurrence
Ordinarily retrieving data from SharePoint with JavaScript is really straightforward (at least for versions beyond SharePoint 2007) using either REST or the JavaScript Object Model. However, calendars have functionality for creating recurring events which can complicate things.
For example, a recurring event may have a start date of two years ago and an end date many years in the future, but maybe the event itself only actually occurs on the third Tuesday of every month. If you just query the list and try to compare today's date against the start date and end date to see if they overlap, that recurring event will show up in your results (even though today is not the third Tuesday of the month).
In server-side code you can get around this by setting the ExpandRecurrence property to true on the SPQuery object used to query the list. However, as of SP2010 and SP2013, that property is not exposed on the equivalent JavaScript Object Model.
Workaround: Using the Lists.GetListItems web service**
An alternative is to use one of the old web services that are still floating around... specifically the Lists web service accessible at /_vti_bin/Lists.asmx
. This web service has a GetListItems
method that accepts a SOAP message in which you can specify a query option to expand recurrence as you would on the server side.
Here's an example demonstrating how you can query the Lists web service using plain JavaScript:
// Set webUrl and listGuid to values specific to your site and list
var webUrl = "http://server/sitewhereyourlistexists";
var listGuid = "{000000000-0000-0000-0000-000000000000}"
// An XMLHttpRequest object is used to access the web service
var xhr = new XMLHttpRequest();
var url = webUrl + "/_vti_bin/Lists.asmx";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type","text/xml; charset=utf-8");
xhr.setRequestHeader("SOAPAction","http://schemas.microsoft.com/sharepoint/soap/GetListItems");
// The message body consists of an XML document
// with SOAP elements corresponding to the GetListItems method parameters
// i.e. listName, query, and queryOptions
var data = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soap:Body>" +
"<GetListItems xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\">" +
"<listName>"+listGuid+"</listName>" +
"<query>" +
"<Query><Where>" +
"<DateRangesOverlap>" +
"<FieldRef Name=\"EventDate\"/>"+
"<FieldRef Name=\"EndDate\"/>"+
"<FieldRef Name=\"RecurrenceID\"/>"+
"<Value Type=\"DateTime\"><Today/></Value>"+
"</DateRangesOverlap>"+
"</Where></Query>"+
"</query>" +
"<queryOptions>"+
"<QueryOptions>"+
"<ExpandRecurrence>TRUE</ExpandRecurrence>"+
"</QueryOptions>"+
"</queryOptions>" +
"</GetListItems>" +
"</soap:Body>" +
"</soap:Envelope>";
// Here we define what code we want to run upon successfully getting the results
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
var doc = xhr.responseXML;
// grab all the "row" elements from the XML results
var rows = doc.getElementsByTagName("z:row");
var results = "Today's Schedule ("+rows.length+"):\n\n";
var events = {};
for(var i = 0, len = rows.length; i < len; i++){
var id = rows[i].getAttribute("ows_FSObjType"); // prevent duplicates from appearing in results
if(!events[id]){
events[id] = true;
var allDay = rows[i].getAttribute("ows_fAllDayEvent"),
title = rows[i].getAttribute("ows_Title"),
start = rows[i].getAttribute("ows_EventDate");
var index = start.indexOf(" ");
var date = start.substring(5,index)+"-"+start.substring(2,4); // get the date in MM-dd-yyyy format
start = start.substring(index, index+6); // get the start time in hh:mm format
var end = rows[i].getAttribute("ows_EndDate");
index = end.indexOf(" "); end = end.substring(index,index+6); // get the end time in hh:mm format
results += date + " " + (allDay == "1" ? "All Day\t" : start + " to " + end ) + " \t " + title + "\n";
}
}
alert(results);
}else{
alert("Error "+xhr.status);
}
}
};
// Finally, we actually kick off the query
xhr.send(data);
Checking ranges other than today's date
In the <Value>
child node of the <DateRangesOverlap>
node, you can specify <Now />
, <Today />
, <Week />
, <Month />
, or <Year />
.
Week, Month, and Year will check for events within the same week, month, or year of the current date.
To check a date range relative to some date other than today's, you can add a <CalendarDate>
node to the <QueryOptions>
node of the CAML query, as seen below.
"<query>" +
"<Query><Where>" +
"<DateRangesOverlap>" +
"<FieldRef Name=\"EventDate\"/>"+
"<FieldRef Name=\"EndDate\"/>"+
"<FieldRef Name=\"RecurrenceID\"/>"+
"<Value Type=\"DateTime\"><Week /></Value>"+
"</DateRangesOverlap>"+
"</Where></Query>"+
"</query>" +
"<queryOptions>"+
"<QueryOptions>"+
"<ExpandRecurrence>TRUE</ExpandRecurrence>"+
"<CalendarDate>2017-03-10</CalendarDate>" +
"</QueryOptions>"+
"</queryOptions>" +
Note that values of <Now />
and <Year />
do not seem to respect the CalendarDate
value.
来源:https://stackoverflow.com/questions/38876519/retrieve-events-number-from-sharepoint-calendar-using-js