Retrieve the events from a SharePoint calendar using REST API - rest

I have the rest endpoint for accessing the sharepoint calendar from my internal network at work. It looks like this:
https://teamsites.{COMPANY}.com/sites/{SITE_URI}/_api/Web/Lists/getbytitle({TITLE-OF-CALENDAR})/items
When I do an authorized GET request to the above url, it gives me a list of 4 events from the calendar, but the dates are kind of random. What is the endpoint I need to specify in order to retrieve all of the events for the current month?
Also, I'm guessing that the reason I'm only getting 4 events per request is because of some pagination thing that I'm not handling... if you know how to retrieve all the events in one request, that would be a bonus.
Thanks in advance!

The events for a current month could be retrieved via the following CAML query:
<Where>
<DateRangesOverlap>
<FieldRef Name='EventDate' />
<FieldRef Name='EndDate' />
<Value Type='DateTime'>
<Month />
</Value>
</DateRangesOverlap>
</Where>
For that matter GetItems method could be utilized as demonstrated below:
var query = `
<Where>
<DateRangesOverlap>
<FieldRef Name='EventDate' />
<FieldRef Name='EndDate' />
<Value Type='DateTime'>
<Month />
</Value>
</DateRangesOverlap>
</Where>`
getListItems(_spPageContextInfo.webAbsoluteUrl,'TeamCalendar',query)
.done(function(data){
var items = data.d.results;
for(var i = 0; i < items.length;i++) {
console.log(items[i].Title);
}
})
.fail(function(error){
console.log(JSON.stringify(error));
});
where
function getListItems(webUrl,listTitle, queryText)
{
var viewXml = '<View><Query>' + queryText + '</Query></View>';
var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/getitems";
var queryPayload = {
'query' : {
'__metadata': { 'type': 'SP.CamlQuery' },
'ViewXml' : viewXml
}
};
return $.ajax({
url: url,
method: "POST",
data: JSON.stringify(queryPayload),
headers: {
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"Accept": "application/json; odata=verbose",
"content-type": "application/json; odata=verbose"
}
});
}
But there is one limitation with this approach, neither REST nor CSOM/JSOM APIs do not support expanding for recurring events (it means only a single event item will be returned for a recurring event). Refer those requests for a more details:
Provide CSOM and REST API for recurring calendar events
Add support for recurring events in the REST API
For that scenario legacy SharePoint Web Services comes to the rescue, in particular Lists Web Service.
The following example demonstrates how to retrieve events for a current month and expand recurring events (SPServices library is utilized here):
$().SPServices({
operation: "GetListItems",
async: false,
listName: "TeamCal",
CAMLViewFields: "<ViewFields>" +
"<FieldRef Name='Title' />" +
"<FieldRef Name='EventDate' />" +
"<FieldRef Name='EndDate' />" +
"<FieldRef Name='Location' />" +
"<FieldRef Name='Description' />" +
"<FieldRef Name='fRecurrence' />" +
"<FieldRef Name='RecurrenceData' />" +
"<FieldRef Name='fAllDayEvent' />" +
"</ViewFields>",
CAMLQuery: "<Query>" +
"<Where>" +
"<DateRangesOverlap>" +
"<FieldRef Name='EventDate' />" +
"<FieldRef Name='EndDate' />" +
"<FieldRef Name='RecurrenceID' />" +
"<Value Type='DateTime'>" +
"<Month />" +
"</Value>" +
"</DateRangesOverlap>" +
"</Where>" +
"<OrderBy>" +
"<FieldRef Name='EventDate' />" +
"</OrderBy>" +
"</Query>",
CAMLQueryOptions: "<QueryOptions>" +
"<RecurrencePatternXMLVersion>v3</RecurrencePatternXMLVersion>" +
"<ExpandRecurrence>TRUE</ExpandRecurrence>" +
"</QueryOptions>",
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode("z:row").each(function() {
var $node = $(this);
var eventTitle = $node.attr("ows_Title");
console.log(eventTitle);
});
}
})

Related

its possible consume a spring boot api rest from JSF?

