how to get approval status field value in sharepoint client object model - sharepoint

How can i get list item approval status value using client object model in sharepoint?
Here is my sample code on fetching other attribute values.
ClientContext.Load(listItems,
items => items.Include(
item => item.Id,
item => item.DisplayName,
item => item.FileSystemObjectType,
item => item.HasUniqueRoleAssignments));

Here is the full code that gets and sets (optional) approval status (Possible values for this.oListItem.get_item('_ModerationStatus'): 0 - "Approved", 1 - "Denied", 2- "Pending"):
<script type="text/javascript" src="/jquery-1.10.2.min.js"></script>
<script src="/jquery.SPServices-2013.02a.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () { ExecuteOrDelayUntilScriptLoaded(loadConstants, "sp.js"); });
function loadConstants() {
var userid= _spPageContextInfo.userId;
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid(" + userid + ")";
var requestHeaders = { "accept" : "application/json;odata=verbose" };
$.ajax({
url : requestUri,
contentType : "application/json;odata=verbose",
headers : requestHeaders,
success : onSuccess,
error : onError
});
function onSuccess(data, request){
var loginName = data.d.Title;
//get current (selected) list item id
var docurl = document.URL;
var beginindex = docurl.indexOf('?ID=') + 4;
var endindex = docurl.indexOf('&Source=');
var itemid = docurl.substring(beginindex, endindex);
var ctx = new SP.ClientContext("your site url");
var oList = ctx.get_web().get_lists().getByTitle('your list name');
this.oListItem = oList.getItemById(itemid);
var appStatus = "";
ctx.load(this.oListItem);
ctx.executeQueryAsync(Function.createDelegate(this, function () {
//get approval status
appStatus = this.oListItem.get_item('_ModerationStatus');
//set approval status to Approved (0)
this.oListItem.set_item('_ModerationStatus', 0);
this.oListItem.update();
ctx.executeQueryAsync(
Function.createDelegate(this, this.onQuerySucceeded),
Function.createDelegate(this, this.onQueryFailed)
);
}), function (sender, args) { alert('Error occured' + args.get_message());});
}
function onError(error) {
alert("error");
}
}
</script>

You can get approve status using like this
ClientContext.Load(listItems,
items => items.Include(
item => item.Id,
item => item.DisplayName,
item => item["Status"]));
You can get any of field custom or Sharepoint default fields value like this.

Related

Nested ClientContext executeQueryAsync()

