Displaying SharePoint user presence indicator in CSR

The following are code snippets which can be used to show a user’s Lync/Skype for Business presence status in SharePoint Client Side Rendering (CSR).

Default Render

<span>
    <span class="ms-imnSpan">
        <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink ms-spimn-presenceLink">
            <span class="ms-spimn-presenceWrapper ms-imnImg ms-spimn-imgSize-10x10">
                <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-spimn-img ms-spimn-presence-disconnected-10x10x32" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_1,type=sip"></img>
            </span>
        </a>
    </span>
    <span>
        <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink" tabIndex="-1">
            <img name="imnmark" title="" ShowOfflinePawn="1" class=" ms-hide" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_2,type=sip"></img>
        </a>
        <span>User</span>
    </span>
</span>

With Picture Detail View

<div>
    <div class="ms-tableRow">
        <div>
            <span class="ms-imnSpan">
                <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink ms-spimn-presenceLink">
                    <span class="ms-spimn-presenceWrapper ms-imnImg ms-spimn-imgSize-10x10">
                        <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-spimn-img ms-spimn-presence-disconnected-10x10x32" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_661,type=sip"></img>
                    </span>
                </a>
            </span>
        </div>
        <div class="ms-tableCell ms-verticalAlignTop">
            <div class="ms-peopleux-userImgDiv">
                <span class="ms-imnSpan">
                    <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink" tabIndex="-1">
                        <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-hide" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_3452,type=sip"></img>
                    </a>
                    <span>
                        <img style="width:62px; height:62px; border:none" src="http://userimageurl" alt="User"></img>
                    </span>
                </span>
            </div>
        </div>
        <div class="ms-tableCell ms-peopleux-userdetails ms-noList">
            <ul style="max-width:150px">
                <li>
                    <div class="ms-noWrap">
                        <span>
                            <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink" tabIndex="-1">
                                <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-hide" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_34523,type=sip"></img>
                            </a>
                            <span>User</span>
                        </span>
                    </div>
                </li>
            </ul>
        </div>
    </div>
</div>

With Picture

<div>
    <div>
        <span>
            <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink" tabIndex="-1">
                <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-hide" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_1,type=sip"></img>
            </a>
            <span>
                <img style="width:62px; height:62px; border:none" src="http://userimageurl" alt="User"></img>
            </span>
        </span>
    </div>
    <div class="ms-floatLeft ms-descriptiontext">
        <span class="ms-verticalAlignTop ms-noWrap ms-displayInlineBlock">
            <span class="ms-imnSpan">
                <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink ms-spimn-presenceLink">
                    <span class="ms-spimn-presenceWrapper ms-imnImg ms-spimn-imgSize-10x10">
                        <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-spimn-img ms-spimn-presence-disconnected-10x10x32" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_2,type=sip"></img>
                    </span>
                </a>
            </span>
            <span class="ms-noWrap ms-imnSpan">
                <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink" tabIndex="-1">
                    <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-hide" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_3,type=sip"></img>
                </a>
                <span>User</span>
            </span>
        </span>
    </div>
</div>

Presence Only

<span class="ms-imnSpan">
    <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink ms-spimn-presenceLink">
        <span class="ms-spimn-presenceWrapper ms-imnImg ms-spimn-imgSize-10x10">
            <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-spimn-img ms-spimn-presence-disconnected-10x10x32" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_1,type=sip"></img>
        </span>
    </a>
</span>

Picture Only