I try execute a ajax query from the xhtml file, and its trows error :
Uncaught SyntaxError: Invalid or unexpected token
This is my ajax query:
<h:form>
<script type="text/javascript">
llamadaNombre();
function llamadaNombre(){
var list2=null;
$.ajax({
type : "GET",
url : "localhost:8080/users",
dataType: "json",
data: {val: list2},
success : function(result) {
$('#tablebody').html("");
$.each(result,function(key, val) {
editar="<h:commandLink action='/paginas/crud/editarCliente?dni="+val.dni+"' class='btn btn-success'> <span class='glyphicon glyphicon-search'></span> editar </h:commandLink>" ;
eliminar="<h:commandLink action='/paginas/crud//eliminarCliente?id="+val.dni+"' class='btn btn-success'> <span class='glyphicon glyphicon-trash'></span> eliminar </h:commandLink>";
var htmlrow ="<tr>"+"<td>" + val.id + "</td>"+"<td>" + val.nombre + "</td>"+"<td>" + val.apellidos + "</td>"+"<td>" + val.dni + "</td>"+"<td>" + val.correo + "</td>"+"<td>" + val.telefono + "</td>"+"<td>" + val.direccion + "</td>"+"<td>" + val.cp + "</td>"+"<td>" + val.edad + "</td>"+"<td>" + editar + "</td>"+"<td>" + eliminar + "</td>"+"</tr>";
$('#tablebody').append(htmlrow);
})
}
})
}
</script>
</h:form>
the format of data in the api rest is json
There are any way for connect api in springBoot and JSF application ? its throw the error:
jquery.min.js:2 Access to XMLHttpRequest at `'htttp://localhost:8080/users?val=' from origin 'http://localhost:9090' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.`
i Try change the port in diferents enviorments but its keep returning that error and if configure in the same port trows error that this ports its listening
this is my API controlller:(solved)
#Service
#CrossOrigin(origins = "http://localhost:8080")
public class UsuariosController {
public List<Clientes> getAll(){
return clientesFacade.getAllClientes();
}
You should add the headers param to your request as a bellow script :
$.ajax({
type : "GET",
url : "localhost:8090/users",
data: {val: list2},
headers: {
"X-Requested-With": "XMLHttpRequest",
"Authorization": .......,
},
success: function (data, text) {
console.log(data);
},
........
in your java controller, you should authorize to access from localhost in your case, you can just add the annotation : #crossorigin(origins = "localhost" ) to your service.

Ignoring blank email address input field Google Apps Script

I have an HTML form which contains email addresses from various suppliers. I am creating a kind of mail merge function so I can send all the contacts a personalised email when the form is submitted. Here is my .gs file:
function sendEmail(form) {
const sSheet = SpreadsheetApp.getActiveSpreadsheet();
const file = DriveApp.getFileById(sSheet.getId());
const documentUrl = file.getUrl();
/* var toEmail = form.toAddress;
var ccEmail = form.ccAddress;
var fromEmail = "****#*****.com";
var subject = form.subject;
var message = form.message; */
var toEmail = "";
var fromEmail = "****#*****.com";
var message = "";
var hotelAddresses = [
form.toAddress1,
form.toAddress2,
form.toAddress3,
form.toAddress4,
form.toAddress5,
form.toAddress6,
form.toAddress7,
form.toAddress8,
form.toAddress9,
form.toAddress10,
form.toAddress11,
form.toAddress12,
form.toAddress13,
form.toAddress14,
form.toAddress15,
form.toAddress16,
form.toAddress17,
form.toAddress18,
form.toAddress19,
form.toAddress20,
form.toAddress21,
form.toAddress22,
form.toAddress23,
form.toAddress24,
form.toAddress25,
form.toAddress26,
form.toAddress27,
form.toAddress28,
form.toAddress29,
form.toAddress30,
form.toAddress31,
form.toAddress32,
form.toAddress33,
];
var contactNames = [
form.contactName1,
form.contactName2,
form.contactName3,
form.contactName4,
form.contactName5,
form.contactName6,
form.contactName7,
form.contactName8,
form.contactName9,
form.contactName10,
form.contactName11,
form.contactName12,
form.contactName13,
form.contactName14,
form.contactName15,
form.contactName16,
form.contactName17,
form.contactName18,
form.contactName19,
form.contactName20,
form.contactName21,
form.contactName22,
form.contactName23,
form.contactName24,
form.contactName25,
form.contactName26,
form.contactName27,
form.contactName28,
form.contactName29,
form.contactName30,
form.contactName31,
form.contactName32,
form.contactName33,
];
var days = [
form.day1,
form.day2,
form.day3,
form.day4,
form.day5,
form.day6,
form.day7,
form.day8,
form.day9,
form.day10,
form.day11,
form.day12,
form.day13,
form.day14,
form.day15,
form.day16,
form.day17,
form.day18,
form.day19,
form.day20,
form.day21,
form.day22,
form.day23,
form.day24,
form.day25,
form.day26,
form.day27,
form.day28,
form.day29,
form.day30,
form.day31,
form.day32,
form.day33,
];
var dates = [
form.date1,
form.date2,
form.date3,
form.date4,
form.date5,
form.date6,
form.date7,
form.date8,
form.date9,
form.date10,
form.date11,
form.date12,
form.date13,
form.date14,
form.date15,
form.date16,
form.date17,
form.date18,
form.date19,
form.date20,
form.date21,
form.date22,
form.date23,
form.date24,
form.date25,
form.date26,
form.date27,
form.date28,
form.date29,
form.date30,
form.date31,
form.date32,
form.date33,
];
var times = [
form.time1,
form.time2,
form.time3,
form.time4,
form.time5,
form.time6,
form.time7,
form.time8,
form.time9,
form.time10,
form.time11,
form.time12,
form.time13,
form.time14,
form.time15,
form.time16,
form.time17,
form.time18,
form.time19,
form.time20,
form.time21,
form.time22,
form.time23,
form.time24,
form.time25,
form.time26,
form.time27,
form.time28,
form.time29,
form.time30,
form.time31,
form.time32,
form.time33,
];
var additionalInfo = [
form.additional1,
form.additional2,
form.additional3,
form.additional4,
form.additional5,
form.additional6,
form.additional7,
form.additional8,
form.additional9,
form.additional10,
form.additional11,
form.additional12,
form.additional3,
form.additional14,
form.additional15,
form.additional16,
form.additional17,
form.additional18,
form.additional19,
form.additional20,
form.additional21,
form.additional22,
form.additional23,
form.additional24,
form.additional25,
form.additional26,
form.additional27,
form.additional28,
form.additional29,
form.additional30,
form.additional31,
form.additional32,
form.additional33,
];
for(var i = 0; i<times.length; i++){
var subject = "Meeting - " + days[i] + ", " + dates[i] + " at " + times[i];
toEmail = hotelAddresses[i];
message = "Dear " + contactNames[i] + ","
+"<br><br>"+
"Please confirm the meeting on " + days[i] + " " + dates[i] + " at " + times[i] + "." + "<br>" + "<br>" +
additionalInfo[i] +
" If you could kindly let me know if you are able to confirm that would be great." + "<br>" + "<br>" +
"Many thanks and I look forward to hearing from you soon." + "<br>" + "<br>" +
"Yours sincerely," + "<br>" + "<br>" +
form.yourName + "<br>" + "<br>"
+ "<em><b>" + form.yourPosition + "</b></em> <br><br>" +
"<span style='color:#0e216d'><b> Company name. </b>" + "<br>" +
GmailApp.sendEmail(
toEmail, // recipient
subject, // subject
'test', { // body
htmlBody: message // advanced options
}
);
}
}
It works fine except that sometimes the input fields for email will be blank, in which case I need the script to ignore that supplier and continue to run. At the moment it is obviously hitting the empty input and stopping the execution.
I presume I need a conditional statement of sorts... something along the lines of if(hotelAddresses[i] != null) {}
But I cannot work out where to insert this...
Additional: 31 Aug 18
For the HTML I have a series of objects (33 in total) that are all set up like this:
<input type="checkbox" id="check1" class="check" checked>
<input type="text" id="name1" class="contactNameInput" name="toAddress1">
<input type="text" id="contactName1" class="contactNameInput mailName" name="contactName1">
<input type="text" id="time1" class="contactNameInput hidden mailTime" name="time1">
<input type="text" id="day1" class="contactNameInput hidden mailDay" name="day1">
<input type="text" id="date1" class="contactNameInput hidden mailDate" name="date1">
<textarea class="additional contactNameInput" id="additional1" name="additional1" placeholder="Additional requests..."></textarea>
<div class="preview1"></div>
You want to separate the cases with and without hotelAddresses[i] using a script like if(hotelAddresses[i] != null) {}. When my understanding is correct, how about this modification?
Modification points:
Do you want to add after "<span style='color:#0e216d'><b> Company name. </b>" + "<br>" +? In the current script, it's "<span style='color:#0e216d'><b> Company name. </b>" + "<br>" + GmailApp.sendEmail(...). If you want to add more strings, please put them. If you don't want to add, please remove the last +.
I think that the script of if(hotelAddresses[i] != null) {} can be used in the for loop.
The script which reflected above is as follows.
Modified script:
In this modified script, the script of for loop was modified.
for(var i = 0; i<times.length; i++) {
var toEmail = hotelAddresses[i];
if (toEmail) {
var subject = "subject";
var message = "messages";
GmailApp.sendEmail(toEmail, subject, 'test', {htmlBody: message});
} else {
// do something
}
}
Note:
In this modified script, subject and message are replaced by "subject" and "messages", respectively. So please modify them for your situation.
If you want to do something when hotelAddresses[i] is null, please modify // do something.
If you don't want to do something when hotelAddresses[i] is null, please remove else {}.
If I misunderstand your question, please tell me. I would like to modify it.

Batch updating several items using REST API in SharePoint Online

Please provide a working solution for this, I'm getting 400 bad request error when doing a batch update. I tried Andrew Cornell's blog post in this regard. But couldn't get it to work yet. Below is the code I tried.
// create the changeset
batchContents.push('--changeset_' + changeSetId);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('POST ' + webUrl + '(' + itemProperties[i].Id + ')' + ' HTTP/1.1'); //+ '(' +itemProperties[i].Id + ')'
batchContents.push('Content-Type: application/json;odata=verbose');
batchContents.push('Accept: application/json;odata=verbose');
batchContents.push('If-Match: ' + itemProperties[i].__metadata.etag);
//batchContents.push('X-HTTP-Method:' + 'MERGE');
batchContents.push('X-RequestDigest:' + $("#__REQUESTDIGEST").val());
batchContents.push('');
batchContents.push(JSON.stringify(itemUpdater));
batchContents.push('');
}
// END changeset to create data
batchContents.push('--changeset_' + changeSetId + '--');
// generate the body of the batch
var batchBody = batchContents.join('\r\n');
// start with a clean array
batchContents = new Array();
// create batch for creating items
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' + changeSetId + '"');
batchContents.push('Content-Length: ' + batchBody.length);
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push(batchBody);
batchContents.push('');
//bath end
batchContents.push('--batch_' + batchGuid);
batchBody = batchContents.join('\r\n');
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/$batch';
// batches need a specific header
var batchRequestHeader = {
'X-RequestDigest': jQuery("#__REQUESTDIGEST").val(),
'Content-Type': 'multipart/mixed; boundary="batch_' + batchGuid + '"'
};
url: endpointUri,
type: 'POST',
async: false,
headers: batchRequestHeader,
data: batchBody,
refered : part 1
part 2

Load selected data using $(this).append(data) inside live

I use the following code to dynamically add input fields to form, based on this source:
http://www.infotuts.com/dynamically-add-input-fields-to-form-jquery/
Here's a part of my code:
$(document).ready(function(){
var counter = 2;
$("#btnAddIngredients").click(function () {
var newIngredientsData = $(document.createElement('div'))
.attr("id", 'ingredientsData' + counter);
newIngredientsData.html('<div id="ingredientsData'+ counter + '" class="row">' +
'<div class="col-ingredients">#'+ counter + ' : <select id="ingredient'+ counter + '" name="ingredient'+ counter + '" class="selectIngredients"><select/></div>' +
'<div class="col-extra"><input type="text" name="extra'+ counter + '" id="extra'+ counter + '" size="30" maxlength="100" /></div>' +
'<div class="col-quantity"><input type="text" name="quantity'+ counter + '" id="quantity'+ counter + '" size="5" maxlength="30" /></div>' +
'<div class="col-unit"><select id="unit'+ counter + '" name="unit'+ counter + '" class="selectUnit"><select/></div>'+
'</div>');
newIngredientsData.appendTo("#ingredientsList");
counter++;
});
$(".selectIngredients").live("click",function () {
$(this).empty();
$(this).append('<option value="">Loading...</option>');
$.post("getdata.php", {what: "ingredients"},
function (data){
alert(data);
$(this).append(data);
}
,"html");
});
});
What i'm expecting is for the selected value to be populated every time I click on it But the only thing that appeared is "<option value="">Loading...</option>", which I appended first. It seems $(this).append(data) didn't do it's job. nothing is being appended. The alert(data) above it correctly displays the contents that should be appended.
If I change $(this).append(data); to $("#ingredients1").append(data); for example, the select data is loaded correctly, but not when I use $(this).append(data);
What's wrong here? Why do the appends; in the function (data){} doesn't work, while the preceding $(this).append('<option value="">Loading...</option>'); works correctly every time?
this isn't referring to the same element inside of the post closure, use a context variable:
var that = $(this);
$.post("getdata.php", {what: "ingredients"}, function (data) {
alert(data);
that.append(data);
});
$(this) in your ajax response is the window, not the <select>.
You can use the "context" setting for ajax http://api.jquery.com/jQuery.ajax/ ... and it transfer "this" to the success scope

Workflow for Google Apps script approving correct row via email

I am creating a workflow process with Google Apps script. I have looked at this video for most of the layout.
I built a form in Google Apps script that takes input data from a user. The data is then submitted into rows with e.parameter values. That data is then emailed to an approver. The approver has an approve button that they press to change the "Status" column to approved.
Issue:
I cant get the data to approve the correct row. I am passing a row parameter that is supposed to correspond to the correct row but it isnt working.
Here is my code that submits data to the spreadsheet and once the data has been approved via email. The DoPost function runs and approves the row. Can someone Please help! I've been trying to find solutions all day.
function sendEmail_(e) {
var sheet = SpreadsheetApp.openById("0AuCblud0Ss7BdHA1bXZjYXA0Y0IyekhUQm5vWG02MVE").getActiveSheet();
var range = sheet.getRange(sheet.getLastRow() + 1, 1, 1, 13);
range.setValues([
[e.parameter.LastName, e.parameter.FirstName, e.parameter.DivisionName, e.parameter.EffectiveDate,
e.parameter.Network, e.parameter.EmployeeNewPosition, e.parameter.DivisionFolder, e.parameter.SpecificIndividual,
e.parameter.Email, e.parameter.username, e.parameter.who, e.parameter.Banner, "Unapproved"]
]);
var row = sheet.getLastRow() + 1;
//"https://script.google.com/a/macros/wichitafallstx.gov/s/AKfycbwOgTTGqNsVwnqs-xfqa7TEJWGc_lJZdoyoEoixngKdDemVQuo/exec
var body = '<form action= <form action = " https://sites.google.com/a/macros/wichitafallstx.gov/s/AKfycbxAOGO6q9ofauf34xlDA9sLG8sUXeZsuvQkDKATOQ/exec" method ="post">' +
"<b>Last Name:</b>" + e.parameter.LastName + '<br><br>' +
"<b>First Name:</b>" + e.parameter.FirstName + '<br><br>' +
"<b>Division Name:</b>" + e.parameter.DivisionName + '<br><br>' +
"<b>Effective Date:</b>" + e.parameter.EffectiveDate + '<br><br>' +
"<b>Network:</b>" + e.parameter.Network + '<br><br>' +
"<b>Employee New Position:</b>" + e.parameter.EmployeeNewPosition + '<br><br>' +
"<b>Division Folder:</b>" + e.parameter.DivisionFolder + '<br><br>' +
"<b>Specific Individual:</b>" + e.parameter.SpecificIndividual + '<br><br>' +
"<b>Email:</b>" + e.parameter.Email + '<br><br>' +
"<b>Username:</b>" + e.parameter.username + '<br><br>' +
"<b>who:</b>" + e.parameter.who + '<br><br>' +
"<b>Banner:</b>" + e.parameter.Banner +
'<br />' +
'<br />' +
'<input type="hidden" name="row" value=" ' + row + ' "/>' +
'<input type="submit" value="Approve" onclick="approve()" />' +
'</form>';
var owners = SitesApp.getSite("wichitafallstx.gov", "information-systems").getOwners();
var mail = MailApp.sendEmail(owners.join(","), "test", '', {
htmlBody: body
});
}
//handles the payload that is posted back to appscript..from the form that is passed from the form created in send email.
function doPost(e) {
var r = e.parameter["row"];
var sheet = SpreadsheetApp.openById("0AuCblud0Ss7BdHA1bXZjYXA0Y0IyekhUQm5vWG02MVE").getActiveSheet();
var values = sheet.getRange(r, 1, 1, 13).getValues();
sheet.getRange(r, 13).setValue("Approved");
}
I am passing a row parameter that is supposed to correspond to the correct row but it isnt working.
It appears that you are passing the row below the one intended.
var range = sheet.getRange(sheet.getLastRow() + 1, 1, 1, 13);
range.setValues([
[e.parameter.LastName, e.parameter.FirstName, e.parameter.DivisionName, e.parameter.EffectiveDate,
e.parameter.Network, e.parameter.EmployeeNewPosition, e.parameter.DivisionFolder, e.parameter.SpecificIndividual,
e.parameter.Email, e.parameter.username, e.parameter.who, e.parameter.Banner, "Unapproved"]
]);
// In assignment below 'new' lastRow is the row you just filled
// in with above and should not include + 1
var row = sheet.getLastRow() // no + 1;