Thursday, June 26, 2014

SharePoint 2013 ClientPeoplePicker Using REST

One of the benefits of using the SPRemoteAPIExplorer extension  is you can run across functionality that you did not know existed in the SharePoint REST API. Many developers use CSOM/JSOM to implement the PeoplePicker in their applications.  Both Richard diZerega’s  Real World Apps for SharePoint 2013 and Jeremy Thake’s  Using Multiple PeoplePickers in SharePoint 2013 Hosted Apps with AngularJS are great articles explaining how to do this using JSOM.  Many developers have asked if there is a simpler way of implementing a PeoplePicker without having to load the dependent JavaScript files.  This has been difficult with provider hosted apps since by default it does not include  an app web. You can get a sample of how to add  the people picker control to a provider hosted app from the Office App Model Samples v2.0 in the Components\Core.PeoplePicker folder AMS App Model Samples.  There is also the experimental office widget that implements a people picker control for provider hosted apps Widgets for Provider Hosted Apps. The good news is that you can implement your own people picker using the “_api/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser” endpoint along with jquery-UI. It does not require having to load any of the dependent js files and makes it very easy to implement multiple people pickers. In this post I will show you sample code on how you can set up one ajax rest function to service mulitple jquery-ui autocomplete text boxes. The endpoint gives you maximum flexibility on how to control the searching for users and I will explain what each parameter means.

Picking Apart the People Picker

The above shows two jquery-ui  autocomplete text boxes both using the same function to suggest people. The first box is configured to allow suggesting users and groups and the second one only allows suggesting users.  This was easy to implement by just adding two input elements to page and then in the javascript attaching the function to do the search using jquery-ui.

$(document).ready(function () {
$("#txtPeoplePicker").autocomplete({
source: search,
minLength: 2
});
$("#txtPeoplePicker2").autocomplete({
source: search,
minLength: 2
});
});

The code below shows the search function that is called which is using the REST API to get the suggestions. Note that I added a principalType attribute to each html input element to allow changing the behavior of the of what is returned. You can add as many attributes you want and use them in your function to change any of the query parameters.

function search(request,response) {
var appweburl = decodeURIComponent(getQueryStringParameter('SPAppWebUrl'));
var hostweburl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));

var restSource = appweburl + "/_api/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser";
var principalType = this.element[0].getAttribute('principalType');
$.ajax(
{
'url':restSource,
'method':'POST',
'data':JSON.stringify({
'queryParams':{
'__metadata':{
'type':'SP.UI.ApplicationPages.ClientPeoplePickerQueryParameters'
},
'AllowEmailAddresses':true,
'AllowMultipleEntities':false,
'AllUrlZones':false,
'MaximumEntitySuggestions':50,
'PrincipalSource':15,
'PrincipalType': principalType,
'QueryString':request.term
//'Required':false,
//'SharePointGroupID':null,
//'UrlZone':null,
//'UrlZoneSpecified':false,
//'Web':null,
//'WebApplicationID':null
}
}),
'headers':{
'accept':'application/json;odata=verbose',
'content-type':'application/json;odata=verbose',
'X-RequestDigest':requestDigest
},
'success':function (data) {
var d = data;
var results = JSON.parse(data.d.ClientPeoplePickerSearchUser);
if (results.length > 0) {
response($.map(results, function (item) {
return {label:item.DisplayText,value:item.DisplayText}
}));
}
},
'error':function (err) {
alert(JSON.stringify(err));
}
}
);


}

Working with the response


Unfortunately, the response from the REST call is a string. Typically, all the REST responses in SharePoint will return objects as entities and complex types. In this case the object is a string. At first I thought I was going to have to use the context.parseJSONObject call from CSOM but you can just use JSON.parse and it will create the JSON object array. The response is undocumented. I am hoping Microsoft will expose this within the EDM model in future versions. I already voted for this on user voice UserVoice. Below is an example of what is returned.



Element number 5 is a user and Element 6 represents a SharePoint group. Note the EntityData is different.  The code just uses the DisplayText property to set both the return label and value used by jquery-ui.


What about all those parameters?


The REST API gives you many options to affect the results  a search using the ClientPeoplePickerQueryParameters object. Trying to figure out how these parameters affected searching  was daunting. Many of the parameters only apply to the people picker control but you can use them when implementing them with your own control. I will try to explain each.

AllowEmailAddresses: This is for the people picker control  and allows valid email addresses to be resolved and used as values. It has no effect on the search.

AllowMultipleEntities: This for the people picker control and allows for entering multiple users or groups. It has no effect on the search.


AllUrlZones: Only affects the search if you have set the WebApplicationID. It search across all UrlZones for that particular web application.


