in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint 2013, SharePoint 2010, Office 365, SharePoint Online, and other Microsoft products, as well as some discussion of general programming related concepts.

This Blog

Syndication

Archives

Corey Roth [MVP]

A SharePoint MVP bringing you the latest time saving tips for SharePoint 2013, Office 365 / SharePoint Online and Visual Studio 2013.

How to: Use the SharePoint 2013 Client Object Model (SP.js) from a Client Web Part

I was talking to Tom Resing (@resing) last week about using the SharePoint Client Object Model inside a Client Web Part and it became apparent that I left you all hanging with my last post.  I got you to the point where you could build your web part, but referencing SP.js is not as simple as you would think it would be.  I had to look at a lot of code samples to put this all together.  This follow-up post will give you the necessary steps to get started working with SharePoint right away.

The first thing I do is add some script references to the page.  For Client Web Parts, I tend to use a new .js file to host the web part’s JavaScript and I leave app.js to serve the needs of Default.aspx.  Building on my example from the last post, I add a new script called HelloWorldClientWebPart.js.  I add this in the Scripts folder. 

AppHelloWorldScriptProjectItem

We’ll add our code to this file in a minute but first I want to add those references.  In this case, we aren’t loading a reference to SP.js yet.  Instead, we’ll load jQuery from a CDN as well as MicrosoftAjax.js.  You may not need all of those, but chances are you do.

<head>

    <script type="text/javascript" src="../Scripts/jquery-1.6.2.min.js"></script>

    <script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script>

    <script type="text/javascript" src="../Scripts/HelloWorldClientWebPart.js"></script>

</head>

Now we’ll jump over to our new script file.  We’re going to borrow a few lines from App.js starting with variables to hold the context, web, and user.

var context;

var web;

var user;

Now we use jQuery’s document.ready function to add our code.

$(document).ready(

    function () {

    }

);

You can add this line to your document.ready function to get a reference to the SPSite object of the site hosting the client web part (app part) as opposed to the site actually hosting the app itself.  We’ll also need it to get our reference to SP.js as well.

//Get the URI decoded SharePoint site url from the SPHostUrl parameter.

var spHostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));

This method relies on getQueryStringParameter which you’ll find in many App examples.

function getQueryStringParameter(urlParameterKey) {

    var params = document.URL.split('?')[1].split('&');

    var strParams = '';

    for (var i = 0; i < params.length; i = i + 1) {

        var singleParam = params[i].split('=');

        if (singleParam[0] == urlParameterKey)

            return decodeURIComponent(singleParam[1]);

    }

}

To get the host URL, you will have to modify your elements.xml to make this work.  Do this by adding {standardtokens} to the URL of the Content element.

<Content Type="html" Src="~appWebUrl/Pages/HelloWorldClientWebPart.aspx?{StandardTokens}" />

When you do this, SharePoint will automatically pass you a number of query string parameters that you can take advantage of including the SPHostUrl.  At that point you can pass the URL into your call to get a SPWeb object.

Back in the JavaScript file, we add the rest of our code.  First we need to get the URL to the 15 folder inside _layouts and assign it to our layoutsRoot variable.  Now we can use the jQuery getScript() method to retrieve the scripts we need.  Before you get SP.js, you have to get SP.Runtime.js.  That is why you see the nested calls below.  Once SP.js can be retrieved, it makes a call to the execOperation method.  This method can then take advantage of the SharePoint Client Object Model.

//Build absolute path to the layouts root with the spHostUrl

var layoutsRoot = spHostUrl + '/_layouts/15/';

 

$.getScript(layoutsRoot + "SP.Runtime.js", function () {

    $.getScript(layoutsRoot + "SP.js", execOperation);

}

);

To demonstrate it’s use, we’ll use the same script example used in App.js.  We start by defining execOperation and getting a reference to the content and SPSite object.

function execOperation() {

    // get context and then username

    context = new SP.ClientContext.get_current();

    web = context.get_web();

 

    getUserName();

}

We then use the same getUserName() and other functions from App.js.

function getUserName() {

    user = web.get_currentUser();

    context.load(user);

    context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);

}

 

// This function is executed if the above OM call is successful

// It replaces the content of the 'welcome' element with the user name

function onGetUserNameSuccess() {

    $('#message').text('Hello ' + user.get_title());

}

 

// This function is executed if the above OM call fails

function onGetUserNameFail(sender, args) {

    alert('Failed to get user name. Error:' + args.get_message());

}

Putting the entire script together, here is what it looks like.

var context;

var web;

var user;

 

//Wait for the page to load

$(document).ready(

    function () {

        //Get the URI decoded SharePoint site url from the SPHostUrl parameter.

        var spHostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));

 

        //Build absolute path to the layouts root with the spHostUrl

        var layoutsRoot = spHostUrl + '/_layouts/15/';

 

        $.getScript(layoutsRoot + "SP.Runtime.js", function () {

            $.getScript(layoutsRoot + "SP.js", execOperation);

        }

        );

 

        // Function to execute basic operations.

        function execOperation() {

            // get context and then username

            context = new SP.ClientContext.get_current();

            web = context.get_web();

 

            getUserName();

        }

    }

);

 

function getQueryStringParameter(urlParameterKey) {

    var params = document.URL.split('?')[1].split('&');

    var strParams = '';

    for (var i = 0; i < params.length; i = i + 1) {

        var singleParam = params[i].split('=');

        if (singleParam[0] == urlParameterKey)

            return decodeURIComponent(singleParam[1]);

    }

}

 