I have a requirement to change the value of a SharePoint List Workflow Status Column.
Lets assume we could have 2 to many workflow columns in one list (The below code works when a list has 1 workflow status column).
The issue is when it has multiple Workflow Status Column, it updates only the last column as there are nested executeQueryAsync calls.
I have tried the same with Deferred/Promise as well - see the second code block.
<script type="text/javascript">
ExecuteOrDelayUntilScriptLoaded(initialize, "sp.js");
//Get our objects
function initialize() {
var t0 = performance.now();
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getById(_spPageContextInfo.pageListId)
var fieldCollection = list.get_fields();
var spField;
context.load(fieldCollection);
context.executeQueryAsync(Function.createDelegate(this, onFieldCollectionSucceeded), Function.createDelegate(this, onListDataFailed));
function onFieldCollectionSucceeded(sender, args) {
var fieldEnumerator = fieldCollection.getEnumerator();
while (fieldEnumerator.moveNext()) {
var field = fieldEnumerator.get_current();
var fType = field.get_fieldTypeKind();
//Value 28 correspond to SPWorkflowStatus
if (fType === 28) {
console.log(fieldEnumerator.get_current().get_title() + ": " + fType);
spField = field;
context.load(spField, "SchemaXml");
context.executeQueryAsync(Function.createDelegate(this, onFieldSucceeded), Function.createDelegate(this, onListDataFailed));
}
}
}
function onFieldSucceeded(sender, args) {
console.log("Schema changes processing for column: " + spField.get_title());
var schema = spField.get_schemaXml();
var newSchema = schema.replace('Abgelehnt', 'Rejected');
spField.set_schemaXml(newSchema);
spField.update();
context.executeQueryAsync(
Function.createDelegate(this, schemaChanged),
Function.createDelegate(this, onListDataFailed));
};
function schemaChanged(sender, args) {
console.log('Field Schema Updated');
}
function onListDataFailed(sender, args) {
console.log('List Data fetch failed. ' + args.get_message() + 'n' + args.get_stackTrace());
};
var t1 = performance.now();
console.log("Total Execution Time " + (t1 - t0) + " milliseconds.")
};
<script type="text/javascript">
//http://johnliu.net/blog/2015/12/convert-sharepoint-jsoms-executequeryasync-to-promise-in-the-prototype
ExecuteOrDelayUntilScriptLoaded(registerJsomPromise, "sp.js");
ExecuteOrDelayUntilScriptLoaded(initialize, "sp.js");
function initialize() {
var t0 = performance.now();
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getById(_spPageContextInfo.pageListId)
var fieldCollection = list.get_fields();
var spField;
context.load(fieldCollection);
context.executeQueryAsync(Function.createDelegate(this, onFieldCollectionSucceeded), Function.createDelegate(this, onListDataFailed));
};
function onFieldCollectionSucceeded(sender, args) {
var fieldEnumerator = fieldCollection.getEnumerator();
while (fieldEnumerator.moveNext()) {
var field = fieldEnumerator.get_current();
var fType = field.get_fieldTypeKind();
//Value 28 correspond to SPWorkflowStatus
if (fType === 28) {
console.log(fieldEnumerator.get_current().get_title() + ": " + fType);
spField = field;
context.load(spField, "SchemaXml");
var promise = context.executeQuery();
setTimeout(function () { }, 500);
promise.done(function () {
console.log("Schema changes processing for column: " + spField.get_title());
var schema = spField.get_schemaXml();
var newSchema = setSchema(schema);
spField.set_schemaXml(newSchema);
spField.update();
context.load(spField);
context.executeQueryAsync(
Function.createDelegate(this, schemaChanged),
Function.createDelegate(this, onListDataFailed));
});
promise.then(function (sArgs) {
console.log('Field Schema Updated');
//sArgs[0] == success callback sender
//sArgs[1] == success callback args
}, function (fArgs) {
//fArgs[0] == fail callback sender
//fArgs[1] == fail callback args.
//in JSOM the callback args aren't used much -
//the only useful one is probably the get_message()
//on the fail callback
var failmessage = fArgs[1].get_message();
});
//context.executeQueryAsync(Function.createDelegate(this, onListDataSucceeded), Function.createDelegate(this, onListDataFailed));
}
}
}
function schemaChanged(sender, args) {
console.log('Field Schema Updated');
}
function onListDataFailed(sender, args) {
console.log('List Data fetch failed. ' + args.get_message() + 'n' + args.get_stackTrace());
};
var t1 = performance.now();
console.log("Total Execution Time " + (t1 - t0) + " milliseconds.")
function registerJsomPromise() {
SP.ClientContext.prototype.executeQuery = function () {
var deferred = $.Deferred();
this.executeQueryAsync(
function () { deferred.resolve(arguments); },
function () { deferred.reject(arguments); }
);
return deferred.promise();
};
}
The execute query async changes the state of iterator. This is why you have a weird behavior. You should load your fields, update those, and do one single execute at the end out of the while to actually update stuff. The only issue with that approach is that if you're code fails at some point, all the updates will be pending. So careful error handling is required.

Getting User Level Permissions on List in sharepoint online using Javascript and Rest API

I have implemented sharepoint hosted app for getting user level permissions on a list using javascript and rest api.
Here is my code,
'use strict';
var hostweburl;
var appweburl;
var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
hostweburl = _spPageContextInfo.siteAbsoluteUrl;
appweburl = _spPageContextInfo.siteServerRelativeUrl;
alert(hostweburl);
alert(appweburl);
getListUserEffectivePermissions();
});
function getListUserEffectivePermissions() {
var listTitle = 'MyList_Deepa';
//var account = 'i%3A0%23.f%7Cmembership%7Cuser%40abhishek#sarasamerica.com&#target=';
var endpointUrl = "'" + appweburl + "'/_api/SP.AppContextSite(#target)/web/lists/getbytitle('" + listTitle + "')/getusereffectivepermissions(#user)?#user='i%3A0%23.f%7Cmembership%7Cuser%40abhishek#sarasamerica.com&#target='" + hostweburl + "'";
//var endpointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('" + MyList_Deepa + "')/getusereffectivepermissions(#u)?#u='" + encodeURIComponent(account) + "'";;
return $.ajax({
url: endpointUrl,
dataType: 'json',
headers: {
"accep": "application/json;odata=verbose",
"X-RequestDigest": $("#_REQUESTDIGEST").val()
}
});
}
function parseBasePermissions(value) {
var permissions = new SP.BasePermissions();
permissions.initPropertiesFromJson(value);
var permLevels = [];
for (var permLevelName in SP.PermissionKind.prototype) {
if (SP.PermissionKind.hasOwnProperty(permLevelName)) {
var permLevel = SP.PermissionKind.parse(permLevelName);
if (permissions.has(permLevel)) {
permLevels.push(permLevelName);
}
}
}
return permLevels;
}
getListUserEffectivePermissions().done(function (data) {
var roles = parseBasePermissions(data.d.GetUserEffectivePermissions);
console.log(roles);
});
Error: Failed to load resource: the server responded with a status of 404 (Not Found).
Please anybody can give solution to resolve the problem.

