Using the JavaScript object model (JSOM) in apps for SharePoint
Hi! My name is Ricardo Loo. I am a Programming Writer for SharePoint. In today's article we'll talk about how to use the JavaScript object model (JSOM) in a simple HTML page in your app for SharePoint. By using the JSOM, you can access data and functionality in SharePoint 2013. You can also use Representational State Transfer (REST) endpoints to access data. The choice depends on various factors such as your abilities or development platform. For more information, see Choose the right API set in SharePoint 2013.
To keep things simple and short, I am using an app page hosted in SharePoint—but remember that you can also use the JSOM if your pages are not hosted in SharePoint. To access the objects using the JSOM in pages not hosted in SharePoint, you can use the cross-domain library (we'll post more information about the cross-domain library in a subsequent article.)
To use the JSOM, you must follow these steps:
1. Reference the required libraries.
2. Get a client context instance and load SharePoint objects.
3. Execute the query and provide callback functions.
Reference the required libraries
Before using the JSOM you must reference the following libraries, in this order:
1. ASP.NET Ajax library
2. sp.runtime.js file
3. sp.js file
When the app pages are hosted in SharePoint, you can use relative paths to the required files. The following script tags show you how to reference the required libraries in a page hosted in SharePoint:
<script
type="text/javascript"
src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js">
</script>
<script type="text/javascript" src="_layouts/15/sp.runtime.js"></script>
<script type="text/javascript" src="_layouts/15/sp.js"></script>
<script type="text/javascript">
// Continue your program flow here.
</script>
Get a client context and load the objects
To access the objects in the JSOM, you first need an instance of the client context. You can get an instance of SP.ClientContext by using the get_current() method. Now, we have an access point (the client context) to the objects in SharePoint. As you probably imagine, you must issue a query to get the specific objects you need.
What's next? Let's create a list. You can use lists in the app web to provide storage for your app. For example, you can use a list to store user data or some other information. Whether you use lists or another type of storage depends on how you design your app. For more information, see Data storage options in apps for SharePoint.
The following code shows how to get an instance of the client context and load the required objects to create a list:
var clientContext;
var listCreationInfo;
var web;
var list;
clientContext = SP.ClientContext.get_current();
web = clientContext.get_web();
listCreationInfo = new SP.ListCreationInformation();
listCreationInfo.set_title("User data");
listCreationInfo.set_templateType(SP.ListTemplateType.genericList);
list = web.get_lists().add(listCreationInfo);
clientContext.load(list);
Execute the query and provide callback functions
Now, you are ready to send the query to SharePoint and get your list created. You can send your query by using the executeQueryAsync method in the client context object. You should provide callback functions to handle the success and failure events. The following code shows how to use the executeQueryAsync method and provide callback functions for the success and failure events:
clientContext.executeQueryAsync(
function () { alert("Success!") },
function () { alert("Request failed") }
);
Great! So… where is your list?
To see your list, just go to the following URL:
app_web/Lists/User%20data
Figure 1. List created using the JSOM
Easy! Well, I think that is enough for one post. I hope you found it useful to get up and started using the JSOM in your apps for SharePoint.
Beyond this article
- About the tools used for this article: I wrote the code for this article on my home computer. I don't have Visual Studio or SharePoint installed on that computer. I just used the "Napa" Office 365 Development Tools. You can sign up for Office 365 and install the "Napa" app in your developer website. Then you can build apps just like the one explained in this article, using only your browser. For the full instructions, see Sign up for an Office 365 Developer Site.
- About storage in real-world apps: You can check for apps that handle data in real-world scenarios by browsing the Office Store. The Customer Orders and Products app is a good example of a real app that handles and stores data.
- About more operations using the JSOM: The example in this article is a very simple one. I chose creating a list to demonstrate how to use the JSOM. You can find many more operations in the article How to: Complete basic operations using JavaScript in SharePoint 2013.
Let us know what other topics you would like us to talk about by using the comments section below. Thanks for your time!
Comments
Anonymous
September 28, 2012
The comment has been removedAnonymous
October 12, 2012
If you're inside of SharePoint (i.e. a SharePoint-Hosted App, and not an Autohosted App) the correct way to reference sp.js, etc is as follows: <SharePoint:ScriptLink ID="ScriptLink1" Name="sp.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false" /> <SharePoint:ScriptLink ID="ScriptLink2" Name="SP.UI.Dialog.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false" /> You can do this in your header's content control.Anonymous
October 12, 2012
Also the correct way to register MicrosoftAjax.js is to use the ScriptManager tag, if you prefer to use the cdn, set EnableCdn="true": <asp:ScriptManager ID="ScriptManager1" runat="server" EnableCdn="true" /> (If your page already has one [i.e. included from the MasterPage], you can register a ScriptManagerProxy instead.)Anonymous
October 12, 2012
Great info for ASP.NET developers, Mikey. Thank you! Developers writing apps on other platforms should use the standard script tags or whatever mechanisms your platform offers.Anonymous
March 15, 2013
Hey its very nice post. I got the list created but how to add field from the code. I want to create 2 column while creating list. Is it possible?Anonymous
June 16, 2013
I Added Reference to MicrosoftAjax.js and it is loaded correctly but still im getting the same error, 'Type' is undefinedAnonymous
December 22, 2013
hi, I want to use JSOM in the provider hosted app web site. Is this possible. Because i ma using the below code and its giving the below error SCRIPT5009: 'Type' is undefined SP.Runtime.js, line 2 character 129 Code : function loadDependentScripts() { var scriptbase = hostweburl + "/_layouts/15/"; // Load the js files and continue to the successHandler $.getScript(scriptbase + "SP.Runtime.js", function () { $.getScript(scriptbase + "SP.js", function () { $.getScript(scriptbase + "SP.RequestExecutor.js", runCode); } ); } ); } $(document).ready(function () { hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl")); //appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));//No SPAppWebURL in query string appweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl")); // resources are in URLs in the form: // web_url/_layouts/15/resource scriptbase = hostweburl + "/_layouts/15/"; loadDependentScripts(); }); function runCode() { loadUser(); } function loadUser() { var ctx = new SP.ClientContext.get_current(); user = ctx.get_web().get_currentUser(); ctx.load(user); ctx.executeQueryAsync(onGetUserNameSuccess, onGetUserNameFail); } function onGetUserNameSuccess() { fetchedUserName = 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()); } function getQueryStringParameter(param) { 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] == param) { return singleParam[1]; } } } Please help me if its possible in provider hosted app. ThanksAnonymous
January 07, 2014
Bharat, Did you add the reference to MicrosoftAjax.js mentioned in the previous comments? That should solve the "Type is undefined" errorAnonymous
March 17, 2014
I am trying to create site columns and later create content types ( using the site columns created ). The content types have dependencies on few content types that we should create. I am trying this using jquery deferred but I am unable to sequence them as required. Can you please help me with the creating site columns and content types.Anonymous
April 01, 2014
I'm developing an app for sharepoint and I m trying to get list items on sharepoint. It works successful when I load the page for the first time but when I open another page and I want to return on the first page for the second time, I'm getting this error : "JavaScript runtime error: Unable to get property 'split' of undefined or null reference" here is the code : var hostweburl; var appWebUrl; $(document).ready(function () { //Get the URI decoded URLs. hostweburl = decodeURIComponent( getQueryStringParameter("SPHostUrl")); appWebUrl = decodeURIComponent( getQueryStringParameter("SPAppWebUrl")); // Load the js file and continue to the // success event $.getScript("../_layouts/15/SP.RequestExecutor.js", execCrossDomainRequest); }); // Function to prepare and issue the request to get // SharePoint data function execCrossDomainRequest() { // Initialize the RequestExecutor with the app web URL. executor = new SP.RequestExecutor(appWebUrl); // Issue the call against the host web. // To get the title using REST we can hit the endpoint: // app_web_url/_api/SP.AppContextSite(@target)/web/title?@target='siteUrl' // The response formats the data in the JSON format. // The functions successHandler and errorHandler attend the // success and error events respectively. executor.executeAsync( { url: appWebUrl + "/_api/SP.AppContextSite(@target)/web/Lists/GetByTitle('video')/items?@target='" + hostweburl+"'", method: "GET", headers: { "Accept": "application/json; odata=verbose" }, success: successHandler, error: errorHandler } ); } // Function to handle the success event. // Prints the host web's title to the page. function successHandler(data) { var jsonObject = JSON.parse(data.body); // code to run... } } // Function to handle the error event. // Prints the error message to the page. function errorHandler(data, errorCode, errorMessage) { document.getElementById("table").innerText = "Could not complete cross-domain call: " + errorMessage; } // Function to retrieve a query string value. // For production purposes you may want to use // a library to handle the query string. function getQueryStringParameter(paramToRetrieve) { 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] == paramToRetrieve) return decodeURIComponent(singleParam[1]); } }Anonymous
April 03, 2014
Great Post, very helpful. Thanks...Anonymous
April 04, 2014
The comment has been removedAnonymous
April 10, 2014
I am trying to access data inside excel through Excel services REST APi from a Sharepoint hosted app. Both the app and the excel file are hosted in the same site. The app is installed in: http://<site-name>.Sharepoint.com/<sitecollection-name>/<App-Name> and the excel i am trying to access is located on the same site collection as above inside documents library. http://<site-name>.Sharepoint.com/<sitecollection-name>/_vti_bin/ExcelRest.aspx/Shared Documents/Test1.xlsx/Model/Tables('table1') I am able to get the data from the below thru browser. But when i access the same thru app i get the error "Invalid field or parameter requestInfo.url.". Below is the code: $(document).ready(function () { hostweburl = decodeURIComponent( getQueryStringParameter("SPHostUrl") ); appweburl = decodeURIComponent( getQueryStringParameter("SPAppWebUrl") ); var scriptbase = hostweburl + "/_layouts/15/"; // Load the js files and continue to the successHandler $.getScript(scriptbase + "SP.Runtime.js", function () { $.getScript(scriptbase + "SP.js", function () { $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest); } ); } ); }); // Function to prepare and issue the request to get // SharePoint data function execCrossDomainRequest() { // executor: The RequestExecutor object // Initialize the RequestExecutor with the app web URL. var url1 = hostweburl + "/_vti_bin/ExcelRest.aspx/Shared Documents/Test1.xlsx/Model/Tables('table1')?$format=json"; var executor = new SP.RequestExecutor(appweburl); executor.executeAsync( { url: url1, //"/_api/web/lists", method: "GET", headers: { "Accept": "application/json; odata=verbose" }, success: successHandler, error: errorHandler } );Anonymous
July 08, 2014
Is the abbreviation "JSOM" an official Microsoft term? I couldn't find this in the msdn.Anonymous
July 14, 2014
More than an official term it is an acronym that we use to make it easier to read articles like this one. As a rule of thumb, we define the term early in the article, like JavaScript object model (JSOM), and then use the short version through the rest of the article. The acronym is widely used on MSDN content, for example: msdn.microsoft.com/.../dn268594(v=office.15).aspx msdn.microsoft.com/.../jj907313(v=office.15).aspxAnonymous
August 20, 2014
The comment has been removedAnonymous
March 18, 2015
Hi, I am trying to upload a document in office 365 using CSOM and javascript but its not happening. Please help.Anonymous
April 09, 2015
Yeah me 2 dev. I just a HTML page with a fileupload control to be able to crate a document in SharePoint online. I've tried everything but nothing works... :-( MSFT HELPAnonymous
April 15, 2015
Hello Ricardo - Can you please help me to learn the cross domain library to use JSOM for those pages which are not hosted in SharePoint?Anonymous
April 16, 2015
Hello Paul This code sample should help: code.msdn.microsoft.com/.../SharePoint-2013-Get-items-d48150aeAnonymous
April 16, 2015
dev, Cubalibre... If you want to add a file to a document library using cross-domain library take a look at the following file. code.msdn.microsoft.com/.../sourcecode It uploads a file by hitting the following endpoint fileEndpoint = appweburl + "/_api/SP.AppContextSite(@target)/web/lists(listid)/rootfolder/files/add(url' bookTitle.txt')?@target='hostweburl'; fileContent = document.getElementById("content").value;Anonymous
April 18, 2015
The comment has been removedAnonymous
April 27, 2015
Hi Dave, Sorry it took so long to get back to you. We're not monitoring this blog anymore. May I suggest using stackoverflow.com? Use SharePoint and Office365 tags. Regarding your question, you shouldn't try to add server-side code to your solutions, if you can updated the SQL table with client-side code then you should be okay.Anonymous
May 26, 2015
Great Post