Grant Access to ‘SharePoint Group’ on Item Level Permission using Client Side Scripting (JSOM) in SharePoint 2010 and 2013

Ahamed Fazil Buhari
 
Senior Developer
February 4, 2017
 
Rate this article
 
Views
5254

In my previous article we have seen ‘How to Break Inherit Permission and Grant Access to Specific User on SharePoint List Items or Folders (Multiple) using SPServices and JavaScript’ here in this article we can see how to grant access to SharePoint group.

For example, consider that we’ve a library named ‘Shared Document’ and we need to grant access to specific Items inside that library to a SharePoint Group called ‘Document Managers’. Initially we need to get all the Item ID’s or folder ID’s which would be accessible by a SharePoint Group called ‘Document Managers’

Using the below SPServices, we can get all the Item & Folder ID’s in a JSON object

 var folderID = {};
 // Use SPServices or REST API to get all the item ID's
 $().SPServices({
     operation: "GetListItems",
     async: false,
     listName: "Shared Document",
     CAMLQuery: "<< Query based on your req. >>",
     completefunc: function (xData, Status) {
         $(xData.responseXML).SPFilterNode("z:row").each(function () {
         var folderVal = $(this).attr("ows_ID"); || '';
         if (folderVal != '') {
             var folder_ID = {};
             folder_ID["folderID"] = folderVal;
             folderID[folderVal] = folder_ID;            
         }
     }
 });
 
 //SharePoint 2010, Group can be resolved using groupID not by groupName
 //you can get the groupID value in URL after navigating to that SharePoint Group
 var groupID = 25;
 GrantAccesstoGroup(folderID, groupID)

Use the below JSOM script to grant access to SharePoint group on a specific Items.

Please note that, SharePoint Group can be resolved using groupID in SharePoint 2010. In SharePoint 2013, group can be resolved using its name as well using getByName(‘groupName’).

 function GrantAccesstoGroup(folderID, groupID){
     SP.SOD.executeFunc("sp.js", 'SP.ClientContext', AccessToGroupOnSecurityInheritance(folderID, groupID));
 }
 
 function AccessToGroupOnSecurityInheritance(folderID, groupID) {
 	var context = SP.ClientContext.get_current();
     var oList = context.get_web().get_lists().getByTitle('Shared Document');   
 	
 	$.each(folderID, function (key, value) { 	   
 		  
 		var folderID_int = parseInt(value.folderID);         
 		var oListItem = oList.getItemById(folderID_int);
 		
 		//Break Role Inheritance if u need to,
               //oListItem.breakRoleInheritance(false);	    
 	    
 		var collGroup = context.get_web().get_siteGroups();	    
 	       var oGroup = collGroup.getById(groupID);	
            
              //In SharePoint 2013 group can be resolved using by its name as well
 	      //var oGroup = collGroup.getByName(groupName);
             	    
 	    
         //Defining the Role
 	    var collRoleDefinitionBinding = SP.RoleDefinitionBindingCollection.newObject(context);	
 	    collRoleDefinitionBinding.add(context.get_web().get_roleDefinitions().getByType(SP.RoleType.administrator));	    	
 	   
 	    oListItem.get_roleAssignments().add(oGroup, collRoleDefinitionBinding);
 	   
 	    context.load(oListItem);        	
 	    context.executeQueryAsync(onQuerySucceeded, onQueryFailed);
  	});     
 }
 function onQuerySucceeded() {
 
     console.log('Access Granted to SharePoint Group');
 }
 
 function onQueryFailed() {
 
     console.log('Request failed.');
 }

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

How to perform CRUD Operation on SharePoint Library Folders and Sub Folders using SPServices and JavaScript

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Views
5347

In this article lets see how to create, read, rename OOTB Folders in a SharePoint library programmatically using JQuery and SPServices

1. To create a Folder using SPServices,

 function CreateFolder(folderName) {
     $().SPServices({
         operation: "UpdateListItems",
         async: false,
         listName: "Library Name",
         updates: "<Batch OnError='Continue' PreCalc='TRUE' ListVersion='0' >" +
       		"<Method ID='1' Cmd='New'>" +
        	  	"<Field Name='FSObjType'>1</Field>" +
        	  	"<Field Name='BaseName'>" + folderName + "</Field>" +
       	  	"</Method>" +
      	  	"</Batch>",
         completefunc: function (xData, Status) {
             console.log("Folder Created Successfully…"); 
         }
     });
 }

To create subfolder, the folderName value would be “ParentFolder/ChildFolder”.

2. To read the content inside the folder,

 function ReadFolder(folderName) {
     $().SPServices({
         operation: "GetListItems",
         async: false,
         listName: "Library Name",
         CAMLViewFields: "<ViewFields Properties='True' />",
         CAMLQuery: "<Query><Where><Contains><FieldRef Name='FileRef' /><Value Type='Text'>" + folderName + "</Value></Contains></Where></Query>",
         CAMLQueryOptions: "<QueryOptions><Folder>" + folderName + "</Folder></QueryOptions>",
         completefunc: function (xData, Status) {
             $(xData.responseXML).SPFilterNode('z:row').each(function () {
                 itemID = $(this).attr("ows_ID");                          
                 //Extract other fields as per the requirement		  	
             });
         }
     });    
 }

If the content is inside the subfolder, then we need alter the above ReadFolder(folderName) function little bit

 function ReadSubFolder(folderName, subfolder) {
 var fullFolderName = _spPageContextInfo.webServerRelativeUrl + "/Shared Document/" + folderName;
 
     $().SPServices({
         operation: "GetListItems",
         async: false,
         listName: "Shared Document",
         CAMLViewFields: "<ViewFields Properties='True' />",
         CAMLQuery: "<Query><Where><Contains><FieldRef Name='FileRef' /><Value Type='Text'>" + folderName + "</Value></Contains></Where></Query>",
         CAMLQueryOptions: "<QueryOptions><Folder>" + fullFolderName + "</Folder></QueryOptions>",
         completefunc: function (xData, Status) {
             $(xData.responseXML).SPFilterNode('z:row').each(function () {
                 itemID = $(this).attr("ows_ID");
                 var subFolderName = $(this).attr("ows_FileLeafRef").split(";#")[1];
                 if (subFolderName == subfolder) {
                     //use the same SPService in some other function and pass subfolder value
                 }
                 //Extact other fields as per your requirement
             });
         }
     });    
 }

3. To rename the specific folder,

 function RenameFolder(oldFolderName, newFolderName) {
     $().SPServices({
         operation: "GetListItems",
         async: false,
         listName: 'Library Name',
         CAMLViewFields: "<ViewFields Properties='True' />",
         CAMLQuery: "<Query><Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Eq></Where></Query>",
         CAMLQueryOptions: "<QueryOptions><IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns></QueryOptions>",
         completefunc: function (xData, Status) {
             $(xData.responseXML).SPFilterNode('z:row').each(function () {
                 var existingFolderName = $(this).attr("ows_FileLeafRef").split(";#")[1];
                 if (existingFolderName == oldFolderName) {
                     var Folder_ID = $(this).attr("ows_ID");
                     $().SPServices({
                         operation: "UpdateListItems",
                         async: false,
                         batchCmd: "Update",
                         listName: 'Library Name',
                         valuepairs: [["Title", newFolderName], ["BaseName", newFolderName]],
                         ID: Folder_ID,
                         completefunc: function (xData, Status) {
                             console.log("Folder Name Updated Successfully...");
                         }
                     });
                 }
             });
         }
     });
 }

I would prefer JSOM to delete the folder, because it is an easy way to delete.

 function DeleteFolder(folderName) {
     clientContext = new SP.ClientContext.get_current();
     oWebsite = clientContext.get_web();
 
     clientContext.load(oWebsite);
     clientContext.executeQueryAsync(function () {       
         
         folderUrl = oWebsite.get_serverRelativeUrl() + "/Library Name/" + folderName;
         this.folderToDelete = oWebsite.getFolderByServerRelativeUrl(folderUrl);
         this.folderToDelete.deleteObject();
 
         clientContext.executeQueryAsync(
             Function.createDelegate(this, successHandler),
             Function.createDelegate(this, errorHandler)
         );
     }, errorHandler);
 
     function successHandler() {
         console.log('Folder Deleted Successfully!!!');
     }
     function errorHandler() {
         console.log('Error in deleting the folder');
     }
 }
 SP.SOD.executeFunc("sp.js", 'SP.ClientContext', DeleteFolder('foldername'));

To delete the subfolder, we need to pass the folderName parameter along with the parent folder name delimited by ‘/’.

 

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

How to use Client Side Rendering (JSLink) in a SharePoint Hosted APP

Krishna KV
 
Team Leader, Aspire Systems
September 18, 2016
 
Rate this article
 
Views
11295

JSLink is a new feature that is introduced in SharePoint 2013. It is a combination of Html, javascript and css to customize the rendering of SharePoint List views and forms. It can be called as Client Side Rendering (CSR rather than writing a XSLT)

· The rendering happens in the client side, so the pages can load faster with CSR.

· Compare to XSLT, JavaScript will be easier to development and debugged.

· We can customize specific fields, header, body and footer.

Create a SharePoint hosted app.

clip_image002

clip_image004

clip_image006

Adding columns in the list.

clip_image008

Adding custom view to the list can be provide any name and select the columns to view.

clip_image010

Schema.xml under view 2 include the custom script.

 <View BaseViewID="2" Name="2757a7d6-f368-47e7-bbda-5bcfdb318b60" DisplayName="NewView" Type="HTML" WebPartZoneID="Main" SetupPath="pagesviewpage.aspx" Url="NewView.aspx">
 <ViewFields>
     <FieldRef Name="LinkTitle" />
     <FieldRef Name="StartDate" />
     <FieldRef Name="_EndDate" />
     <FieldRef Name="PercentComplete" />
     <FieldRef Name="Project" />
     <FieldRef Name="Edit" />
 </ViewFields>
 <Query />
 <Toolbar Type="Standard" />
 <XslLink Default="TRUE">main.xsl</XslLink>
 <JSLink Default="TRUE">~site/Scripts/ListRender.js</JSLink>
 </View>

Add the ListRender.js under the script folder

 (function () {
     var overrideCtx = {};
     overrideCtx.Templates = {};
     overrideCtx.Templates.Header = "<h2><#=ctx.ListTitle#></h2>" +
         "<table class='table table-striped'><tr><th>Title</th><th>Start Date</th><th>End Date</th><th>Project</th><th>Progress </th></tr>";
     // This template is assigned to the CustomItem function.
     overrideCtx.Templates.Item = customItem;
     overrideCtx.Templates.Footer = "</table>";
     overrideCtx.BaseViewID = 2;
     overrideCtx.ListTemplateType = 100;
     overrideCtx.OnPreRender = loadCss;
     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
 })();
 
 function customItem(ctx) {
     var ret = "<tr><td>" + ctx.CurrentItem.Title + "</td>";
     ret += "<td>" + ctx.CurrentItem.StartDate + "</td>";
     ret += "<td>" + ctx.CurrentItem._EndDate + "</td>";
     ret += "<td>" + ctx.CurrentItem.Project + "</td>";
     ret += "<td>" + getProgress(parseInt(ctx.CurrentItem["PercentComplete."])) + "</td></tr>"
     return ret;
 }
 
 function getProgress() {
     return  '<div class="progress">' +
             '<div class="progress-bar" role="progressbar" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100" style="width:' + value + '%">' + value + '%' +
             '</div></div>';
 }
 
 function loadCSS(ctx) {
     document.write('<link rel="Stylesheet" type="text/css" href="../../Content/bootstrap.css"/>');
 }

clip_image012

clip_image014

Author Info

Krishna KV
 
Team Leader, Aspire Systems
 
Rate this article
 
Krishna K.V has been working in IT Industry for over 7+ years. He holds a Master Degree in Information Technology. He is more interested to learn and share new technologies, ...read more
 

Deep Dive into SharePoint 2013 and JavaScript – Part 3

Ahamed Fazil Buhari
 
Senior Developer
August 13, 2016
 
Rate this article
 
Views
7608

Hi and welcome to our Part 3 article on – ‘Deep Dive into SharePoint 2013 and JavaScript’, this article is continuation of my previous article (Deep Dive into SharePoint 2013 and JavaScript – Part 2). Here we will look into REST (REpresentational State Transfer) which significantly expanded capabilities of SharePoint 2013.

REST

Before we start the architecture of REST there’s one tool I have to call out that you have to install. It’s called Fiddler and it’s an HTTP debugger. It allows to capture request and response traffic and analyze it and also it allows to create and submit new request quickly and easily which is very useful when we are doing REST programming. It’s a freeware and you can download it from here.

Let’s get into the main topic. REST is a mechanism of interacting with entities via URIs. Each resource we want to interact with has its own URI. For SharePoint this means interacting with lists, libraries, listItems and documents via URIs.

REST was introduced in SharePoint 2010 and enhanced in 2013. SharePoint REST interface is based on the OData spec and it doesn’t support the full spec.

All about URI (some simple examples):

 //Fetch List:
 http://ahamed.sp.com/_api/web/lists/GetByTitle('MyList')
 
 //Get all items from List
 http://ahamed.sp.com/_api/web/lists/GetByTitle('MyList')/items
 
 //Get Item with ID of 3
 http://ahamed.sp.com/_api/web/lists/GetByTitle('MyList')/items(3)
 
 //Page through items in List
 http://ahamed.sp.com/_api/web/lists/GetByTitle('MyList')/items?$top=10
 
 //Get all items from Lists where Score > 100
 http://ahamed.sp.com/_api/web/lists/GetByTitle('MyList')/items/?$filter=Score gt 100
 

URI structure in a REST call:

http://ahamed.sp.com/_api/web/lists/GetByTitle(‘MyList’)/items?$top=10

http://ahamed.sp.com/ -> Location (Host address)

_api/ -> Service (Alias for the full name of the service endpoint, _vti_bin/client.svc)

SharePoint URLs have 256 character limit not counting the query options, just the base URL portion. So this would save some space.

After the service, we need to specify an endpoint. There are currently 5 supported endpoints in SharePoint 2013.

Endpoints:

· Site – /_api/site

· Web – /_api/web

· User Profile – /_api/SP.UserProfiles.PeopleManager

· Search – /_api/search

· Publishing – /_api/publishing

web/lists/GetByTitle(‘MyList’)/items -> Resource path

There are hundreds of resources in SharePoint for sites, webs, lists, listitems, etc.

$top=10 -> Query Options

This is often used for filtering and limiting the fields returned and paging through the data.

· $select

· $filter

· $top/$skip

Not all OData Query operations are supported by SharePoint REST implementation.

Please refer this msdn site for OData Query operations in SharePoint 2013, https://msdn.microsoft.com/en-us/library/fp142385.aspx

HTTP Verbs:

· GET – Reading Information

· POST – Create, Update, Delete

o Verb-Tunneling – Some firewalls block all the HTTP verbs except GET and POST, it is ok for Create and Read, but there’s different approach for deletes and updates. So, here comes the use of Verb-Tunneling. It requires to submit standard POST, but we need to specify the real verb we want to use in X-Http method header.

o Body – For Create and Update we need to pass the values in the Request Body, but this is not necessary for delete.

CRUD Operation on SharePoint using REST API

Read Operation:

There are many ways to submit our request to the server, the easy way is to use JQuery Ajax function. We will now read the data using simple HTTP GET. For Ajax function, we need to give two additional things in the URL of whatever resource we are connecting to and the right HTTP header.

 $.ajax(
 {
     url: encodeURI(siteURL),
     type: "GET",
     header: {
         "accept" : "application/json;odata=verbose"
     }
 });
 
 

Results will be in JSON and the result type may differ based on the call we made. Some of the call and its result types are shown below

CallResult TypeAccessed via
_api/web/listsCollectiondata.d.results[index]
_api/web/lists/GetByTitle(“ListName”)Singledata.d
_api/web/lists/GetByTitle(“ListName”)/itemsCollectiondata.d.results[index]
_api/web/lists/GetByTitle(“ListName”)/items(id)Singledata.d
_api/web/foldersCollectiondata.d.results[index]
_api/web/GetFolderByServerRelativeUrl(‘/Lists/listname/MyFolder’)Singledata.d

· Common Query Options

o $orderby – asc or desc

_api/web/lists/GetByTitle(“ListName”)/items/?$orderby=Title asc

o $select – specify which columns to get

_api/web/lists/GetByTitle(“ListName”)/items/?$select=Title,Body

o $filter – Allows to specify criteria to filter the items

_api/web/lists/GetByTitle(“ListName”)/items/?$filter=Price gt 1000

o $top and $skip – Used for paging through large result (it doesn’t work for list items)

_api/web/lists/?$skip=10&$top=10

To skip through the items we need to make use of Paging, which is explained below

· Paging

o List Items (List Item collections)

§ SharePoint limits the size of result set for queries

§ If we are not specifying how many items we want in each page of results, then by default it will give 100 items each time.

o List Item collection use $skiptoken and specify the ID of the last item that we do not want inside our batch

$skiptoken=Paged%3dTRUE%26p_ID%3d<# to skip>&$top=<# to retrieve>

%3d -> ‘=’ signs and %26 -> ‘&’ signs

Write Operation:

First thing is we need to use POST in http type and the second thing is we need to specify the values/properties in request body (Data that we need to write to SharePoint). And the last thing is, we need to specify the Form Digest value. We don’t always have easy access to Form Digest value using jquery.

$(“#__REQUESTDIGEST”).val() [SharePoint] – This will work if we’re submitting REST from JavaScript loaded into SharePoint page i.e. a layout page, SharePoint hosted app.

If we are calling from non-SharePoint page, then we have to get Form Digest in another way. Submit POST to,

/_api/contextinfo [Remote]

Once we have Form Digest value, we can use it to submit back to SharePoint with our write operations.

Create Operation:

Provide actual values for the item that we’re creating as a JSON object in key (‘Name of the column’) – value (‘value for that column’) pair.

· Column Names

 var values  = {
 “Col1”	: ”Data1”,
 “Col2” : “Data2”,
 “__metadata” : {“type” : “SP.Data.” + <<name of the list>> + “ListItem”}
 }
 

Along with these, we need to supply another key value pair, i.e. “__metadata“ – It tells the SharePoint, what kind of item we’re creating.

Once we create this JSON object, we need to convert it into string and passed as request body.

var itemData = JSON.stringify(values);

· Request Headers

We need to have request headers, in the below context you will find the headers object for code originating from SharePoint.

 var header = {
 	“accept” : “application/json;odata=verbose”,
 	“content-length” : itemData.length,
 	“X-RequestDigest” : $(“#__REQUESTDIGEST”).val()
 }
 

Finally we pack this all and send to SharePoint, using JQuery ajax function.

 $.ajax({
 	url: encodeURI(baseurl),
 	type: “POST”,
 	contentType: “application/json;odata=verbose”,
 	data: itemData,
 	headers: headers
 });
 

This is same as Reading data except we have two properties data and type: “POST”.

Update Operation:

Updating items in SharePoint using REST is a bit different. We can use two ways here, either Http PUT or Http POST

· Http PUT:

Here we need to specify all the fields or else it will take its default value. So more common people use POST.

· Http POST:

o X-Http-Method and If-Match

In this we need to make use of Verb Tunneling which we talked about earlier in this article, and pass the value as PATCH. We do this by setting X-Http-Method header to PATCH, along with these we need to specify the fields which we need to update. The last thing is we need to tell which version we need to update, we do this with If-Match header and it is called as eTag, it is not the SharePoint version, it will work regardless of whether or not we’ve enabled version in our list or library.

When we submit a request to update an item in SharePoint, we pass the eTag that we received when we retrieved the item in the If-Match header. If no one updated the item that we retrieved, which would have caused the eTag version on the server to change, then our update will go through. If the eTag value on the server is different from the eTag that we pass, then our update will fail.

If we want to update the item on the server regardless of its eTag value or its version then we need to specify * in our If-Match header. It will match any version on the server and update it.

Delete Operation:

Delete is similar to an update. Here, we still need POST, X-Http-Method header to DELETE, IF-Match rules what we already seen in Update Operation, Content-Length value to 0 but we do not set anything in the body.

Complete basic operations SP 2013 using REST has given in the official MSDN site -> click here

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

Deep Dive into SharePoint 2013 and JavaScript – Part 2

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Views
7551

Hello everyone, this article is the continuation of my previous article (Deep Dive into SharePoint 2013 and JavaScript – Part 1). Here we will look into JSOM (JavaScript Object Model) in SharePoint.

JSOM

It was introduced in SharePoint 2010 as 1/3 of the new Client Side Object Model, CSOM. JSOM code is simply a JavaScript library that allows us to access SharePoint from client browsers. Like all JS libraries, JSOM is downloaded from the server to the browser on demand. JSOM has no authentication to execute the code, all code executes within the user context established by the browser.

JSOM is limited to current site collection.

clip_image002

Unless the cross-domain library is used, it cannot access different site collection.

From an architectural view, JSOM is made of JavaScript libraries. There are three libraries we’ll need in SP 2013 – MicrosoftAjax.js, Sp.runtime.js, SP.js all these are available via OOTB master page.

1. Batching:

It is all about performance, batching in JSOM reduces chattiness to improve performance. In the below simple example, before going into detail let’s look into the work of batching

 function doWork() {
   //Establishing the context - After the below line executes, we don't have context which      //to work - instead it is put into "batch"
     var currCtx = SP.ClientContext.get_current();
 // into "batch"
     var lists = currCtx.get_web().get_lists();
 //Not into "batch", this will execute immediately and it won’t wait for batch to be //processed
     alert("Im not in the batch");
 // into "batch"
     var myLists = lists.getByTitle("My List");
 // this executeQueryAsync doesn’t get added into the Batch, instead it cause the batch to send to the server for processing
     currCtx.executeQueryAsync(onSuccees, onFail);
 
     // more code
 }
 

clip_image004

All the JSON codes are queued up in the Batch and executeQueryAsync doesn’t get added into the Batch, instead it cause the batch to send to the server for processing. Any code coming after the executeQueryAsync will be processed immediately, it doesn’t wait for the batch result

As a part of executeQueryAsync call, there are two call back function one is for success and another one is for failure. While all this happening on the client the server receives the batch on the Client.svc REST endpoint, rips open the XML payload and begins processing it. All of the work is done by the regular Server Side Object Model interacting with the SharePoint db as required. If the server process the JSON with no unhandled exception then it will hit the onSuccees() function in the client side

clip_image005

This Batching process specifically applied only to JSON code, regular JavaScript code is not impacted by batching.

2. Client Context:

The next core concept on JSON is Client Context (SP.ClientContext). Client side code revolve around the client context. In JSOM, client context is our connection back to SharePoint. Everything begins here and everything revolves around context. One thing to be careful of is the name we use to represent client context shouldn’t be ctx, because ctx is SharePoint variable which we already seen its usage in Part -1 of this article.

3. Exceptional Handling:

Handling exception conditions is an important in any professional development effort. Unfortunately it’s one that far too often ignored in JavaScript. JavaScript natively support error handling through the same Try/Catch/Finally. This exceptional handling primarily reduces the round trip when dealing with batching and contacting the server.

 function sampleExceptionHandler() {
     var currCtx = SP.ClientContext;
     //Create instance of ExceptionHandling object and call startScope() method, indicate beginning of exceptional handling block
     _scope = new SP.ExceptionHandlingScope(currCtx);
     var_start = _scope.startScope();
 
     //Beginning of try block
     var _try = _scope.startTry();
     //attempt something that causes an error ("error list" not exists), code are inside //the try block now
     var lists = currCtx.get_web().get_lists();
     var errorList = lists.getByTitle("error list");
     //End of try block and dispose try object
     _try.dispose();
 
     var _catch = _scope.startCatch();
     //"Server side steps" to fix the error
     _catch.dispose();
 
     var _finally = _scope.startFinally();
     //**server-side actions that will always occur
     _finally.dispose();
 
     _start.dispose();
     currCtx.executeQueryAsync(onsampleExceptionHandlerSucceed, onFail);
     //last step to clean up and then call executeQueryAsync to commit the whole batch, //Try/Catch/Finally in all, up to the server to be processed.
 }
 
 

One thing we need to keep in mind when we are making use of this try catch blocks is that, this is our batch code inside this try block and it executes on the server. If we intermingle regular or non-JSOM code inside this block then it will execute immediately on the client regardless of whether or not an error actually happened.

This is how we do exceptional handling in JSOM to maintain the integrity of our batch and keep our application from being excessively chatty, even if something goes on.

Once the batch is processed in the server and send back to the client with success it doesn’t mean everything goes fine but still Success callback called. We use get_hasException function to check the hasException property of the scope, if that returns true, we know that error happened and was handled on the server as part of our batch.

function onsampleExceptionHandlerSucceed() {
var errTracker;
if (_scope.get_hasException()) {
errTracker = “Error on server was handled”;
errTracker += “\n\nError was ” + _scope.get_errorMessage();
}
else {
errTracker = “No error…”;
}
}

4. Reading Data using JSOM

We’ll start with a look at doing simple reads of information from SharePoint. As with Server OM mostly deals with webs, lists, listitems, files, and so on.

· Typical Process:

o Instantiate objects

 var currCtx = SP.ClientContext.get_current();
 myWeb = currCtx.get_web();
 lists = myWeb.get_lists();
 

o Load objects

currCtx.load(lists);

§ Trim properties requested – In this we can specify which property we want to filled up on the load statement. In the below line we’re loading web object, but just the ’Title’ and ‘ServerRelativeUrl’ properties.

currCtx.load(myWeb, ’Title’, ‘ServerRelativeUrl’);

//or Include can be used to fill up the property names

//currCtx.load(lists, ‘Include(Title,Id)’

o Commit Batch – Finally we need to commit our batch by calling – executeQueryAsync()

currCtx.executeQueryAsync(onSucceed, onFail);

o Work with properties in callback – once our batch has been committed and returned to our success callback we can begin to work with the object instantiated and the properties we asked to be filled up with their values. In the below alert statement you can see that we have used the properties which we were loaded earlier.

 function onSucceed() {
     alert("Website at " + myWeb.get_serverRelativeUrl() +
      "Title " + myWeb.get_title() + " has " + lists.get_count() + " lists.");
 }
 

· Properties

Properties must be requested before being referenced, if it is not then we’ll get a PropertyOrFieldNotInitilized Exception.

When we fill up an object via the load function it’s reasonable to expect that if we don’t limit properties that are filled up that they’re all going to be populated, but unfortunately it won’t work that way. Some properties are not filled up when we just call load without specifying which properties we want to populate.

· Scalar Properties

Only the Scalar properties are populated by default, Scalar properties are those that return – Bool, DateTime, String, Byte, Number, Char, Guid, Array of any of the above. Client Objects and Collections (Non scalar properties) should be explicitly requested.

· CAML Query

One of the most common approach for getting to one or more list items is the same approach we’d use in Server side code, a straightforward CamlQuery.

 var currCtx = SP.ClientContext.get_current();
 myWeb = currCtx.get_web();
 lists = myWeb.get_lists().getByTitle('TestList');
 var query = new SP.CamlQuery();
 query.set_viewXml("<View><Query><Where><Contains><FieldRef ..."+
                     +"..</Contains></Where></Query></View>");
 listItems = lists.getItems(query);
 currCtx.load(listItems);
 currCtx.executeQueryAsync(onSuccess, onFail);
 

5. Security in JSOM

One of the nice things about JSOM in SharePoint 2013 is the ability to interact with the security infrastructure of SharePoint. This is useful in managing security, setting permissions, managing users and groups, etc., the ability to check security asynchronously and present or update the UI accordingly is a huge capability. Here we start with simply security check using JSOM,

 function checkIfUserHasPermissions() {
 var currCtx = SP.ClientContext();
 myWeb = currCtx.get_web();
 //getting only the EffectiveBasePermission property from the web
 currCtx.load(web, 'EffectiveBasePermission');
 currCtx.executeQueryAsync(onSuccess, onFail)
 }
 
 function onSuccess() {
     //perms variables holds the SP Permission property value
     var perms = SP.PermissionKind.editListItems || SP.PermissionKind.fullMask;
 //get_effectiveBasePermission() function on web object which returns an SP.basePermissions obj that includes has() function
     if(web.get_effectiveBasePermission().has(perms)){
      alert("has permission");
     }
     else{
         alert("no permission");
     }
 }
 

While folder is a securable object in SharePoint, there’s no direct way to work with folder level permission in JSOM. Similar to the Server-Side object model, the way that we do will get the folder object as a list item. Once we have the list item that represents the folder, we can work with the permissions that way.

Security in Apps – Security programming and in fact, security in general is very different in apps when compared to regular SharePoint sites. The app security model is focused more on app and user specific permissions as opposed to groups. In an app web it is possible to add user permission directly or add new groups permissions, however it’s not possible to create or delete groups or add users to an existing group, which severely limits the possibilities for managing security in an app.

End of Part 2.

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

Deep Dive into SharePoint 2013 and JavaScript – Part 1

Ahamed Fazil Buhari
 
Senior Developer
August 12, 2016
 
Rate this article
 
Views
13085

Hello everyone, in this article we will see the relationship between SharePoint 2013 and JavaScript from scratch to end.

You might be an expert in SharePoint or expert in JavaScript but still some people have doubt that, what’s this JavaScript doing inside the SharePoint. If you have that doubt too, then you are at the right place to kick that doubt out of your head. I know that, it is too late to share about basic stuff related to SP 2013 in the year 2016, but still it’s worth sharing.

Ok let’s get into the business. Microsoft has promoted JavaScript to a first-class language with the release of SharePoint 2013, so that all SharePoint Developers must be comfortable.

In SP 2013, not only the App-Model changed the development landscape but additional capabilities across the product make the JavaScript an even more important skill for SharePoint developers.

Please make a note of these good practices and learn the below stuffs before you are writing JavaScript programming in SharePoint, definitely it will be helpful:

JavaScript namespace – In JavaScript, by default all the code loaded into the memory are tossed into a single big bucket called Global Namespace. Every variables, every functions and everything go inside the Global Namespace. There might be a chance we run into the risk of having conflicts between all of these names. If you are using jQuery, make use of jquery.noconflict() mode.

JSON – An Important element to understand is JSON (JavaScript Object Notation). JSON is a subset of the whole JavaScript object literal notation. In real-world, it is more on Data-Exchange. These are Key-Value pairs, separated by commas and wrapped in curly braces.

Promises in JavaScript – Promises are pretty advanced topic in JavaScript, but it facilitate clean code when you’re doing asynchronous programming like almost everything we do in SharePoint JavaScript. It allow to control over asynchronous call and related interactions. Some of the important functions in Promises are,

.then – Take action upon success/failure of a function.

.always – This always gets called, whether it was a success or failure.

.when – wait until all actions complete before performing another action (it is non-blocking operation and it supports both success and fail triggering).

To know more about Promise please refer here.

Strict Mode – If you’re using JavaScript and not using strict mode it’s harder to guarantee that things will end up where you want them to end up. Strict mode enforces a better flavor for JavaScript, this is option explicit mode from VB. It is easy to setting up Strict Mode, just add literal string “use strict” to your code. It can be entered at Library level or Function level. It prevents a lots of dumb mistake (for example: var abc = “1”; // strict mode

abc = “1” // not strict mode

JavaScript Development Tools

· Visual Studio Add-ons

o Web Essential 2012

o JavaScript Parser for Visual Studio (simple plugin used to find your way around large JavaScript files)

o JSLint for Visual Studio (code analysis for JavaScript).

· JSON Viewer

o https://jsonviewer.codeplex.com/

I am not explaining much on the above mentioned stuffs, because all those will lead to separate topic and it will divert from our main topic. So, I’m leaving it to the developers to learn by their own.

Out of the box SharePoint JavaScript environment:

1. SharePoint JavaScript

2. Variables

a. Context (ctx)

b. PageContext

3. Utilities

a. List Views

b. URL Manipulation

c. General Utilities

1. SharePoint JavaScript:

At a high level, SharePoint is just an ASP.Net web application like any other web application, it relies on client side scripting via JavaScript to deliver richer, more engaging user experiences. SharePoint has an extensive library of JavaScript used to deliver the experience we get out of the box. In the LAYOUTS directory there are around 170 JavaScript files.

The default SharePoint master page loads 5 js files (Core.js, Menu.js, Callout.js, Sharing.js, and SuiteLinks.js)

image

These files are loaded by using ScriptLink tag and using attribute OnDemand=”true”, so that these files are downloaded only if there’s a need.

Other common JavaScript libraries used across SharePoint include Init.js (more utility functions), SharePoint.js (main library for JavaScript Object Model – JSOM).

Many of the JavaScript files comes in SharePoint are in 2 flavors,

(*.js) Production and (*.debug.js) Debug.

Production – These files have the names what we would expect example: init.js, core.js etc and they are minified to reduce their size.

Debug – These have the same base name core, init, menu, whatever, but then debug.js instead of just .js so core.debug.js, menu.debug.js etc and these files that we want to work with if we need to debug.

2. Variables:

These variables represents an object that provides a lot of really useful information about the current context in which our code is running.

a. Context or ctx:

It provides wealth of information about the current page and the current environment. It won’t be available on all the pages, in general it’s not available on form pages (new, edit, display) and not available on layouts, site settings, administration pages etc. and also not available on apps unless we’re inside of a list. It is mainly available in Lists View pages.

image

v This variable is read-only and updating this variable has no effect. Some of the useful properties of the context (ctx) object includes

Ø List Data – gives us information about the items shown in the ListView web part on the current page. The data will be available only when we are viewing a list.

i. List View only

ii. Row collection property:

1. Column values

2. Row is 0-based, based on display, not item ID

3. ContentTypeId

4. FSObjType(0=ListItem, 1=Folder)

image

iii. Form URLs

1. displayFormURL

2. editFormURL

3. newFormURL

iv. ListTitle

v. ListURL

vi. ListGUID

vii. ListSchema

1. IsDocLib

2. Field Information

3. LocaleID

4. PagePath

viii. HttpRoot

1. BaseURL

ix. imagesPath

1. Relative Url to Images directory

It is good to make use of the Context (ctx) variable when there is only one ListView on the page.

b. _spPageContextInfo

It is pretty much similar to ctx variable and it is available on most of the pages like Layouts, site pages, apps etc. This provide access to lot of useful information, like current user, site, lists, pages etc.

Demo on SharePoint OOTB JavaScript Variables:

image

You can see lots of useful information available inside this ctx object, but I think that the most useful is if we need to go ahead and get the actual data values that are displayed inside the list view.

We do that inside the ListData Property, specifically inside the Row property of ListData. Each items are show inside this Row property in an array fashion.

document.location.href = SetUrlKeyValue("ID", "3", true, ctx.editFormUrl)

SetUrlKeyValue – This function allows us to specify the name or key value pair on the query string that we’re going to redirect the user.

In this example we want to specify the ID of 3, so that when we get the Edit form itself for that ID.

Here is the another example, with _spPageContextInfo variable

 var verUI;
 switch (_spPageContextInfo.webUIVersion) {
     case 12:
         verUI = "SharePoint 2007";
         break;
     case 14:
         verUI = "SharePoint 2010";
         break;
     case 15:
         verUI = "SharePoint 2013";
         break;
     default:
         verUI = "Unknown";
         break;
 }
 var msg = "Welcom to " + _spPageContextInfo.webTitle + ". You are browsing the site in " + _spPageContextInfo.currentCultureName + " using the " + verUI + " user interface";
 alert(msg);
 

Output:

image

3. Utilities – List View OOTB functions:

SelectAllItems, DeselectAllItems, CountSelectedItems(ctx), SelectRowByIndex(ctx,idx,addToSelection), GetListItemByID(ctx, id)

Selecting Items which has Odd Item ID.

 function selectItem() {
     clearAll();
     //Loop through each of the items using ctx.ListData.Row.length
     for (var i = 0; i < ctx.ListData.Row.length; i++) {
         //Selecting only odd ID number items
         if (parseInt(ctx.ListData.Row[i].ID) % 2 !== 0) {
             //Select that row using OOTB function
             SelectRowByIndex(ctx, i, true);
         }
     }
 }
 
 function clearAll() {
     var clvp = ctx.clvp;
     var tab = clvp.tab;
     //OOTB function to deselect the items
     DeselectAllItems(ctx, tab.rows, false);
 
 }
 
 //Function to show the Item tab in the ribbon
 function showItemTab() {
     ribbon = SP.Ribbon.PageManager.get_instance().get_ribbon();
     SelectRibbonTab("Ribbon.ListItem", true);
 }
 
 selectItem();
 var itemCount = CountSelectedItems(ctx);
 alert("There are " + itemCount + " selected items selected");
 showItemTab();
 

var itemCount = CountSelectedItems(ctx);

alert("There are " + itemCount + " selected items selected");

showItemTab();

image

SP.Utilities.Utility object (sp.js) –

Few examples:

alert(SP.Utilities.Utility.getLayoutsPageUrl("SiteSetting.aspx"));

To get the layout page:

image

To navigate within the modal dialog box:

<a onclick=’SP.Utilities.HttpUtility.navigateTo(“url”)’> click to navigate inside </a>

To know more about this utility function please refer to this msdn link. We end this Part 1 here

Happy Coding

Ahamed

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

SharePoint online CRUD Operation using pnp-JS-Core

Krishna KV
 
Team Leader, Aspire Systems
July 25, 2016
 
Rate this article
 
Views
15921

The Patterns and Practices JavaScript Core Library is an open source project which helps the developers to simplify the code instead of writing multiple lines of code for the common SharePoint operations. It was written in typescript; we can use this to develop the application using typescript / JavaScript

To know more about the PNP JS core https://github.com/OfficeDev/PnP-JS-Core

Before starting the code and we should have the below JS Files.

Fetch.js https://github.com/github/fetch/blob/master/fetch.js

es6-promise.js https://github.com/stefanpenner/es6-promise/blob/master/dist/lib/es6-promise.js

pnp.js https://github.com/OfficeDev/PnP-JS-Core/blob/master/dist/pnp.js

angular JS.

Alternatively, we can use npm package “npm install sp-pnp-js –save-dev”

Angular Service (PNP)

 (function () {
     app.service('appService', ['$http','$q',function ($http,$q) {
         function getUrlParamByName(name) {
             name = name.replace(/[[]/, "\[").replace(/[]]/, "\]");
             var regex = new RegExp("[\?&]" + name + "=([^&#]*)");
             var results = regex.exec(location.search);
             return results === null ? "" : decodeURIComponent(results[1].replace(/+/g, " "));
         }
         var appWebUrl =getUrlParamByName("SPAppWebUrl");
         var hostWebUrl =getUrlParamByName("SPHostUrl");
 
         this.getProjects=function() {
             var d = $q.defer();
             $pnp.sp.crossDomainWeb(appWebUrl, hostWebUrl).lists.getByTitle('Projects').items.get().then(function(response) {
                 d.resolve(response);
             });
           return d.promise;
         }
 
 
         this.addProject=function(project) {
             var d = $q.defer();
             $pnp.sp.crossDomainWeb(appWebUrl, hostWebUrl).lists.getByTitle('Projects').items.add(project).then(function(response) {
                 d.resolve(response);
             });
             return d.promise;
         }
 
         this.deleteProject=function(id) {
             var d = $q.defer();
             $pnp.sp.crossDomainWeb(appWebUrl, hostWebUrl).lists.getByTitle('Projects').items.getById(id).delete().then(function (response) {
                 d.resolve(response);
             });
             return d.promise;
 
         }
 
         this.updateProject = function(project) {
             var d = $q.defer();
             $pnp.sp.crossDomainWeb(appWebUrl, hostWebUrl).lists.getByTitle('Projects').items.getById(project.Id).update({Technology:project.Technology}).then(function (response) {
                 d.resolve(response);
             });
             return d.promise;
         };
     }]);
 })();

Angular Controller

 (function () {
     app.controller('projectCtrl', ['$scope', 'appService', function ($scope, appService) {
         $scope.title = "test";
         
         $scope.getProjects = function () {
             appService.getProjects().then(function(response) {
                 $scope.title = "welcome";
                 $scope.projects = response;
             });
         };
 
         $scope.addProject = function() {
             appService.addProject($scope.project).then(function(response) {
                 $scope.getProjects();
                 $scope.project = {};
             });
         };
 
         $scope.deleteProject=function(id) {
             appService.deleteProject(id).then(function(response) {
                 $scope.getProjects();
             });
         }
 
         $scope.updateProject = function(project) {
             appService.updateProject(project).then(function(response) {
                 $scope.getProjects();
             });
         };
 
         $scope.getProjects();
 
     }]);
 })();

Default.aspx

 <asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
     <script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
     <meta name="WebPartPageExpansion" content="full" />
     <link href="../Content/bootstrap.css" rel="stylesheet" />
     <script src="../Scripts/angular.min.js"></script>
     <script src="../Scripts/fetch.js"></script>
     <script src="../Scripts/es6-promise.min.js"></script>
     <script src="../Scripts/pnp.js"></script>
     <script src="../App/app.module.js"></script>
     <script src="../App/app.service.js"></script>
     <script src="../App/project.ctrl.js"></script>
 </asp:Content>
 <asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
 </asp:Content>
 
 <asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
     <div data-ng-app="projectApp">
         <div data-ng-controller="projectCtrl">
             <table class="table table-bordered">
                 <thead>
                     <tr>
                         <th>Project</th><th>Client</th><th>Technology</th>
                     </tr>
                 </thead>
                 <tbody>
                     <tr ng-repeat="project in projects">
                         <td>{{project.Title}}</td><td>{{project.Client}}</td>
                
                         <td>
                             <div class="col-sm-6">
                                 <input type="text" ng-model="project.Technology" class="form-control" /></div>
                             <button type="button" class="col-sm-2 btn-default" ng-click="updateProject(project)">Update</button>
                             <button type="button" class="col-sm-2 btn-default" ng-click="deleteProject(project.Id)">Delete</button>
                         </td>
                     </tr>
                 </tbody>
                 <tfoot>
                     <tr>
            <td><input type="text" class="form-control" ng-model="project.Title" /></td>
            <td><input type="text" class="form-control" ng-model="project.Client" /></td>
            <td><div class="col-sm-10">
            <input type="text" class="form-control" ng-model="project.Technology" />
                             </div>
          <button type="button" class="col-sm-2 btn-default" ng-click="addProject()">Add</button>
                         </td>
                     </tr>
                 </tfoot>
             </table>
         </div>
     </div>
 </asp:Content>

image

Author Info

Krishna KV
 
Team Leader, Aspire Systems
 
Rate this article
 
Krishna K.V has been working in IT Industry for over 7+ years. He holds a Master Degree in Information Technology. He is more interested to learn and share new technologies, ...read more
 

CRUD Operation on various field Types in SharePoint List using SPServices – SharePoint 2013

Ahamed Fazil Buhari
 
Senior Developer
June 7, 2016
 
Rate this article
 
Views
10701

In this article, let us see some of the basic operations on various field types in SharePoint List using SPServices.

Before dealing with SPServices in SharePoint 2013, Let us go through the definitions of SPServices from MSDN

– SPServices is a jQuery library which abstracts SharePoint’s Web Services and makes them easier to use.

– It also includes functions which use the various Web Service operations to provide more useful (and cool) capabilities.

– It works entirely client side and requires no server install.

Here, you can find Create operation on different SharePoint field types namely –

· Single line of text

· Multiple line of text

· Date

· People picker

· Lookup (Single & Multiple)

· Choice.

In this article, let us have a look on the Item Creation: The rest of the operations, I am leaving to the readers.

 var valuePair = []; //Array variable to hold all the Field_Internal_Name and its value.
 valuePair.push(["Column_Text1_InternalName", colText1]); 
 //Single line of text field
 valuePair.push(["Lookup_single_InternalName", Lookup_FieldID +';#'+LookupText]); 
 //Lookup field
 // Lookup_FieldID -> ID of lookup list item which has been selected
 // LookupText -> Text of lookup list item which has been selected
 var isoDate = {extracted_Date}.toISOString(); //Date Field
 //convert the date value into ISOString() format which is understandable by SharePoint
 valuePair.push(["Date_InternalName", isoDate]);
 var peoplePicker = $("[id$='PeoplePicker_ID']>span>div").attr("key"); 
 // People picker field
 var userID = null;
 $().SPServices({
     operation: "GetUserInfo",
     async: false,
     userLoginName: peoplePicker,
     completefunc: function (xData, Status) {
         $(xData.responseXML).find("User").each(function() {
             userID = $(this).attr("ID");
         });
     }
 });
 valuePair.push(["Peoplepicker_InternalName, userID]);
 //SPServices accepts User ID for people picker field while creation of new item
 valuePair.push(["Lookup_multiple_InternalName", Lookup_FieldID1 +';#'+LookupText1 + ';#' + Lookup_FieldID2 + ';#' + LookupText1 ]);
 // LookupText -> ID of lookup list item which has been selected
 // LookupText -> Text of lookup list item which has been selected
 //To save multiple lookup field -> append ‘;#’ after every ID, text and next value
 
 //SPServices to Create an Item.
 $().SPServices({
     operation: "UpdateListItems",
     async: false,
     listName: "Name of the list",
     batchCmd: "New",
     valuepairs: valuePair,
     completefunc: function (xData, Status) {
         if (Status != "success" || $(xData.responseXML).find('ErrorCode').text() !== "0x00000000") {
             alert("Error in saving the item.");
         }
         else {
             if (Status == "success") {
                 alert("Item created successfully...");
             }
         }
     }
 });	
 

Though this is very straight forward, this will save a lot of development effort for sure.

Click HERE to download the SPService JQuery Plugin.

Happy Coding,

Ahamed Buhari

Author Info

Ahamed Fazil Buhari
 
Senior Developer
 
Rate this article
 
Ahamed is a Senior Developer and he has very good experience in the field of Microsoft Technologies, especially SharePoint, Azure, M365, SPFx, .NET and client side scripting - JavaScript, TypeScript, ...read more
 

Scroll to the Mandatory Field validation – Issue with Iframe – ScrollinToView- JavaScript

Sathish Nadarajan
 
Solution Architect
April 20, 2016
 
Rate this article
 
Views
7206

Recently met with a strange small issue like setting up the focus. In one of the project, I have the AppPart and an lengthy App hosted inside that. Hence, both the SharePoint Site as well as the AppPart is having the Scroll Bars as shown in the figure.

clip_image002

Now, the issue was like at the bottom of the app, I have a submit button and on click of the submit button, the scroll should move up and focus should be set on the mandatory fields, which were not given the inputs. I tried with the asusual focus methods and the setfocus etc.,

But everything was working with the normal pages. But when I deploy inside this iFrame, nothing works. And the most important thing is, the SharePoint and the AppWeb are hosted on different domains. Since the document.domain differs, we cannot call the DOM Object.

While doing some googling, found a solution for this issue. The native JavaScript code will be very much helpful for this scenario.

Just a small div surrounding the control. Then we need to use the method scrollIntoView().

 if (($("#ddlDate").val() === "") || ($("#ddlDate").val() === "null")) {
                  document.getElementById("divDueDateCtrl").scrollIntoView();
                  
              }
 

Though it seems very small, it ate some hrs of my time to fix.

Happy Coding,

Sathish Nadarajan.

Category : JavaScript, SharePoint

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

How to Get User Profile Properties in SharePoint 2013 using JavaScript

Sathish Nadarajan
 
Solution Architect
December 13, 2015
 
Rate this article
 
Views
25760

In one of the recent requirement, I was about to render the User Profile Information on an Item Display Template. In that case, I don’t have any other option apart from querying the User Profile Service Application using the PeopleManager Class from the JavaScript. Let us have a quick close look on it.

 $.ajax({
         asynch: false,
         url: location.protocol + "//" + location.host + "/SiteCollectionURL/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='" + username + "'",
         method: "GET",
         headers: { "Accept": "application/json; odata=verbose" },
         success: function (data) {
          
         if (data.d.UserProfileProperties.results.length > 0) {
                     for (var i = 0; i < data.d.UserProfileProperties.results.length; i++) {
                        
                         if (data.d.UserProfileProperties.results[i].Key === "WorkPhone") { workPhone = data.d.UserProfileProperties.results[i].Value; }
                         if (data.d.UserProfileProperties.results[i].Key === "Title") { designation = data.d.UserProfileProperties.results[i].Value; }
                         if (data.d.UserProfileProperties.results[i].Key === "FirstName") { firstName = data.d.UserProfileProperties.results[i].Value; }
                         if (data.d.UserProfileProperties.results[i].Key === "LastName") { lastName = data.d.UserProfileProperties.results[i].Value; }
                         if (data.d.UserProfileProperties.results[i].Key === "WorkEmail") { email = data.d.UserProfileProperties.results[i].Value; }
     
                         
                     }
                 }
     if (data.d.PictureUrl !== null) { photo = data.d.PictureUrl; }
 
      
 
     },
     error: function (x, y, z) {
                 alert(JSON.stringify(x) + 'n' + JSON.stringify(y) + 'n' + JSON.stringify(z));
             }
 
         });
 

The only key thing here is, we cannot retrieve directly by using the Key. We need to loop through the available properties and make sure that the Key is equal to our expected Property, then take the Value.

If someone knows a method directly fetching that, please post it here.

 

Happy Coding,

Sathish Nadarajan.

Author Info

Sathish Nadarajan
 
Solution Architect
 
Rate this article
 
Sathish is a Microsoft MVP for SharePoint (Office Servers and Services) having 15+ years of experience in Microsoft Technologies. He holds a Masters Degree in Computer Aided Design and Business ...read more
 

Leave a comment