Automate login + posting to forum using nodejs + phantomjs

I am trying to automate login to a forum ( yet another forum , test forum available here: http://testforum.yetanotherforum.net/ ) using node-phantom.
This is my code:
/**
* Yet Another Forum Object
*
*
*/
var yaf = function() {}; //
module.exports = new yaf();
var phantom = require('node-phantom');
//var sleep = require('sleep');
var configTestForum = {
loginUrl: "http://testforum.yetanotherforum.net/login",
loginFormDetail: {
usernameBox: 'forum_ctl03_Login1_UserName', // dom element ID
passwordBox: 'forum_ctl03_Login1_Password',
submitButton: 'forum_ctl03_Login1_LoginButton'
},
loginInfo: {
username: 'testbot',
password: 'testbot123'
}
};
var config = configTestForum;
// program logic
yaf.prototype.login = function(username, password, cb) {
var steps = [];
var testindex = 0;
var loadInProgress = false; //This is set to true when a page is still loading
/*********SETTINGS*********************/
phantom.create(function(error, ph) {
ph.createPage(function(err, page) {
page.set('settings', {
userAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0",
javascriptEnabled: true,
loadImages: false,
});
phantom.cookiesEnabled = true;
phantom.javascriptEnabled = true;
/*********SETTINGS END*****************/
console.log('All settings loaded, start with execution');
/**********DEFINE STEPS THAT FANTOM SHOULD DO***********************/
steps = [
//Step 1 - Open Amazon home page
function() {
console.log('Step 1 - Open Login Page');
page.open(config.loginUrl, function(status) {
});
},
function() {
console.log('Step 2 - Populate and submit the login form');
var submitForm = function(config) {
console.log('Form Submit 1 ( putting login )');
document.getElementById(config.loginFormDetail.usernameBox).value = config.loginInfo.username;
console.log('Form Submit 2 ( putting pass )');
//jQuery('#' + config.loginFormDetail.passwordBox).val(config.loginInfo.password);
//jQuery('#' + config.loginFormDetail.usernameBox).val(config.loginInfo.password);
document.getElementById(config.loginFormDetail.passwordBox).value = config.loginInfo.password;
console.log('Form Submit 3 ( clicking button ) ');
document.getElementById(config.loginFormDetail.submitButton).click();
//var clickElement = function (el) {
// var ev = document.createEvent("MouseEvent");
// ev.initMouseEvent(
// "click",
// true /* bubble */, true /* cancelable */,
// window, null,
// 0, 0, 0, 0, /* coordinates */
// false, false, false, false, /* modifier keys */
// 0 /*left*/, null
// );
// el.dispatchEvent(ev);
// console.log('dispatched!');
//};
//document.getElementById(config.loginFormDetail.submitButton).click();
//clickElement(jQuery("#forum_ctl03_Login1_LoginButton")[0]);
//
//var form = document.getElementById('form1');
////var list = function(object) {
//// for(var key in object) {
//// console.log(key);
//// }
////};
////list(form);
//
//
//// jQuery('#form1').submit();
//
//form.submit();
//
//document.forms[0].submit();
//HTMLFormElement.prototype.submit.call(jQuery('form')[0]);
console.log('Form Has Been Submitted <-----------------');
};
var subittedForm = function(err, retVal) {
console.log('Form Submit error : ' + err);
console.log('Form Submit returned : ' + retVal);
};
//page.evaluateJavaScript(jsCode);
page.evaluate(submitForm, subittedForm, config);
},
//Step 3 - wait for submit form to finish loading..
function() {
//sleep.sleep(5);
console.log("Step 3 - wait for submit form to finish loading..");
//sleep.sleep(3);
page.render('loginComplete.png');
page.get('cookies', function(err, cookies) {
// console.log(cookies);
});
page.evaluate(function() {
console.log(document.URL);
});
},
function() {
console.log('Exiting');
}
];
/**********END STEPS THAT FANTOM SHOULD DO***********************/
//Execute steps one by one
interval = setInterval(executeRequestsStepByStep, 500);
function executeRequestsStepByStep() {
if (loadInProgress == false && typeof steps[testindex] == "function") {
//console.log("step " + (testindex + 1));
steps[testindex]();
testindex++;
}
if (typeof steps[testindex] != "function") {
console.log("test complete!");
ph.exit();
// cb(ph);
cb('done');
}
}
page.onLoadStarted = function() {
loadInProgress = true;
console.log('Loading started');
};
page.onLoadFinished = function() {
loadInProgress = false;
console.log('Loading finished');
};
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onError = function(msg, trace) {
var msgStack = ['ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function+'")' : ''));
});
}
console.error('\n' + msgStack.join('\n'));
};
page.onResourceError = function(resourceError) {
console.error('Unable to load resource (#' + resourceError.id + ' URL:' + resourceError.url + ')');
console.error('Error code: ' + resourceError.errorCode + '. Description: ' + resourceError.errorString);
};
page.onResourceTimeout = function(msg) {
console.error('onResourceTimeout!!>' + msg);
};
page.onAlert = function(msg) {
console.error('onAlert!!> ' + msg);
};
});
});
// var page = webPage.create();
};
Output of the code is :
Step 1 - Open Login Page
Loading started
Loading finished
Step 2 - Populate and submit the login form
Form Submit 1(putting login)
Form Submit 2(putting pass)
Form Submit 3(clicking button)
Form Has Been Submitted < -----------------
Form Submit error: null
Form Submit returned: null
Unable to load resource(#14 URL:http://testforum.yetanotherforum.net/login?g= login &= )
Error code: 5.Description: Operation canceled
ERROR: TypeError: 'undefined'
is not an object(evaluating 'Sys.WebForms.Res.PRM_TimeoutError'), [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object]
Step 3 - wait
for submit form to finish loading..
http: //testforum.yetanotherforum.net/login
Exiting
test complete!
done
Option client store expiration is not valid.Please refer to the README.
Process finished with exit code 0
What it attempts to do is :
Open login page : http://testforum.yetanotherforum.net/login?returnurl=%2fcategory%2f1-Test-Category
Try to login using login name / password and then clicking the button.
Take a screenshot and Retrieve the cookies ( containing the auth data )
Currently it is getting stuck in step 2. It can populate the login and password box, but no kind of clicking or submitting the form is working.Basically it is stuck as shown:
(as you can see the login / password are filled correctly ).
By looking at step 2 ( Step 2 - Populate and submit the login form ) in my code, do you notice anything obvious? or am I doing something wrong in the page settings?

How to Get AllowedContentTypes of a document set in sharepoint JSOM

How to programatically get AllowedContentTypes property of a document set
On SERVER SIDE (C#) WE CAN get the CT as below
var ctIds = ds.ContentTypeTemplate.AllowedContentTypes;
//1
foreach (SPContentTypeId ctId in ctIds)
{
Console.WriteLine(ctId); //print Content Type Id
}
How to achieve the same in Javascript i was able to get the folder of the doc set what properties i need to use to get the AllowedContentTypes Property
Hi Vadim Thanks for your answer but i am getting the error "SP.DocumentSet.DocumentSetTemplate' is null or not an object"
<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.documentmanagement.js"></script>
<script type="text/javascript">
// ExecuteOrDelayUntilScriptLoaded(getCT, "sp.js");
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
SP.SOD.executeFunc('sp.documentmanagement.js', 'SP.DocumentSet.DocumentSet', function() {
var docSetUrl = getQueryStringValue("RootFolder"); //<- Doc Set Url
getDocumentSetContentTypes(docSetUrl,
function(ctIds)
{
//print content type ids
ctIds.get_data().forEach(function(ctId){
console.log(ctId.get_stringValue());
});
},
logError);
});
});
function logError(sender,args){
console.log(args.get_message());
}
function getFolder(url,success,error)
{
var ctx = SP.ClientContext.get_current();
var folder = ctx.get_web().getFolderByServerRelativeUrl(url);
ctx.load(folder,'ListItemAllFields');
ctx.executeQueryAsync(
function(){
success(folder);
},
error);
}
function getDocumentSetContentTypes(folderUrl,success,error)
{
getFolder(folderUrl,
function(folder)
{
var folderItem = folder.get_listItemAllFields();
var ct = folderItem.get_contentType();
var ctx = folder.get_context();
var template = SP.DocumentSet.DocumentSetTemplate.getDocumentSetTemplate(ctx,ct);
var ctIds = template.get_allowedContentTypes();
ctx.load(ctIds);
ctx.executeQueryAsync(
function(){
success(ctIds);
},
error);
},
error);
}
function getQueryStringValue (key) {
return unescape(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + escape(key).replace
(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1"));
}
</script>
SP.DocumentSet.DocumentSetTemplate.getDocumentSetTemplate function from sp.documentmanagement.js is used for getting content type template and get_allowedContentTypes property returns allowed content types, for example:
var template = SP.DocumentSet.DocumentSetTemplate.getDocumentSetTemplate(ctx,ct);
var ctIds = template.get_allowedContentTypes();
The following example demonstrates how to retrieve allowed content types of Document Set using JSOM
function getFolder(url,success,error)
{
var ctx = SP.ClientContext.get_current();
var folder = ctx.get_web().getFolderByServerRelativeUrl(url);
ctx.load(folder,'ListItemAllFields');
ctx.executeQueryAsync(
function(){
success(folder);
},
error);
}
function getDocumentSetContentTypes(folderUrl,success,error)
{
getFolder(folderUrl,
function(folder)
{
var folderItem = folder.get_listItemAllFields();
var ct = folderItem.get_contentType();
var ctx = folder.get_context();
var template = SP.DocumentSet.DocumentSetTemplate.getDocumentSetTemplate(ctx,ct);
var ctIds = template.get_allowedContentTypes();
ctx.load(ctIds);
ctx.executeQueryAsync(
function(){
success(ctIds);
},
error);
},
error);
}
Usage
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
SP.SOD.executeFunc('sp.documentmanagement.js', 'SP.DocumentSet.DocumentSet', function() {
var docSetUrl = '/Documents/2013'; //<- Doc Set Url
getDocumentSetContentTypes(docSetUrl,
function(ctIds)
{
//print content type ids
ctIds.get_data().forEach(function(ctId){
console.log(ctId.get_stringValue());
});
},
logError);
});
});
function logError(sender,args){
console.log(args.get_message());
}

