Monday, August 24, 2015

Quick & Dirty JSON Web Service call with jQuery

Use this little snippet to make a nice little async call using jquery and "promises"!

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

var url = SOME_URL_THAT_RETURNS_JSON;

var promise = $.getJSON(url); 

promise.then(successFunc);

function successFunc(data)
{
alert("$.getJSON returns  " + data.SOMEDATA);
}

UPDATE: Discovered that there is a difference between SharePoint online and on-premise concerning ajax.

online supports minimal json (which is what you get with getJSON and on-premise does not!

for on-premise you must explicity set json-verbose, something like so:

$.ajax({ url: Url, method: 'GET', beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json; odata=verbose"); },
cache: true, error: function (data) { ////failure },
success: function (data) { ////success } });

Saturday, August 22, 2015

Creating Custom Display Templates

At first this seems pretty hard but there's only 3 areas you have to worry about
  1. Map your Managed Properties
  2. Do some Javascript on your value from #1
  3. Display some value in the HTML
For #1 locate the <mso:ManagedPropertyMapping msdt:dt="string">. If for instance you need the ListItemId of the item in question add it to the end of the list after a comma. Here's what it looks like with the single quotes escaped:
,&#39;ListItemID&#39;:&#39;ListItemID&#39;
You will now have access to this like this:var itemID = $getItemValue(ctx, "ListItemID");

For #2 just stick your javascript after the <!--#_. 
If you want to use jQuery include it after the 
        $includeLanguageScript(this.url,...
enter this:
        $includeScript(this.url, "https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.0.min.js");

with jQuery that inserts into the HTML (DOM) put all your jQuery code within this:
AddPostRenderCallback(ctx, function () {
// code here
});


For #3 just insert your javascript variable like this:
<div>_#= itemID =#_</div>

Update: After doing several Display Templates that have to display custom properties I think the best approach is to simply grab the ListItemId and maybe some other fields that are OOTB. Going through the effort of creating new Managed Properties and such might not be worth it when you can simply use a REST call to get the rest of the info you need like this

$.getJSON( "REST API CALL URL", function(data) {
alert( data.SOMEFIELD );
})

Getting a users Profile Picture from a Display Template

This took quite a while to figure out, since it requires a combination of queries to get. Finally decided the best approach was to get the ID of the list item that has a User field. In this case I have a list with an "AssignedTo" field. I want to create a custom Display Template that would display the photo of the person that the item was "AssignedTo". I couldn't find a single article that covered this specific task.

Make sure your Display Template gets the needed Managed Properties like this:
&#39;ListItemID&#39;:&#39;ListItemID&#39;,&#39;SPSiteUrl&#39;:&#39;SPSiteUrl&#39;

First, get the list item that has the AssignedTo field:
var myUrl = mySite + "/_api/web/lists/getByTitle('HighFives')/items("+ itemID +")"


$.getJSON( myUrl, function( data ) {

We are withing the "success" handler here.
Next, now that we have the User ID (AssignedToId, a number) we can query for some useful user data. In this example I really want the "EMail" property since this is all I need to get the photo. Took a while to get this, since Email fails :/
  var url2 = "siteUrl + "/_api/Web/SiteUserInfoList/Items("+ data.AssignedToId +")?$select=Name,Picture,UserName,EMail";
  $.getJSON( url2, function( data ) {
  
  var uName = data.EMail;

Here's the part to get the photo. another option is to use the Picture setting, but using this URL seems simpler and will return a placeholder if nothing found. size can be S,M,L

    var imageLink =siteUrl + "/_layouts/15/userphoto.aspx?size=S&accountname="+ uName +"&url=";

Using jQuery to insert the picture on the page.

$("#userPictureDiv_" + itemID).html("<img style='width:100%;max-width:48px' src='"+ imageLink +"'/> abc " + imageLink);
  }); 

  });

Since this is in a Display template you can't just set the contents of the DOM within a document.ready, this all has to be contained within this:

AddPostRenderCallback(ctx, function () {

// code here

});