Building a SharePoint 2013 Client Web Part using the Client Side Object Model (CSOM)

In this post I will walk you through the process of building a Client Web part that creates a new document library using the new SharePoint 2013 CSOM App Model. The code for this sample can be downloaded from here.

This is all done via the new SharePoint CSOM model and doesn’t use any server side code. I avoided making RESTful calls or using any frameworks such as AngularJS or tools such as TypeScript etc. I wanted to keep this as bare bones and out of the box as much as possible. In future posts I will refine the code to leverage TypeScript and RESTful API calls but for now its pretty standard.

The code is written in JavaScript and makes calls to the native SharePoint Client APIs. It is pretty self explanatory and hopefully easy to follow.

Prerequisites:

  • Visual Studio 2013 – I used Ultimate as my MSDN subscription allowed for that
  • A SharePoint 2013 instance – I used a SharePoint Online MSDN tenant with a Developer site collection to debug against but you can also use an On-premises deployment equally as well.

Client Web Parts in SharePoint 2013 require hosting in an IFrame and require list, site collection and web permissions depending on the operation. In the case of creating a new list or library you need to set the “Manage” permission at the Site Collection in the AppManifest.xml. This is covered later in this post (Step8).
Also hosting a web part page as an IFrame requires that the “AllowFraming” property being set in the rendered page or the “Not allowed to render in a frame” Error will appear. The code to do this is as follows:

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

Instructions:

1) Create a new project in Visual Studio 2013 using the App for SharePoint 2013 template and click Ok. For the purposes of the post I used the solution name AppPartSample.

image

2) Specify the App settings for the project. Choose a URL to debug against and make sure to choose the SharePoint-Hosted option for the App hosting options:

image

3) Login to your SharePoint site. In my case I am using Office365:

image

4) You should now have the core setup of your project. Next we will add the actual Client Web Part. Next right click on the AppPartSample project and select Add..New Item and select “Client Web Part (Host Web)” and give it a name, click Add. For this post I will call the Web part “ClientWebPartSample”:

image

5) You will need to specify a new client web part page, for the purposes of testing I will create a new page to host the component. You can select an existing web page but I created a new page just in case. We can also set the default page later on in the AppManifest.xml.

image

6) We are now ready to get coding. First open up the “ClientWebPartSample.aspx” under the Pages folder and insert the following code. Make sure not to overwrite the @Page or @Register directives at the top of the page. Paste the following code after those directives.

The .aspx page is pretty straight forward with a table for displaying the input fields and a submit button. There is also a <div> for displaying success.

The submit button will call the JavaScript function “createNewLibrary();” which we will get to in the next section.  The .aspx code to be inserted is as follows:

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

   2:  

   3: <html>

   4: <head>

   5:     <title></title>

   6:  

   7:     <script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
   1:  

   2:     <script type="text/javascript" src="/_layouts/15/MicrosoftAjax.js">

   1: </script>

   2:     <script type="text/javascript" src="/_layouts/15/sp.runtime.js">

   1: </script>

   2:     <script type="text/javascript" src="/_layouts/15/sp.js">

   1: </script>

   2:  

   3:     <!-- Custom code is reference here -->

   4:     <script type="text/javascript" src="../Scripts/App.js">

</script>

   8:         

   9: </head>

  10: <body>

  11:     <table>

  12:         <tr>

  13:             <td>List Name:</td>

  14:             <td><input type="text" id="tbListName" maxlength="255" /></td>

  15:         </tr>

  16:        <tr>

  17:             <td>List Description:</td>

  18:             <td><input type="text" id="tbListDesc" /></td>

  19:         </tr>

  20:          <tr>

  21:             <td><input type="button" id="btnSubmit" value="New List" onclick="createNewLibrary();" /></td>

  22:         </tr>

  23:     </table>

  24:     <div>

  25:         <p id="message">

  26:             <!-- The following content will be replaced with the user name when you run the app - see App.js -->            

  27:         </p>

  28:     </div>

  29: </body>

  30: </html>

 

7) Next lets code up the JavaScript. Go to the Scripts folder and open the App.js. Insert the following code and overwrite the generated code.