Error - No Transport , while trying to create an entity using json

//Prepare ‘Account’ object and call create function
function createAccount() {
var new_nit = new Object();
// Set text field
new_nit.Name = "Maddy";
createRecord(new_nit, "new_nitSet", createAccountCompleted, null);
}
// This callback method executes on succesful account creation
function createAccountCompleted(data, textStatus, XmlHttpRequest) {
var nit = data;
alert("Account created; Id: ");
}
// This function creates record by making OData call
function createRecord(entityObject, odataSetName, successCallback, errorCallback) {
//Parse the entity object into JSON
var jsonEntity = window.JSON.stringify(entityObject);
// Get Server URL
var serverUrl = Xrm.Page.context.getServerUrl();
//The OData end-point
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
//Asynchronous AJAX function to Create a CRM record using OData
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: serverUrl + ODATA_ENDPOINT + "/" + odataSetName,
data: jsonEntity,
beforeSend: function (XMLHttpRequest) {
//Specifying this header ensures that the results will be returned as JSON.
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, XmlHttpRequest) {
if (successCallback) {
successCallback(data.d, textStatus, XmlHttpRequest);
}
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
if (errorCallback)
errorCallback(XmlHttpRequest, textStatus, errorThrown);
else
alert("Error on the creation of record; Error – "+errorThrown);
}
});
}
I'm using above code to create a entity called nit. I have json2 and jQuery js files in web resource. When i run this code on button click, i'm getting error as No Transport. when i searched , i got to know that this error is because of cross site scripting. How to enable cross site scripting or how to get rid of this error.
function createAccount() {
var gid = Xrm.Page.getAttribute("new_syllabus").getValue();
var stamail = new Object();
stamail.new_name = "Maddy";
stamail.new_gid = gid;
var myurl = "http://" + window.location.host + "/" + Xrm.Page.context.getOrgUniqueName();
//alert(gid);
// alert(Xrm.Page.data.entity.getId());
var jsoEntity = JSON.stringify(stamail);
var createRecordReq = new XMLHttpRequest();
var ODataPath = myurl + "/XRMServices/2011/OrganizationData.svc";
createRecordReq.open("POST", ODataPath + "/new_nitSet", false);
createRecordReq.setRequestHeader("Accept", "application/json");
createRecordReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
// createRecordReq.onreadystatechange = function () { requestCallBack(this); };
createRecordReq.send(jsoEntity);
var newRecord = JSON.parse(createRecordReq.responseText).d;
}
Instead of using ajax i used above code. Its working fine.

Resources