MaximumEntitySuggestions: Basically a row limit of how many users or groups are returned.


PrincipalSource: What sources you wish to search. Choices are  All - 15 , Membership Provider - 4 , RoleProvider - 8, UserInfoList - 1  or Windows - 2. These values can be combined.


PrincipalType: Controls the type of entities that are returned in the results. Choices are All - 15, Distribution List - 2 , Security Groups - 4,  SharePoint Groups – 8, User – 1. These values can be combined.


QueryString: The term to search


Required: This is for the people picker control and makes the field required. It has no effect on the search


SharePointGroupID: An integer representing the group ID you want to limit your search to. Only works if you set the Web parameter also which cannot be done via REST.


UrlZone: Limits the search to certain zones within the web application. Can only be used if the UrlZoneSpecified  parameter is set to true. Choices are Custom - 3, Default - 0, Extranet - 4, Internet – 2, IntraNet – 1. These values can be combined.


UrlZoneSpecified: Sets whether you are limiting your search to a particular URL zone in the web application.


Web: If set it works in conjunction with the SharePointGroupID parameter.


WebApplicaitonID: String value representing the Guid of the web application you want to limit your search to.


Easy PeoplePicker Functionality Using REST


Using the SharePoint REST API makes it easy to implement people picking. No need to struggle with the loading of dependent JavaScript files and you get better control over the behavior of the people searching. Finally you can easily use one function to service as many html inputs as you want.

Wednesday, June 4, 2014

Understanding SharePoint 2013 REST API Responses

Technorati Tags: ,,,,

I have been using the SPRemoteAPIExplorer Visual Studio Extension a lot. It has been a great help in understanding what inputs are required when making endpoint calls. Of course it is incredibly easy to generate the actual jQuery code with the new 2.0 feature.  However, something was missing. When I started using REST the more I discovered that the responses sent back were difficult to navigate. It took multiple steps to visualize what the responses looked like using either the browser developer tools or the new Visual Studio JSON visualizer. This was slowing down my development. It would be nice to know what to expect from a REST call so I could write the code to get what I wanted. The MSDN documentation is getting better but the response documentation is sparse, or the JSON shown is hard to understand. So to make my REST development much more productive I decided to add the responses for remote calls to the SPRemoteAPIExplorer in version 2.5. I also added the ability to copy the JSON path from a response to so you can copy it directly into your code. Having to remember the deeply nested JSON path of a response property can be daunting and error prone since the JSON path is case sensitive. For example, the REST response from the postquery method when searching returns an undocumented complex type. This type has many nested complex types. Trying to figure out where or if the data in a response exists could be an hour long web search or a lot of stepping through code and using visualizers. This can be much easier.

 

Copy the JSON Path

You can right click on any part of a response and select the “Copy Response Path” menu item. This will generate the JSON path to be used in your code. This feature is immensely helpful if you don’t know the rules of how different response types are returned. For example all “multivalue” types are returned as object arrays in JavaScript. The items are always included in an array named “results”.  Multivalued types include “Feeds”, “Arrays” and “Collections”. All three of these types are possible responses in the SharePoint Remote API.  Another unknown rule when getting JSON responses is that the method name is included in the JSON when the response is either a complex type or a primitive type. The example below shows that the “postquery” method name is appended because it returns a complex type.

Here is the output:

data.d.postquery.PrimaryQueryResult.RefinementResults.Refiners.results[0].Entries.results[0].RefinementCount

REST Response Types

Rest responses come in three flavors. Below are the icons used to display them in the response. Each type has a corresponding “multivalued” icon.

Primitives of course are string, integers, boolean and date. Complex types are types that are not defined in the entity model but are used as parameters to methods or returned in responses. Entities are the entities defined in the SharePoint Remote API model and can have both properties and methods. Entities returned as arrays or collections are considered feeds. When expanding any of the multivalued type icons you will see the properties of the underlying child item and not the properties of the collection itself.

The Complexity of Responses

As you use this tool you will discover that complex types can be embedded in entities. Many of the complex types are undocumented and internal within the object model. This tool will give you 99% reliable and accurate information on how to use and consume the SharePoint Remote API.  The other 1% like a “DataTable” in the Table property of a RelevantResult returned by search are hard coded and are not exposed. I am working on fixing that. In the meantime, with this release I have also fixed the generation of $ajax jQuery calls for methods that are tagged as “IntrinsicRestFul”. These method types were discussed in a previous post. Intrinsic RestFul. SPRemoteAPIExplorer has made my REST API coding incredibly productive. With the new Response and Response Path features it should be even easier for you.