<div>
    <div>
        <div class="ms-tableCell">
            <span class="ms-imnSpan">
                <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink ms-spimn-presenceLink">
                    <span class="ms-spimn-presenceWrapper ms-spimn-imgSize-8x72">
                        <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-spimn-img ms-spimn-presence-disconnected-8x72x32" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_1,type=sip"></img>
                    </span>
                </a>
            </span>
        </div>
        <div class="ms-tableCell ms-verticalAlignTop">
            <div class="ms-peopleux-userImgDiv">
                <span class="ms-imnSpan">
                    <a href="#" onclick="IMNImageOnClick(event);return false;" class="ms-imnlink" tabIndex="-1">
                        <img name="imnmark" title="" ShowOfflinePawn="1" class="ms-hide" src="/_layouts/15/images/spimn.png?rev=23" alt="User Presence" sip="user@domain.com" id="imn_2,type=sip"></img>
                    </a>
                    <span class="ms-peopleux-imgUserLink">
                        <span class="ms-peopleux-userImgWrapper" style="width:72px; height:72px">
                            <img style="min-width:72px; min-height:72px; clip:rect(0px, 72px, 72px, 0px); max-width:72px" src="http://userimageurl" alt="User"></img>
                        </span>
                    </span>
                </span>
            </div>
        </div>
    </div>
</div>

Source: http://www.sharepointcolumn.com/lync-presence-indicators-code-snippets-in-sharepoint-2013/

Remove duplicate list items from SharePoint REST call result using JavaScript

The following code snippet show how to remove duplicate list items in the JSON result of a SharePoint REST call using JavaScript.

Function Definition:

function RemoveDuplicateItems(items, propertyName) {
    var result = [];
    if (items.length > 0) {
        $.each(items, function (index, item) {
            if ($.inArray(item[propertyName], result) == -1) {
                result.push(item);
            }
        });
    }
    return result;
}

Function Usage:
In the below code, assumption is that, the REST call returns data.d.results and the column for which duplicate items need to be removed is Title

var items = data.d.results;
items = RemoveDuplicateItems(items, 'Title');

 

JSLink URL Tokens in SharePoint

Following are some of the JSLink URL Tokens I have come across in SharePoint.

  • ~site – reference to the current SharePoint site (or “Web”)
  • ~sitecollection – reference to the current SharePoint site collection (or “Site”)
  • ~layouts – version specific reference to the web application Layouts folder (so it will automatically swap out /_layouts/14 or /_layouts/15 for you)
  • ~sitecollectionlayouts – reference to the layouts folder in the current site collection (e.g. /sites/team/_layouts/15)
  • ~sitelayouts – reference to the layouts folder in the current site (e.g. /sites/teams/subsite/_layouts/15)

Few Examples:

~sitecollection/_catalogs/masterpage/
~site/siteassets/
~layouts/reputation.js

Source: https://www.martinhatch.com/2013/08/jslink-and-display-templates-part-1.html

Load scripts in SharePoint within custom Javascript or Workflow

Following is the code which can be used to load JavaScript in sequence.

This code for example loads the reputation.js from SharePoint’s layouts folder & jQuery from site assets.

(function () {
    ExecuteOrDelayUntilScriptLoaded(function () {
        //sp.runtime.js has been loaded
        ExecuteOrDelayUntilScriptLoaded(function () {
            //sp.js has been loaded
            SP.SOD.registerSod('reputation.js', SP.Utilities.Utility.getLayoutsPageUrl('reputation.js'));
            SP.SOD.registerSod('jquery-3.2.1', '../SiteAssets/Scripts/jquery-3.2.1.min.js');
            SP.SOD.loadMultiple(['reputation.js', 'jquery-3.2.1'], function () {
                //reputation.js & jquery-3.2.1.min.js have been loaded.
                var context = SP.ClientContext.get_current();
                var web = context.get_web();
                //Check if jQuery has been loaded
                if (typeof jQuery != 'undefined') {
                    console.log("Jquery is loaded");
                }
                else {
                    console.log("Jquery is not loaded!");
                }
            });
        }, "sp.js");
    }, "sp.runtime.js");
})();

Source: https://sharepoint.stackexchange.com/questions/92082/uncaught-typeerror-cannot-read-property-get-current-of-undefined

Set permissions for a SharePoint list item using 2013 Workflow

SharePoint 2013 Logo

Following are the steps to be implemented in a 2013 workflow to set permissions for a SharePoint list item.
This particular method set the permissions for all users in a group with a particular role permission using REST Calls

1. Build Header Dictionary and set to a variable