The code is pretty self explanatory and well commented.

   1: 'use strict';

   2:  

   3: //First get the URI decoded URLs. - these are passed in via the query string as {StandardTokens}

   4: var hostweburl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));

   5: var appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));;

   6:  

   7: //SP Context references 

   8: var clientContext;

   9: var appContextSite;

  10: var spWeb;

  11: var spSite;

  12:  

  13: //New list reference

  14: var newList;

  15:  

  16: // This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model

  17: $(document).ready(function () {   

  18:  

  19:     // The js files are in a URL in the form:

  20:     // web_url/_layouts/15/resource_file

  21:     var scriptbase = hostweburl + "/_layouts/15/";

  22:  

  23:     // Load the js files and continue to

  24:     // the execOperation function.

  25:     $.getScript(scriptbase + "SP.Runtime.js",

  26:        function () {

  27:            $.getScript(scriptbase + "SP.js",

  28:                function () { $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest); }

  29:                );

  30:        }

  31:        );

  32:  

  33: });

  34:  

  35: // Function to execute basic operations and obtain the SP Client and App contexts

  36: function execCrossDomainRequest() {

  37:  

  38:     //Obtain the SP contexts

  39:     clientContext = new SP.ClientContext(appweburl);

  40:     appContextSite = new SP.AppContextSite(clientContext, hostweburl);

  41:  

  42:     //Get the SPWeb of the HostWeb

  43:     spWeb = appContextSite.get_web();

  44:     clientContext.load(spWeb);

  45:  

  46:     //Execute against the server

  47:     clientContext.executeQueryAsync(

  48:         Function.createDelegate(this, onSuccessInitHandler),

  49:         Function.createDelegate(this, onErrorInitHandler)

  50:     );

  51:  

  52: }

  53:  

  54: //Init Success handler

  55: function onSuccessInitHandler() {

  56:     //Success!

  57: }

  58:  

  59: //Init Failed handler

  60: function onErrorInitHandler(sender, args) {

  61:     alert('An initialisation error has occurred. ' + args.get_message() +

  62:        '\n' + args.get_stackTrace());

  63: }

  64:  

  65: //creates a new SP Document library - called from the form submit button

  66: function createNewLibrary() {

  67:  

  68:     //Get the list name details from the form

  69:     var libraryName = document.getElementById("tbListName").value;

  70:     var libraryDescription = document.getElementById("tbListDesc").value;    

  71:  

  72:     //Set the list creation properties - as per http://msdn.microsoft.com/en-us/library/office/jj246290.aspx        

  73:     var listCreationInfo = new SP.ListCreationInformation();

  74:  

  75:     //set the title

  76:     listCreationInfo.set_title(libraryName);

  77:  

  78:     //set the description

  79:     listCreationInfo.set_description(libraryDescription);

  80:  

  81:     //Set the template type - as per http://msdn.microsoft.com/en-us/library/office/ee549420(v=office.14).aspx

  82:     listCreationInfo.set_templateType(SP.ListTemplateType.documentLibrary);   

  83:  

  84:     //Add the list creation attributes

  85:     newList = spWeb.get_lists().add(listCreationInfo);

  86:  

  87:     //Add the list object to the Client context

  88:     clientContext.load(newList);

  89:  

  90:     //Execute against the server - as per this article http://msdn.microsoft.com/en-us/library/dn168907.aspx

  91:     clientContext.executeQueryAsync(

  92:         Function.createDelegate(this, onNewListCreateSuccess),

  93:         Function.createDelegate(this, onNewListCreateFail)

  94:     );

  95: }

  96:  

  97: // On List create success

  98: function onNewListCreateSuccess() {

  99:  

 100:     //show a result on success

 101:     $('#message').text("The list has been successfully created");

 102:  

 103: }

 104:  

 105: // On List create fail

 106: function onNewListCreateFail(sender, args) {

 107:     alert('Error creating the new list or library. The following error has occurred: ' + args.get_message());

 108: }

 109:  

 110:  

 111: // Function to retrieve a query string value.

 112: // For production purposes you may want to use

 113: //  a library to handle the query string.

 114: function getQueryStringParameter(paramToRetrieve) {

 115:     var params =

 116:         document.URL.split("?")[1].split("&");

 117:     var strParams = "";

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

 119:         var singleParam = params[i].split("=");

 120:         if (singleParam[0] == paramToRetrieve)

 121:             return singleParam[1];

 122:     }

 123: }

 124:  

 125:  

 

8) Before deploying and executing the code it is important to update the AppManifest.xml with the right permissions. Open the AppManifest.xml file in Visual Studio and set the permissions as follows. Set the Site Collection permissions to “Manage” as we will be creating a new Document library in the development site collection . Failing to set this will throw an access denied error when trying to create the library.

image 

9) Also you will need to set the default start page from “Default.aspx” to the web part page you created earlier. Otherwise you will deploy and debug and it appears that nothing has happened:

