Tag Archive for SharePoint 2013

Upgrading SharePoint 2010 JS

Since a lot of Customers are upgrading their Office 365 Tenant to SharePoint 2013, I noticed one specific change in how SharePoint loads it’s JavaScript that can break down some of your code. Fortunately it’s very easy to fix and the best part is that this solution was already available in SharePoint 2010. So upgrading your scripts is highly recommended even if you’re still running SharePoint 2010.

SP.js

In SharePoint 2010 the SP.SOD (Script On Demand) was introduced. This library came with a very handy function to Execute some of your custom script after a specific registered script was loaded by the SOD.

To make use of the JavaScript Object Model we have to make sure that SharePoint has loaded sp.js first. Therefor a common line of script is used by lots of developers:

SP.SOD.executeOrDelayUntilScriptLoaded(MyFunction, ‘sp.js’);

When sp.js is loaded, the SOD is notified and MyFunction is executed. In SharePoint 2010 this works in 99% of the times it is called because SharePoint depends on the sp.js file in most of its UI, so you assume the file is always loaded. I say most of the times because sometimes it can be a choice not to load it and just go with the basic JavaScript files (init.js).

SharePoint 2013

In SharePoint 2013 this has changed. Now every SharePoint JavaScript file is loaded only when it’s used, using the same SOD principle. Now most times sp.js is never loaded until it is called by SharePoint. Our call using ExecuteOrDelayUntilScriptLoaded isn’t working anymore since SOD doesn’t gets the notification that sp.js is loaded.

The solution

To overcome this issue there is a simple solution:

if(!SP.SOD.executeOrDelayUntilScriptLoaded(MyFunction, ‘sp.js’)){ 
  LoadSodByKey(‘sp.js’);
};

This will force the loading of sp.js still using the SOD principles. Also this check works in the SharePoint 2010 context, so you can upgrade your scripts now so they will continue to work when upgrading to SharePoint 2013.

Happy Scripting!

SharePoint 2013 Apps: Back and Forth between Webs

I’ve been diving into Apps lately and was surprised on the User Experience and Interaction model in general. Don’t get me wrong I think Apps are cool, but they ask for a very different mindset from a User Experience point of view.

App Web vs. Host Web

Apps are small specific functions or applications (like we know from our Smart Phones). In SharePoint one App has a very small and restricted environment (App Web) where all functions for that App are available. To make the App available, it needs to be added to a Site or SiteCollection (Host Web). This loose coupling has a lot of advantages when it comes down to security and upgradability etc. However integration in your SharePoint User Experience can be a real pain. To keep users in the right context while using Apps there are some possibilities.

Custom Actions

First and easiest solution to this is a Custom Action. Just like we’re used to in SharePoint 2010 (and even 2007) it’s possible to extend SharePoint functionality to the ECB (Edit Control Block) and the Ribbon using a Custom Action. A good place to start is MSDN: http://code.msdn.microsoft.com/office/SharePoint-2013-Open-a-36d1598d

But even though we provision new functions into the Host Web, the Action still takes us to the App Web. We have to provide good interaction models for the User not to get lost in the process (show the App in a dialog is one). And unfortunately we cannot use the Custom Action to add a script to the ScriptLink as we could have done with the Sandbox Model.

Summary:
+ Good to provide a Contextual link to your App (Possible to open in Dialog)
+ Easy to implement
– Limited to ECB and Ribbon (Even Ribbon is limited. No custom Tabs can be added)

App Parts

An App Part is a WebPart that shows a Page from your App. Basically it’s just an iframe that loads your App. The nice thing is that Users are kept into the context of the Host Web they’re on. Still your code is running in you App and not on your Host Web. More on this: http://msdn.microsoft.com/en-us/library/fp179921.aspx

Summary:
+ Integrates on a SharePoint Page in the Host Web as a WebPart
+ Possible to use WebPart Settings as Properties that will be passed to your App
– When Upgrading your App, the App Parts need to be replaced and reconfigured.

Finally

User Experience has become way more important with this new release of SharePoint. The introduction of the App Model also introduces a new challenge on UX design. The two options I mentioned are steps in the right direction but still need good interaction design for Users to understand flow of the apps.

If you want to know more about Apps and UX challenges I can recommend this Blog Post: http://blogs.msdn.com/b/richard_dizeregas_blog/archive/2012/08/02/optimizing-user-experience-for-sharepoint-2013-apps.aspx

SharePoint 2013: _spRegionalSettings

Today I found out that the Regional Settings for a Web is stored in a Variable on the Page in SharePoint 2013. Very handy to quickly get some information like the LCID. Below an example of my SharePoint Web.

_spRegionalSettings = {
    adjustHijriDays: '0',
    calendarType: '1',
    firstDayOfWeek: '4',
    firstWeekOfYear: '2',
    localeId: '1033',
    currentDateInLocalCalendar: 'Thu Mar 28 00:00:00 UTC+0100 2013',
    showWeeks: '0',
    timeZone: '00:59:59.9994363',
    workDayEnd: '1020',
    workDayStart: '480',
    workDays: '0111110',
    time24: '0'
};

The rendering of this page var is done by the SharePoint:ScriptLink. The script is stored in the private Property GlobalizationScript and is put on the Page based on a boolean that is passed to the ScriptLink. Although I couldn’t get more proof, my guess is that you need to set Localizable=”true”.

Happy coding Smile

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: Post a Status Update to a Site Newsfeed (JSOM)

This MSDN Article explains how you’re able to post Newsfeed Items to your Timeline. The Posts however always end up on your Personal Social Feed. How can we post a message to a specific location? For instance a SharePoint Site I follow.

Social Actors

In SharePoint 2013, a SPWeb can also be a Social Actor. This means SharePoint provides some Social Metadata with the Web Object so it’s easy to find and use in a Social Context (even across SiteCollections and/or WebApplications). The Social Actor ID is a unique ID we need.

 

SocialActor Example:
<d:element m:type=”SP.Social.SocialActor”>
  <d:AccountName m:null=”true” /> 
  <d:ActorType m:type=”Edm.Int32″>2</d:ActorType> 
  <d:CanFollow m:type=”Edm.Boolean”>true</d:CanFollow> 
  <d:ContentUri>http://win-6eduurabfig:80/sites/creativecorner/team</d:ContentUri> 
  <d:EmailAddress m:null=”true” /> 
  <d:FollowedContentUri m:null=”true” /> 
 <d:Id>8.a8c7898c48604f3c9dccdc67dbf0805e.014890b080f549e4899619003332b129. a8c7898c48604f3c9dccdc67dbf0805e.0c37852b34d0418e91c62ac25af4be5b</d:Id> 
  <d:ImageUri m:null=”true” /> 
  <d:IsFollowed m:type=”Edm.Boolean”>true</d:IsFollowed> 
  <d:LibraryUri m:null=”true” /> 
  <d:Name>Go Team</d:Name> 
  <d:PersonalSiteUri m:null=”true” /> 
  <d:Status m:type=”Edm.Int32″>0</d:Status> 
  <d:StatusText m:null=”true” /> 
  <d:TagGuid m:type=”Edm.Guid”>00000000-0000-0000-0000-000000000000</d:TagGuid> 
  <d:Title m:null=”true” /> 
  <d:Uri>http://win-6eduurabfig:80/sites/creativecorner/team</d:Uri> 
  </d:element>
 *The ID is without spaces but since it’s really long I broke it up.

Newsfeed

On the Newsfeed page in SharePoint 2013 (Personal Site) we are able to create Updates on the Newsfeed. There is a Dropdown that provides us with the choice Share with Everyone (Post to Social Feed) or with a Site I follow (Post to Site Feed). We can simply use the awesome REST API to get an overview of the Sites I Follow.
“http://win-6eduurabfig:80/_api/social.following/my/Followed(types=4)”
(types=4 means Sites, types=2 means Documents).
Now in order to Post to a Site Feed of one the Sites you follow you just have to pass the SocialActor ID as targetId parameter of the SP.Social.SocialFeedManager.createPost() Method.

 

JSOM Example:
//Check if there is any text
var socialText = “I’d like to share this with you”;
var teamSiteId = “8.a8c7898c48604f3c9dccdc67dbf0805e.014890b080f549e4899619003332b129. a8c7898c48604f3c9dccdc67dbf0805e.0c37852b34d0418e91c62ac25af4be5b“;
//Post the URL to the Personal Newsfeed TimeLine
var clientContext = SP.ClientContext.get_current();
var feedManager = new SP.Social.SocialFeedManager(clientContext);
 // Create the post content.
var postCreationData = new SP.Social.SocialPostCreationData();
postCreationData.set_contentText(socialtext);
// Publish the post.
var resultThread = feedManager.createPost(teamSiteId, postCreationData);
clientContext.executeQueryAsync(function () { //success }, function() { //error });  
Easy as that!

 

Important Sidenotes

1) Some Sites you follow may not have a newsfeed enabled. In this case you will not be able to Post to that Site. You can use this REST Endpoint to check if the Feature for Site Feed is enable on a SPWeb.
 
http://win-6eduurabfig:80/_api/web/features/getById(guid’15a572c6-e545-4d32-897a-bab6f5846e18′)
 
If the Feature is activated this call will return some values. If not the Feature is not activated and it’s not possible to post to this Web.
 
2) The “Sites I Follow” also can contain Sites on which your App is not installed. That means the App is not trusted and doesn’t have permissions to read from that Site. So the Feature check can only be done on Sites that trust your App.