UserProfiles

SharePoint 2013: Display a User with Presence Indicator in a Custom WebPart

When building a custom WebPart that displays users, I wanted to show the Users as displayed in the people Search. screen1

Just a Picture with a small Presence indicator stroke on the left side. This is how Lync shows users as well. It's possible to use SharePoint JS functions to Render a User like this.

Getting User Data

To render a User the SharePoint 2013 way we need some Contextual Information about the User we want to display. For showing Presence we need the User’s SipAddress. Besides that I want to show the Profile Picture and the Preferred Name. With the new Search REST Api there are lots of easy ways to do this. In this example I'm using Search to retrieve some users based on a Profile Property. My REST Url is as follows:

"https://casvaniersel.sharepoint.com/_api/search/query?querytext='Department=ICT'&sourceid='b09a7990-05ea-4af9-81ef-edfab16c4e31'&rowlimit='100'&selectproperties='FirstName, LastName, PictureURL, SipAddress, PreferredName, WorkEmail'"

I'm looking for people that have their Department property filled with "ICT". The sourceid is the GUID of the Default Result Source "Local People Results" (This is a fixed GUID same for On Prem and SharePoint Online). With selectproperties I can indicate what I want to get back from Search.

Handle Search Results from REST

The result object is a very complex object that needs some parsing. Even when using selectproperties, still some overhead is coming into the results. To get the correct Values based on the Fieldnames we can use the jQuery.grep() function to query the object array and get back the correct values. I use this function:

getValueByKey: function (key, results) { var postItem = jQuery.grep(results, function (e) { if (e.Key === key) return e; })[0].Value;

return postItem; }

The results argument is the Object Array that holds the results, the key argument is the Property Name of which we need the Value.

Next: Create a User Context

To render the User I use a SharePoint function "RenderUserFieldWorker(renderCtx, fieldSchemaData, userData, listSchema)". This function is available in the clienttemplates.js. First we have to Ensure that script file and then create the rendering. This script makes sure everything is in place.

EnsureScriptFunc("clienttemplates.js", "RenderUserFieldWorker", function () { ULS2Vv:; //Parse Results var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results; for (i = 0; i < results.length; i++) { //Get the correct properties var item = results[i]; var itemCell = item.Cells; var itemResults = itemCell.results; //Get Values for User var sip = getValueByKey("SipAddress", itemResults); var userPic = getValueByKey("PictureURL", itemResults); var fullname = getValueByKey("PreferredName", itemResults); var lastname = getValueByKey("LastName", itemResults); var email = getValueByKey("WorkEmail", itemResults); //Use SharePoint Render Template to render User with Presence var renderCtx = new ContextInfo(); renderCtx.Templates = {}; renderCtx.Templates["Fields"] = {}; var fieldSchemaData = { "PictureOnly": "1", "PictureSize": "Size_72px" }; var listSchema = { "EffectivePresenceEnabled": "1", "PresenceAlt": "User Presence" }; var userData = { "title": fullname, "email": email, "picture": userPic, "sip": sip }; var user = RenderUserFieldWorker(renderCtx, fieldSchemaData, userData, listSchema); } //Enable Presence ProcessImn(); )};

The variable user now contains the HTML to render a User’s profile picture with the Presence Stroke. The final step to activate the Presence is the function ProcessImn(). That function makes sure that all Presence Controls on the Page are showing the latest status.

The Presence only becomes available when you have Lync setup correctly. For Office 365 use the Desktop Setup to accomplish this. https://portal.microsoftonline.com/OLS/mysoftware.aspx?source=ehome

Download a complete example right here!

SharePoint 2013 Hosted App Part III

In my Previous posts I created an App that retrieved data from a public website. SharePoint 2013 Hosted App SharePoint 2013 Hosted App Part II

I used that data and added it to my App List in SharePoint. In this post I will explain how we also can interact with our personal Timeline using the App Framework. If a song is added to the Playlist, an update is posted on the users Timeline.

App Permissions

All interactions between an App and the App-Host are restricted with certain permissions. These permissions can be set in the AppManifest.xml. A good reference to check which Permissions you’re going to need is MSDN: http://msdn.microsoft.com/en-us/library/fp142383(v=office.15).aspx

To Read and Write from/to the Personal Timeline we need 2 specific permissions in 2 different scopes. Reading from the Timeline needs ‘Read’ permissions with Scope ‘User Profiles’. Writing however needs ‘Write’ permissions with Scope ‘Tenant’.

Schermafbeelding 2012-10-01 om 15.22.59

SP.UserProfiles.js

In order to interact with the Timeline using JavaScript, the library ‘SP.UserProfiles.js’ must be added to the page. The easiest way is to add the ScriptLink tag to the AdditionalPageHead Placeholder.

<SharePoint:ScriptLink ID="ScriptLink" name="SP.UserProfiles.js" runat="server" ondemand="false" localizable="false" loadafterui="true" />

Using the REST interface

Just to show that posting to the users Timeline was successful, the Timeline of the current user is displayed next to the Charts. A persons Timeline can be fetched using the REST interface.

var base = getParameterByName("SPAppWebUrl"); var url = base + "/_api/social.feed/my/TimelineFeed"; $.ajax({ url: url, cache: false, dataType: "json", type: "GET", crossDomain: false, success: function (data) { var TimeLine = data.d.SocialFeed; //do databinding }, error: function (request, status, error) { console.log("error: " + status); console.log("incoming Text: " + error); } });

Posting a Status Update

Posting on the Timeline using the JavaScript Client OM is similar to creating an Item in a SharePoint List. I used the following code:

// Initialize the current client context and the SocialFeedManager instance. clientContext = SP.ClientContext.get_current(); feedManager = new SP.Social.SocialFeedManager(clientContext);

// Create a link to include in the post. var linkDataItem = new SP.Social.SocialDataItem(); linkDataItem.set_itemType(SP.Social.SocialDataItemType.link); linkDataItem.set_text('sample'); linkDataItem.set_uri(track.Sample); var socialDataItems = [linkDataItem];

// Create the post content. var postCreationData = new SP.Social.SocialPostCreationData(); postCreationData.set_contentText("I added " + track.TrackName + " - " + track.ArtistName + " with a {0}."); postCreationData.set_contentItems(socialDataItems);

// Publish the post. Pass null for the "targetId" parameter because this is a root post. resultThread = feedManager.createPost(null, postCreationData);

The SocialDataItem is used to create a link within the Update. After this the only thing that is needed is to ExecuteQueryAsync().

Results

results

In this case Marcel opened the App to add a track to the Playlist. Marcel also follows the administrator and therefor sees updates of administrator in his Timeline too.

This example can be downloaded here