1

I'm trying to use SPServices UpdateListItems() to submit events to a custom calendar list.

I can submit normal events correctly but recurring events don't save properly.

 $().SPServices({
            operation: "UpdateListItems",
            async: false,
            batchCmd: command,
            listName: "Events",
            valuepairs: [["Title", $scope.event.title],
                ["EventDate", moment.utc($scope.event.startDate + $scope.event.startTime, "MM-DD-YYYYh:mm A").toISOString()],
                ["EndDate", moment.utc($scope.event.stopDate + $scope.event.stopTime, "MM-DD-YYYYh:mm A").toISOString()],
                ["Location", $scope.event.location ? $scope.event.location.location : ""],
                ["CTPEventInstructor", $scope.event.instructor ? $scope.event.instructor.name : ""],
                ["Description", $scope.event.description ? $scope.event.description : ""],
                ["Category", categorySubmit ? categorySubmit : ""],
                ["EventAllowRegistration", $scope.event.registrationOpen],
                ["EventRegistrationLimit", $scope.event.limit],
                ["EventRegistrationEmail", $scope.event.registerEmail ? $scope.event.registerEmail : ""],
                ["EventWaitingListEmail", $scope.event.waitingEmail ? $scope.event.waitingEmail : ""],
                ["EventChangedEmail", $scope.event.changeEmail ? $scope.event.changeEmail : ""],
                ["EventDeletedEmail", $scope.event.deleteEmail ? $scope.event.deleteEmail : ""],
                ["RecurrenceData", $scope.recurData],
                ["fRecurrence", $scope.event.recurring ? 1 : 0]],
            ID: eventId,
            completefunc: function (xData, status) {     window.history.back(-1);
                }
                else {
                    alert("Unable to submit your request at this time.");
                }
            }});

This saves the event but not as recurring.

I'm sending recurrence as a string

"<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><daily dayFrequency="2" /></repeat><repeatInstances>10</repeatInstances></rule></recurrence>"

When I view the event I create on the list itself recurrence is listed as

Has anyone ever submitted Recurrence data with SPServices.

I'm also open to using REST API but am hesitant to because you can't retrieve recurrence data with that.

1

I decided to to do it with web SharePoint's Rest API for a few reasons.

  1. SPServices is being depreciated (Well SOAP is)
  2. It was much easier to debug. Using the /_api/ to look into events created by the actual SP Events list (as opposed to my app) was much easier to work with than SPServices.

In the end what I discovered was that I was missing several fields that are required to correctly write a recurring event.

UID, Recurrence, Timezone, and EventType.

UID is a GUID that I randomly generate and assign. Recurrence is always -1 for events that are recurring. Timezone is self explanatory. EventType is an important number.

For recurring events it's 1. This article is a decent guide to event types and the values associated with them.

I don't know if all of these fields are required but I know when I added all of them it worked. I am 99% positive that UID and EventType are required.

Here is the complete code below. Please note that I also refactored how some of the values are passed.

Another interesting sidenote. It wouldn't work with the angular $http I had to use jQuery.ajax().

$scope.createEventWithRecurrence = function () {

    var categorySubmit = $scope.event.category;
    //set a category value for submit to take the Other field in case Category is "Other"
    if (categorySubmit == "Other") {
        categorySubmit = $scope.event.categoryOther;
        //console.log(categorySubmit);
    }

    //create a string that has the events
    var stringStartDate = $scope.event.startDate + $scope.event.startTime;
    var stringEndDate = $scope.event.stopDate + $scope.event.stopTime;
    var reccurenceString = $scope.event.recurData;
    //console.log(reccurenceString);

    var startDate = moment(stringStartDate, "MM-DD-YYYYh:mm A").toISOString();
    var endDate = moment(stringEndDate, "MM-DD-YYYYh:mm A")/*.add($scope.recurMult, $scope.recurChange)*/.toISOString();
    var timeZone = moment(startDate).utcOffset;

    function guid() {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
              .toString(16)
              .substring(1);
        }
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
          s4() + '-' + s4() + s4() + s4();
    }
    var guid = guid();

    var recReq =
        {
        url: "../_api/web/lists/GetByTitle('Events')/items",
        type: "POST",
        data: JSON.stringify({
            '__metadata': {
                'type': 'SP.ListItem'
            },
            'Title': $scope.event.title,
            'EventDate': startDate,
            'EndDate': endDate,
            'Location': $scope.event.location ? $scope.event.location.location : '',
            'CTPEventInstructor': $scope.event.instructor ? $scope.event.instructor.name : '',
            'Description': $scope.event.description ? $scope.event.description : "",
            'Category': categorySubmit ? categorySubmit : "",
            'CTPEventAllowRegistration': $scope.event.registrationOpen,
            'CTPEventRegistrationLimit': $scope.event.limit,
            'CTPEventRegistrationEmail': $scope.event.registerEmail ? $scope.event.registerEmail : "",
            'CTPEventWaitingListEmail': $scope.event.waitingEmail ? $scope.event.waitingEmail : "",
            'CTPEventChangedEmail': $scope.event.changeEmail ? $scope.event.changeEmail : "",
            'CTPEventDeletedEmail': $scope.event.deleteEmail ? $scope.event.deleteEmail : "",
            'fRecurrence': true,
            'fAllDayEvent': $scope.event.allDay,
            'RecurrenceData': reccurenceString,
            'UID': guid,
            'Reccurence': -1,
            'TimeZone': timeZone,
            'EventType': 1,
        }),
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val()
        },
    };


    jQuery.ajax(recReq).success(function () {
        notify("Event data saved.");
        window.history.back(-1);
    }).error(function () {
        notify("Error occurred while saving question data.");
    });
};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.