Name: Accept
Type: String
Value: application/json;odata=verbose

Name: Content-Type
Type: String
Value: application/json;odata=verbose

1. Set “Group ID URL” to a variable

[%Workflow Context:Current Site URL%]_api/Web/SiteGroups/GetByName('Group Name')?$Select=id

2. Set “Role ID URL” to a variable

[%Workflow Context:Current Site URL%]_api/Web/RoleDefinitions/GetByName('Role Name')?$Select=id

3. Set “Break Role Inheritance URL” to a variable

[%Workflow Context:Current Site URL%]_api/Web/Lists/GetByTitle('Library Name')/items([%Current Item:ID%])/BreakRoleInheritance(copyRoleAssignments=false, clearSubacopes=true)

4. Create Response Variables for “Group ID Response”, “Role ID Response”, “Response Headers” & “Response Code” with data type as Dictionary

5. Make GET REST call using Call Action to “Group ID URL” and assign output to above created variables in step 4

6. Use Get Action ‘d/Id’ from above “Group ID Response” variable and set it to a new variable “GroupID”

7. Make GET REST call using Call Action to “Role ID URL” and assign output to above created variables in step 4

8. Use Get Action ‘d/Id’ from above “Role ID Response” variable and set it to a new variable “RoleID”

9. Make POST REST call using Call Action to “Break Role Inheritance URL” and optionally assign output to above created variables in step 4

10. Set “Set Role URL” to a variable

[%Workflow Context:Current Site URL%]_api/Web/Lists/GetByTitle('Library Name')/items([%Current Item:ID%])/RoleAssignments/AddRoleAssignment(principalId=[%Variable:GroupID%],roleDefId=[%Variable:RoleID%])

Add Role:

 AddRoleAssignment(principalId=[%Variable:GroupID%],roleDefId=[%Variable:RoleID%])

Remove Role:

RemoveRoleAssignment(principalId=[%Variable:GroupID%],roleDefId=[%Variable:RoleID%])

11. Make POST REST call using Call Action to “Set Role URL” and optionally assign output to above created variables in step 4

Reference URL: https://msdn.microsoft.com/en-us/library/office/dn531432.aspx

Get SharePoint Item’s Author Details using REST

SharePoint 2013 Logo

When we fetch document details from the SharePoint, sometimes we may need to get the Author details as well. By default when we do ODATA REST query, we will get only Authorid with a number as a result.

To get Author’s additional details we may need to expand the selected item as show below.

https://server/sites/sitecollection/_api/web/Lists/GetByTitle('Documents')/Items?$select=Author/Title,Author/Name,Author/EMail,Author/MobilePhone,Author/SipAddress,Author/Department,Author/JobTitle,Author/FirstName,Author/LastName,Author/WorkPhone,Author/UserName,Author/Office,Author/ID,Author/Modified,Author/Created,*&amp;$expand=Author

Following list show all the valid Author fields

  1. Title
  2. Name
  3. EMail
  4. MobilePhone
  5. SipAddress
  6. Department
  7. JobTitle
  8. FirstName
  9. LastName
  10. WorkPhone
  11. UserName
  12. Office
  13. ID
  14. Modified
  15. Created

Source: https://social.technet.microsoft.com/wiki/contents/articles/31210.sharepoint-2013-get-user-details-from-person-or-group-field-using-rest-api.aspx

Sync desktop files to O365 SharePoint Library

One of the consulting request I got was that an user should be able to sync files from a legacy system to O365 SharePoint Library. The issue was that the legacy system was old and all it could do was place a file in a particular folder.

The solution we could offer was the following.

  1. Configure a Windows mapped drive to point to a SharePoint library
  2. Configure the legacy system to place file into folder

This worked, but having a mapped drive was received as a security threat by the client’s security team.

But now thanks to the newly launched feature of syncing the SharePoint library files with OneDrive, this is easier.
Best part is, it supports both Windows & Mac.
Read more about it here

Sync SharePoint Library with OneDrive Client

Image Source: Office Blog