Wednesday, June 28, 2017

Display the current users Profile Image in SharePoint using EWS.

Introduction

If your IT department has configured it, you can retrieve the thumbnail images used in Outlook from the Exchange Server for your own purposes. This can be useful for customizing the look of various sites in SharePoint, such as employee dashboards.

This post describes how to retrieve and use the image, and how to handle the condition where the users email does not resolve to an image.


Retrieve the Image using EWS

The image is retrieved by using a URL of the following format:

https://Exchange Server/ews/Exchange.asmx/s/GetUserPhoto?email=email address&size=size code


Exchange Server = server that hosts exchange, URL provided by IT

email address = email of the user you are retrieving the image for

size = HR48x48 | HR64x64 | HR96X96 | HR120X120 | HR240X240 | HR360X360 | HR432X432 | HR504X504 | HR648X648

A sample url that would resolve to the user "Ian.mctavish@yourplace.ca" with a 64 x 64 thumbnail would be:

https://Exchange Server/ews/Exchange.asmx/s/GetUserPhoto?email=Ian.mctavish@yourplace.ca&size=HR64x64

Interesting, but how would we use this?

Using the Image on a Page

In its simplest state, you could include this as the url for an image and have it render on any page:

<img alt="Profile Image" src="https://Exchange Server/ews/Exchange.asmx/s/GetUserPhoto?email=Ian.mctavish@yourplace.ca&amp;size=HR64x64" />


This is great for displaying a specific user image on a page, but what if you want to display the current users image instead?

Displaying the Current Users Image


Download and reference JQuery

We can include the jQuery javascript libraries on our page, and use a couple of those functions to extract the image and set the value of the image on page load. You will first need to configure your SharePoint webpage to include the jQuery libraries by first downloading the libraries to your site assets folder, then referencing those libraries within your page:

<script type="text/javascript" src="/SiteAssets/jquery-1.11.3.js"></script>
<script type="text/javascript" src="/SiteAssets/jquery.SPServices-2014.02.js"></script>


Create Default Image

One of the things we need to anticipate is users who's email addresses do not resolve to images. We certainly don't want the dreaded "X" to appear when an image cannot be found. So we handle this by creating a generic profile image for all users and storing it within the SharePoint site. We will configure the page to first display this image, and then, if a profile image is found, then replace it with this image.

Set up the generic image (notice ID value) and put it on your SharePoint page:

<div id="UserImage"><img class="ihss-user-image" src="/Images/user.png" alt=""/></div>

This will resolve when the page loads to your generic user image.


Retrieve the Profile Image

Create a script section on your page and enter the following code:

$(document).ready(function() { 
  SetProfileImage();         
 });

  
 function SetProfileImage()
 {
  var thisUserEmail = $().SPServices.SPGetCurrentUser({
   fieldName: "Email",
   debug: false
  });  
  
var profileImagePath = 'https://exchange.yourweb.ca/ews/exchange.asmx/s/GetUserPhoto?email=' + thisUserEmail  + '&size=HR120x120';

     var img = new Image();
     img.onload = function() {
      //alert('image source: ' + img.src);
      //alert('image height: ' + img.height);
      var divHTML = "<img class=\"ihss-user-image\" src=\"" + profileImagePath + "\" />";
      //alert('image html: ' + divHTML);
      $('#UserImage').html(divHTML);
     }
     img.src = profileImagePath;
 }


The code functions as follows:

1. Once page has finished loading call set profile image
2. Retrieve current users email using SPServices.SPGetCurrentUser
3. Generate Exchange Server URL using email address
4. Configure onload function to update image to resolved profile path if found.

Leveraging the EWS to return user profile images is one way to display the current users Profile Image in SharePoint. The approach used here ensures that, if the user doesn't have an image, or the server is not responding, then the default profile image will be displayed instead.

Thursday, June 15, 2017

Expand the first group only on a SharePoint List View Web Part (SharePoint 2013)

If you add as SharePoint list view web part to a SharePoint page using SharePoint designer, you are given the ability to sort, group and filter the results of that web part for display.  If you choose to group by a specific element, then you can decide to either expand or contract all groups by default. Handy.


However, if you want to expand just the first grouping, and have the rest of the groups collapsed, there is no default setting to allow that to occur.  I have taken the original blog post posted here:


Original Blog Post


and have updated it for SharePoint 2013.


The original idea used here is sound, locate and click, using javascript and jquery, the plus sign located next to the first group.  However, using the web part ID did not work in my case, so I had to dig a bit deeper.


Here is the code I used to call the function:


<script type="text/javascript">


$(document).ready(function() {
   collapseGroups();
  });



And here is the slightly modified function:


function collapseGroups() {
   var closestElement = document.getElementById('group0');
   var myimg = closestElement.getElementsByTagName('img')[0];
   var mysrc = myimg.src;
   $(myimg).parent().click();
}

</script>




The challenging part of getting this working is identifying the document element that is closest to the + sign.  The original post used the name of the web part that hosts the list data, however, this did not work in my case.  Instead, it clicked the first columns sort header in the web part, and resorted the list by that column on page load!


So the approach is fine, click the + sign once you find it, we just need to find an element deeper in the list view web part.  Here is how I did it.


Navigate to your web part page and make note of the Group Header for your grouped column.  So if you were grouping by "Course Year", then "Course Year" would be what you are looking for.


Open the page in source view, and search for your grouping column name. When I searched for "Course Year" I got back html that looked like this:


<tr id="group0">
<td colspan="100" nowrap class="ms-gb">
<a href="javascript:" onclick="javascript:ExpCollGroup('0-1_', 'img_0-1_',event, true);return false;">
<img src="/_layouts/15/images/plus.gif" border="0" alt="expand" id="img_0-1_">&nbsp;Course Year</a>



You can see the plus image markup, plus javascript event associated with that markup that fires the button clicked event.  Unfortunately, between page refreshes, the image id changes, so I couldn't use that. 


However, the closest element with an ID was the table row (tr) that wrapped this line.  This tr has an ID of "group0".  I used this ID value in the collapse groups function, and it worked!  And it appears to be a more stable name than the ever changing values of the + image.