// This function prepares, loads, and then executes a SharePoint query to get the current users information

function getUserName() {

    user = web.get_currentUser();

    context.load(user);

    context.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail);

}

 

// This function is executed if the above OM call is successful

// It replaces the content of the 'welcome' element with the user name

function onGetUserNameSuccess() {

    $('#message').text('Hello ' + user.get_title());

}

 

// This function is executed if the above OM call fails

function onGetUserNameFail(sender, args) {

    alert('Failed to get user name. Error:' + args.get_message());

}

Lastly, I update HelloWorldClientWebPart.aspx with a div to hold the results.  Here is what the entire file looks like.

<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<WebPartPages:AllowFraming ID="AllowFraming1" runat="server" />

<head>

    <script type="text/javascript" src="../Scripts/jquery-1.6.2.min.js"></script>

    <script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script>

    <script type="text/javascript" src="../Scripts/HelloWorldClientWebPart.js"></script>

</head>

<div>

    <h2>Hello World Client Web Part!</h2>

    <div id="message"></div>

</div>

We can then execute the app in the debugger and then add the App Part to the root page of our developer site.  It should look something like this when you’re done.

AppClientWebPartWithJavaScript

Sorry to leave you hanging like that on my previous blog post.  I hope this helps you get started with your app.  It’s a bit involved but not too bad.  It would be nice to create a custom SharePoint Project Item that does this for us.

Come see my sessions at SPC12 and follow me on twitter @coreyroth.

Comments

 

Tom Resing said:

Corey,

Great job explaining all the code. As I mentioned, I've tried all this out and demonstrated it at Austin SPUG so thanks again for the heads up before the post.

Tom

October 24, 2012 4:26 PM
 

SharePoint Daily » Blog Archive » Turn SharePoint into a Social Intranet; Office 365 Development; Windows Phone 8 a Developer Opportunity said:

Pingback from  SharePoint Daily  &raquo; Blog Archive   &raquo; Turn SharePoint into a Social Intranet; Office 365 Development; Windows Phone 8 a Developer Opportunity

October 30, 2012 7:06 AM
 

SharePoint Daily said:

Still here. Take that, Sandy. - Dooley Top News Stories When is the Best Time to Turn Your SharePoint

October 30, 2012 7:08 AM
 

Sonia Circle T said:

Great post!... I have been looking up for for ages!

Thanks a lot CoreyRoth!

Ur a gun!

November 29, 2012 9:20 PM
 

Kem said:

I am getting an error:

Type is not defined: Type.registerNamespace('SP');

The JS is breaking at this line:

context = new SP.ClientContext.get_current();

Any ideas????

December 19, 2012 8:17 PM
 

CoreyRoth said:

@Kem make sure none of that code is inside execOperation().  Bad stuff happens when you do that.

December 19, 2012 8:26 PM
 

YuriBurger said:

@Kem also, make sure you also load MicrosoftAjax.js.

December 29, 2012 7:49 PM
 

Dhrumil Shah said:

Thanks a ton :)

February 27, 2013 4:31 AM
 

Aterese said:

Referencing this part of your post:

To get the host URL, you will have to modify your elements.xml to make this work.  Do this by adding {standardtokens} to the URL of the Content element.

<Content Type="html" Src="~appWebUrl/Pages/HelloWorldClientWebPart.aspx?{StandardTokens}" />

I have multiple elements.xml in project, so I am assuming it is the Content folder | Elements.xml ?

Where within the elements is this added (Module Name=Content) ?

Thank you

Anita

April 10, 2013 6:56 PM
 

CoreyRoth said:

@Aterese It's the elements.xml for your client web part.  It will be in the folder of whatever you named it.

April 11, 2013 10:02 PM
 

Linkapalooza: October 24, 2012 « SDTimes said:

Pingback from  Linkapalooza: October 24, 2012 &laquo; SDTimes

April 24, 2014 1:15 PM
 

sivakumar said:

Nice Article,

Currently i have implemented for developing App in sharepoint 2013.

I had one question,whether we can able to give reference from Module,that is available in Visual Studio 2013.

May 4, 2014 4:24 AM
 

CoreyRoth said:

@sivakumar I'm not sure that I understand your query.

May 5, 2014 8:20 AM
 

Venkat said:

Hi, Can the above code be used for a Visual webpart. I am trying the javascript client object model, and followed your code, however, I am not sure of achieving the below:

Referencing this part of your post:

To get the host URL, you will have to modify your elements.xml to make this work.  Do this by adding {standardtokens} to the URL of the Content element.

<Content Type="html" Src="~appWebUrl/Pages/HelloWorldClientWebPart.aspx?{StandardTokens}" />

There is a elements.xml file in the visual webpart, should the above code be added there. There was no Content tag in the elements.xml. How to achieve this in visual webpart.

Thanks

May 6, 2014 6:30 AM
 

CoreyRoth said:

@Venkat Visual Web Parts don't use the Content element nor do they need to have parameters pass in that manner.    

May 7, 2014 4:45 PM

Leave a Comment

(required)  
(optional)
(required)  
Add

About CoreyRoth

Corey Roth is an independent SharePoint consultant specializing in ECM, Apps, and Search.
2012 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems