Validate list item in REST - javascript

I have a function that will add list item using REST. But I want to validate a list item if its already exist on my list first before I add it. How will do it?
function addListItem() {
var title = $("#txtTitle").val();
var siteUrl = _spPageContextInfo.webAbsoluteUrl;
var fullUrl = siteUrl + "/_api/web/lists/GetByTitle('Employee')/items";
$.ajax({
url: fullUrl,
type: "POST",
data: JSON.stringify({
'__metadata': { 'type': 'SP.Data.EmployeeListItem' },
'EmployeeID': $("#txtEmpID").val(),
'Name': $("#txtName").val(),
}),
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: onQuerySucceeded,
error: onQueryFailed
});
function onQuerySucceeded(sender, args) {
alert("Item successfully added!");
}
function onQueryFailed() {
alert('Error!');
}
};

You can use the OData query operations in SharePoint REST requests
use the $filter parameter in a Get operation to validate if the user exists in the list, using something like this:
$filter=Name eq '<UserName>'
An example:
siteUrl + "/_api/web/lists/GetByTitle('Employee')/items?$filter=Name eq 'John'
< UserName > is the textbox value
You can see a Response sample here:
http://services.odata.org/Northwind/Northwind.svc/Customers?$filter=ContactName%20eq%20%27Maria%20Anders%27
Just do a Get request and count the elements to know if the user exists
$.get("/_api/web/lists/getbytitle('Employee')/items?$filter=Name eq '<Name>'",function(e){
if($(e).find("entry").length > 0){
console.log("user exists");
}
})
You can see a Complete basic operations using SharePoint 2013 REST endpoints using JQuery/Javascript here:
https://msdn.microsoft.com/en-us/library/office/jj164022.aspx

Related

POST Request to cycle through 8 different urls

I have been working on a project for quite some time now.
I have found this post somewhat useful, but am unsure if it is correct or not for my utilization.
Functionality:
Read in SharePoint list items from 8 different subsites with a GET request.
Populate those items in an orderly(grouped) fashion in a DataTable on a single landing page.
DataTable has collapsible/expandable rows grouped by program, followed by deliverable.
Dropdown menu with buttons to print/excel/PDF/Update the table.
Update Table has a HTML form that sends data back to the SharePoint List correlated with the FORM input.
I am currently using 8 different subsites where all of the lists are located. I want to send the new item to the correct list based off of its "Program" value because each of the different lists are a different program. I know I would have to use an if/else statement, but how would I go about that with an AJAX call?
Here is my JS "POST" Code:
$("#btn").click(function(e) {
PostItem();
});
});
function PostItem() {
return getFormDigest("https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/Lists/AMMODeliverables/").then(function(digestData) {
console.log(digestData.d.GetContextWebInformation.FormDigestValue);
var item = {
"__metadata": { "type": "SP.Data.AMMODeliverablesListItem" },
"Title": "updated title",
"Program": $("#dProgram").val(),
"Deliverable": $("#dDeliverable").val(),
"To": $("#dTo").val(),
"Date": $("#dDate").val(),
"Approved": $("#dApproved").val(),
"Notes": $("#dNotes").val()
};
$.ajax({
async: true, // Async by default is set to “true” load the script asynchronously
// URL to post data into sharepoint list or your own url
url: "https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/web/lists/getbytitle('AMMO Deliverables')/items",
method: "POST", //Specifies the operation to create the list item
data: JSON.stringify(item),
headers: {
"content-type": "application/json;odata=verbose",
"X-RequestDigest": digestData.d.GetContextWebInformation.FormDigestValue,
"Accept": "application/json;odata=verbose",
"If-Match": "*"
},
success: function(data) {
alert('Success'); // Used sweet alert for success message
console.log(data + " success in updating item");
},
error: function(data) {
alert(JSON.stringify(item));
console.log(data);
}
});
})
}
function getItemTypeForListName(listName) {
var itemType = "SP.Data." + listName.charAt(0).toUpperCase() + listName.slice(1) + "ListName";
var encItemType = itemType.replace(/\s/g,'_x0020_');
return(encItemType);
}
function getFormDigest(baseurl) {
return $.ajax({
url: "https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/contextInfo",
method: 'POST',
headers: {
'Accept': 'application/json; odata=verbose'
}
});
}
UPDATE:
I feel like I am somewhat in the right direction, but it doesn't work:
function PostItem() {
return getFormDigest("https://siteurl.sharepoint.com/sites/Projects/USMC/AMMO/Lists/AMMODeliverables/").then(function(digestData) {
console.log(digestData.d.GetContextWebInformation.FormDigestValue);
var item = {
"__metadata": { "type": "SP.Data.AMMODeliverablesListItem" },
"Title": "updated title",
"Program": $("#dProgram").val(),
"Deliverable": $("#dDeliverable").val(),
"To": $("#dTo").val(),
"Date": $("#dDate").val(),
"Approved": $("#dApproved").val(),
"Notes": $("#dNotes").val()
};
if (dProgram == "AMMO"){
$.ajax({
async: true, // Async by default is set to “true” load the script asynchronously
// URL to post data into sharepoint list or your own url
url: "https://siteurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/web/lists/getbytitle('AMMO Deliverables')/items",
method: "POST", //Specifies the operation to create the list item
data: JSON.stringify(item),
headers: {
"content-type": "application/json;odata=verbose",
"X-RequestDigest": digestData.d.GetContextWebInformation.FormDigestValue,
"Accept": "application/json;odata=verbose",
"If-Match": "*"
},
success: function(data) {
alert('Success'); // Used sweet alert for success message
console.log(data + " success in updating item");
},
error: function(data) {
alert(JSON.stringify(item));
console.log(data);
}
});
}
else if (dProgram == "AHR"){
First of all, your getFormDigest function is not quite right:
function getFormDigest(baseurl) {
// you pass in a "baseurl" value above, but you're not really doing anything with it.
// the URL you use below is hardcoded to always
// make the request to the /sites/Projects/USMC/AMMO site
return $.ajax({
url: "https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/contextInfo",
method: 'POST',
headers: {
'Accept': 'application/json; odata=verbose'
}
});
}
What you need to do is change that so you can pass a site URL into it and get a valid form digest from the actual site you are trying to post a new item to:
function getFormDigest(siteUrl) {
return $.ajax({
url: siteUrl + "/_api/contextInfo",
method: 'POST',
headers: {
'Accept': 'application/json; odata=verbose'
}
});
}
Next, you need to change your PostItem function to react to the current value of the selected Program, and choose some correct values based on that. I see in the comments you have posted a little snippet where you are creating a map that will spit out the correct URL based on the key of the selected Program. That works if all you need is a single value, however, since you said that the list names are all different on each subsite, you actually need three different values to be generated dynamically based on the selected Program:
The URL to the site itself so you can get a valid form digest,
The list name, so you can get the correct List Item Entity Type value for your new item's JSON __metadata property. You have a function to do this, but you aren't using it. Also, you'll need the list name for:
A URL that includes the site and the list name so you can post the new list item (since the URL to do that is essentially [URL to site]/_api/web/lists/getbytitle('[list name]')/items)
You could do a sequence of if..then..else if..then..else if..then..else statements, but for more than two or three possible values, that gets cumbersome. A much cleaner way of doing it is using a switch statement. So here's what your PostItem function might look like if you used a switch to evaluate what the selected Program value is and then dynamically set the site URL and list name based on that:
function PostItem() {
// the base URL should be what is the same across all subsites. in comments
// you said the subsites start to differ after /sites/Projects.
var baseUrl = "https://your-tenant.sharepoint.com/sites/Projects";
// get the selected program from your form
var programName = $("#dProgram").val();
var siteUrl = null; // set this as empty for now
var listName = null; // set this as empty for now
// a "switch" statement is like a fancy "if" statement that is
// useful if you have more than just two or three options
switch (programName) {
case "AMMO":
// set the site url to be whatever it is after /sites/Projects.
// in the case of AMMO, you have already posted that the "AMMO"
// subsite is under a "USMC" subsite that is under "Projects"
siteUrl = baseUrl + "/USMC/AMMO";
listName = "AMMODeliverables";
break;
case "AHR":
// set the site url to be whatever it is after /sites/Projects.
// IF in this case the "AHR" subsite is directly under /Projects
// and NOT under another subsite (as is the case with /USMC/AMMO),
// you just add that directly:
siteUrl = baseUrl + "/AHR";
// HOWEVER, if it is under another subsite with a different name, similar
// to how "AMMO" is actually under another subsite called "USMC", then you
// would include that "Other" subsite here:
siteUrl = baseurl + "/Other/AHR";
// set the list name, since you said the list names
// are different in each of the subsites
listName = "AHR Deliverables";
break;
case "FOO":
// pretending that "FOO" is _directly_ under /sites/Projects
siteUrl = baseurl + "/FOO";
listName = "FOO Thingys";
break;
case "BAR":
// pretending that "BAR" is NOT directly under /sites/Projects,
// but is in fact under another "Different" subsite
siteUrl = baseurl + "/Different/BAR";
listName = "BAR Whatchamacallits";
default:
// all switch statements need a default option in case
// what we are checking does not match any any of the options
// we are expecting. in this instance, we will _not_ set
// a site URL or list name so that we do not try to post
// to s non-existent site or list
break;
}
// if we didn't get one of our expected choices for programName, then siteUrl
// will not have been populated in the switch, so we can check and make sure we
// actually have a valid siteUrl before we start sending AJAX requests out
if (siteUrl) {
// pass the siteUrl into your improved getFormDigest function so
// that you get the correct form digest from the site you are
// actually trying to post a new item to.
// also, you don't actuall need the "return" here.
getFormDigest(siteUrl).then(function(digestData) {
console.log(digestData.d.GetContextWebInformation.FormDigestValue);
// use your getItemTypeForListName function to get the
// correct SharePoint List Item Entity Type name based on
// the list name
var listItemEntityType = getItemTypeForListName(listName);
// construct the URL to post the new list item to based on the siteUrl
// and the listName, which vary based on the selected projecName
var postNewItemUrl = siteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items";
// construct your new item JSON. you said all the fields
// in all the lists are the same, so the only thing that really
// needs to dynamically chage here is the entity type name,
// which was generated based on the list name
var item = {
"__metadata": { "type": listItemEntityType },
"Title": "updated title",
"Program": programName,
"Deliverable": $("#dDeliverable").val(),
"To": $("#dTo").val(),
"Date": $("#dDate").val(),
"Approved": $("#dApproved").val(),
"Notes": $("#dNotes").val()
};
$.ajax({
// use your dynamically generated URL here
url: postNewItemUrl,
method: "POST", //Specifies the operation to create the list item
data: JSON.stringify(item),
headers: {
"content-type": "application/json;odata=verbose",
"X-RequestDigest": digestData.d.GetContextWebInformation.FormDigestValue,
"Accept": "application/json;odata=verbose",
"If-Match": "*"
},
success: function(data) {
alert('Success'); // Used sweet alert for success message
console.log(data + " success in updating item");
},
error: function(data) {
alert(JSON.stringify(item));
console.log(data);
}
});
});
}
}

Function is returning value before running inner actions

Using SharePoint's PreSaveAction() that fires when the Save button is clicked, I am trying to run checks and manipulate fields before the form is saved. If PreSaveAction() returns true, the form will be saved and closed.
function PreSaveAction() {
var options = {
"url": "https://example.com/_api/web/lists/getbytitle('TestList')/items",
"method": "GET",
"headers": {
"Accept": "application/json; odata=verbose"
}
}
$.ajax(options).done(function (response) {
var actualHours = response.d.results[0].ActualHours
var personalHours = $("input[title$='Personal Hours']").val();
var regex = /^\d*\.?\d+$/ // Forces digit after decimal point
if (personalHours && regex.test(personalHours)) { // Run if input is not blank and passes RegEx
if (response.d.results[0].__metadata.etag.replace(/"/g, "") == $("td .ms-descriptiontext")[0].innerText.replace("Version: ", "").split('.')[0]) {
// Run if item's data from REST matches version shown in form
addChildItem(id, title, personalHours, actualHours)
}
}
});
return true; // firing before request above begins
}
The function is returning as true before running the jQuery AJAX call which runs addChildItem() that manipulates fields within the form and posts relevant data to a separate list.
function addChildItem(id, title, personalHours, actualHours) {
$.ajax({
method: "POST",
url: "https://example.com/_api/web/lists/getbytitle('ChildList')/items",
data: JSON.stringify({
__metadata: {
'type': 'SP.Data.ChildListListItem'
},
ParentID: id,
Title: title,
HoursWorked: personalHours
}),
contentType: "application/json;odata=verbose",
headers: {
"Accept": "application/json; odata=verbose",
},
success: function (data) {
console.log("success", data);
var actualHoursNum = Number(actualHours);
var personalHoursNum = Number(personalHours);
$("input[title$='Actual Hours']").val(actualHoursNum + personalHoursNum);
$("input[title$='Personal Hours']").val('');
// Input is getting cleared on save but shows previous number when form is opened again
},
error: function (data) {
console.log("error", data);
}
});
}
This is causing the form to accept the field value manipulations but only after the save and before the automatic closure of the form.
I need PreSaveAction() to wait until after addChildItem() is successful to return true but I'm not sure how to do this. I have tried using a global variable named returnedStatus that gets updated when addChildItem() is successful but the return value in PreSaveAction() still gets looked at before the jQuery AJAX call is ran.
How can I solve this?
I got a similar case by setting async: false to add user to group in PreSaveAction.
Original thread
<script language="javascript" type="text/javascript">
function PreSaveAction() {
var check = false;
var controlName = 'MultiUsers';
// Get the people picker object from the page.
var peoplePickerDiv = $("[id$='ClientPeoplePicker'][title='" + controlName + "']");
var peoplePickerEditor = peoplePickerDiv.find("[title='" + controlName + "']");
var peoplePicker = SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDiv[0].id];
if (!peoplePicker.IsEmpty()) {
if (peoplePicker.HasInputError) return false; // if any error
else if (!peoplePicker.HasResolvedUsers()) return false; // if any invalid users
else if (peoplePicker.TotalUserCount > 0) {
// Get information about all users.
var users = peoplePicker.GetAllUserInfo();
for (var i = 0; i < users.length; i++) {
console.log(users[i].Key);
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/sitegroups(22)/users";
$.ajax({
url: requestUri,
type: "POST",
async: false,
data: JSON.stringify({ '__metadata': { 'type': 'SP.User' }, 'LoginName': '' + users[i].Key + '' }),
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function(data) {
console.log('User Added');
check = true;
},
error: function (error) {
console.log(JSON.stringify(error));
check = false;
}
});
}
}
} else {
console.log('No user');
}
return check;
}
</script>

Get hold of json content that is being sent to Jquery

That's how I reach when I send some values that are specified in my input and therefore they need to send to a API.
When I try to send them to the monkey, my monkey tells me that nothing has been sent.
At my console.log(token), it tells me what data is available and I also agree that it all fits together. But the problem is just that it has to come over to my API.
function PayStripe() {
// Open Checkout with further options:
handler.open({
name: 'XXX ',
description: 'XX abonnement',
currency: "dkk",
amount: $('#HiddenPrice').val() * 100,
email: $('#Email').val()
});
};
// Close Checkout on page navigation:
$(window).on('popstate', function () {
handler.close();
});
var handler = StripeCheckout.configure({
key: 'pk_test_xxxx',
locale: 'auto',
token: function (token) {
token.subscriptionId = $('#SubscriptionId').val();
token.City = $('#City').val();
token.Postnr = $('#Postnr').val();
token.Mobil = $('#Mobil').val();
token.Adresse = $('#Adresse').val();
token.CVRVirksomhed = $('#CVRVirksomhed').val();
console.log(token.subscriptionId);
console.log(token);
$.ajax({
type: "POST",
url: "/api/Stripe",
contentType: "application/json",
data: token,
success: function (data) {
//window.location.href = '/Subscriptions/Succes';
alert(data + "Succes")
},
error: function (data) {
console.log(data + "Error");
},
dataType: 'json'
});
// You can access the token ID with `token.id`.
// Get the token ID to your server-side code for use.
}
});
Where the problem lies is that the API is by no means able to get informed information from jquery. so it's like it can not / will receive it.
[HttpPost]
[Route("api/Stripe")]
[Produces("application/json")]
public async Task<IActionResult> Post([FromForm] JObject token)
When I grab the token that I need for example. then I do this here:
var SubscriptionId = (int)token.GetValue("subscriptionId");
When you set contentType: "application/json", you need to stringify the data to json yourself
data: JSON.stringify(token),

SharePoint send email with javascript on add list item

I like to send an email to the administrator when a user adds a item to my List. I already changed the NewForm for the list and execute the add item with:
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', retrieveListItems);
Now in my SharePoint the email notification on Lists has been disabled by the company. So I'd like some code to send an email automatically after the user added an item.
I already have the username of the person who added the item.
var loginName = "";
var userid = _spPageContextInfo.userId;
GetCurrentUser();
function GetCurrentUser() {
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid(" + userid + ")";
The email has to be send to an address of the companies outlook server. An SMTP can be used.
Marco
Here is a little code snippet to send email using javascript.
function getUserEmail(){
$.ajax({
url:spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid("+_spPageContextInfo.userId+")?$select=Email",
headers:{"Accept": "application/json;odata=verbose","content-type": "application/json;odata=verbose"},
success:function(result){
var email = result.d.Email;
sendEmail("xxxx#email.com", email, "body", "subject");
}
});
}
function sendEmail(from, to, body, subject) {
var siteurl = _spPageContextInfo.webServerRelativeUrl;
var urlTemplate = siteurl + "/_api/SP.Utilities.Utility.SendEmail";
$.ajax({
contentType: 'application/json',
url: urlTemplate,
type: "POST",
data: JSON.stringify({
'properties': {
'__metadata': {
'type': 'SP.Utilities.EmailProperties'
},
'From': from,
'To': {
'results': [to]
},
'Body': body,
'Subject': subject
}
}),
headers: {
"Accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
},
success: function (data) {
console.log(data);
},
error: function (err) {
console.error(err);
}
});
}
But it also depends on your scenario. Can you give us more details about:
I already changed the NewForm for the list and execute the add item with:
How did you proceed?
Are you working on on-premise or online instance?
It seems that it was still possible to set an alert on a list when an item was added. So that solved my problem.

How to Post a .json file to ArangoDB using Ajax

I am trying to post a .json file as a single document to an ArangoDB collection, from within javascript/ajax.
I can post (to ArangoDB) the .json file using curl, so that works
I can post (to ArangoDB) simple {key: value} pairs using AJAX, so that works, but combining the two seems to be a bridge too far. I have spent a couple of nights trying to get this far, so any help would be hugely appreciated. thanks in advance.
My javascript code looks like this
var database_URL = prompt("Please enter your URL", "http://xxx..xxx.xxxx.:8529/_db/collection_name/_api/document?collection=PA_Users&createCollection=false");
var fd = new FormData();
var selectedFile = document.getElementById('files').files[0];
console.log(selectedFile.name);// this works
fd.append(selectedFile.name,selectedFile);
var settings = {
url : database_URL,
type : "POST",
headers: {
'Authorization': "Basic " + btoa(username1 + ":" + passwrd1)
},
data: fd,
processData: false,
success: function(data) {
// display feedback to user
alert("booyah");
},
error: function(data) {
// display feedback to user
alert("boo hoo");
}
};
$.ajax(settings);
I think you should use /_api/import instead of /_api/document:
HTTP Interface for Bulk Imports
Here is a small working example (without authorization):
$.ajax({
type: "POST",
url:
'/_api/import?type=auto&collection=' +
encodeURIComponent(yourCollectionID) +
'&createCollection=false',
data: file,
processData: false,
contentType: 'json',
dataType: 'json',
complete: function(xhr) {
if (xhr.readyState === 4 && xhr.status === 201) {
callback(false);
} else {
try {
var data = JSON.parse(xhr.responseText);
if (data.errors > 0) {
// error
}
else {
// success
}
}
catch (err) {
console.log(err);
}
}
}
});
}
The api supports a few input formats:
1.) Single document
{name: "Jonny"}
2.) Multiple documents (one doc in each row)
{name: "Jonny"}
{name: "Adam"}
{name: "Peter"}
3.) Multiple documents in JSON array
[{name: "Jonny"}, {name: "Adam"}, {name: "Peter"}]

Categories

Resources