image

10) From Visual Studio 2013 now save everything, Right click on Deploy as this will do a build and deploy the solution.

Once deployed you will be prompted with a trust dialog verifying the web part will be accessing the permissions as set in the AppManifest.xml.

Click on “Trust It”. Alternatively you can hit F5 and you can debug and step through the code but you will still be prompted with the trust dialog.

image

10) The page should render and the output looks pretty basic. Try entering the library details and click the submit button. A new DocLib will be created in the Host web (Dev site collection) and not the App web.

image

As you can see its pretty straightforward and uses out of the box SharePoint CSOM code. You can now embed the web part as a normal web part on web part pages.

I look forward to any questions or feedback and hopefully it has been a useful resource. I will recreate the project above using TypeScript and maybe employ the use of using REST API calls instead of standard SharePoint Client API calls. But that’s for another post 🙂

Here is a list of references I used when writing this:

Advertisements

About Aaron Saikovski

Aaron Saikovski is a Microsoft certified technology specialist, consultant, developer, trainer and cloud solution architect with over 20+ years commercial information technology experience. He has consulted and worked with an incredibly diverse number of both local and international clients across the banking and financial services, utilities, oil and mining, telecommunications, logistics, construction/property, pharmaceutical, transport/airline and FMCG sectors. He has also consulted on a variety of projects to both Federal and State governments in high-profile portfolios such as Prime Minister and Cabinet, Department of Defence, Taxation Office, Department of Education and Training, Department of Employment & Workplace Relations and the Department of Health. Aaron’s skills revolve around the Microsoft platform stack with a core skillset based on the SharePoint platform. He has been involved in some of the largest SharePoint deployments in the world and was a member of the Global SharePoint Ranger team within Microsoft Corporation and was actively involved with the SharePoint Customer Advisory Team (SPCAT) to provide guidance and best practices to the largest Microsoft enterprise global customers. He was also an active MSDN article reviewer and contributor during his time at Microsoft. He has very broad and deep experience with architecting, developing and deploying complex customer solutions leveraging the Microsoft Office365 and Azure cloud platforms. Some of the key cloud customers he has been involved with are Qantas, Caltex, and Fujitsu/Westpac to name a few. He assists customers with their journey to the cloud and provides guidance and best practices to assist in identifying workloads that are suitable candidates to be migrated or redeveloped. These include IaaS, SaaS and PaaS solutions that solve a particular business requirement while providing the best technical outcome for the customer. Aaron is a regular presenter at such events as SharePoint Saturday (http://www.spsevents.org), Microsoft TechEd and is a regular presenter at user groups and conferences. He presents on a wide and varied range of topics that encompass the complete end to end Microsoft solution stack such as Windows 8 App development through to deploying Azure IaaS solutions with PowerShell. Aaron has an active social media profile. He was the founding member of OzMoss (http://www.codify.com/lists/OzMOSS), a very active and prominent online SharePoint community and he can be followed on Twitter at @RuskyDuck72. He blogs regularly at https://aaronsaikovski.wordpress.com/ Aaron is also an active affiliate member of the Institute of Electrical and Electronics Engineers (www.ieee.org) Outside of work Aaron is a very active volunteer for DoggieRescue (www.doggierescue.com) where he volunteers his time to maintain and improve their IT systems to keep them running as optimally and efficiently as possible. ** OPINIONS EXPRESSED ARE MY OWN VIEWS AND NOT THOSE OF MY EMPLOYER **
This entry was posted in CSOM, JavaScript, Office 365, SharePoint 2013, SharePoint Online, Web Parts. Bookmark the permalink.

4 Responses to Building a SharePoint 2013 Client Web Part using the Client Side Object Model (CSOM)

  1. Pingback: Create a Folder and set the ProgID programmatically using the SharePoint 2013 CSOM | Aaron Saikovski's Tech Blog

  2. Pingback: À la découverte du site de communauté | KTNN SharePoint

  3. tola says:

    I tested on O365 is working, but on my Local SharePoint hosted app Foundation 2013, is not working,
    it has error on SP.ClientContext (Doesn’t support) can, give me some idea. on this . http://social.msdn.microsoft.com/Forums/sharepoint/en-US/8e33d658-0430-47bd-be07-e554889ee0e5/object-doesnt-support-this-action-sharepoint-hosted-appsclient-web-part?forum=sharepointdevelopmentprevious#8e33d658-0430-47bd-be07-e554889ee0e5

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s