How to create a Document Set in SharePoint 2013 using JavaScript Client Side Object Model (JSOM)?


 

Well SharePointers!

Challenge and Response are two things those have done wonders to the mankind!

Quiet recently, I got a challenge from someone to create a Document Set in SharePoint 2013 using JSOM (mind it! its JSOM not some .Net Managed CSOM or Server Side code)

The first challenge was to identify if the API is available or not. Truly speaking, I wasn’t quite frankly aware if such an API exists!

In my quest, I was helped by my colleague Gabriel Royer with not just finding the right API but also with debugging the errors in the sample code and writing the missing pieces that actually creates the Document Set. In fact, I could not have achieved this without Gabriel’s help.

Thanks a ton Gabriel!

I’ve listed the steps that you need to follow (The steps here are for the SharePoint hosted app):

Create a Document Library:

First, you need to create a Document Library and and Add a Content Type “Document Set” to the Document Library. For this APP, I’ve created a Document Library named “DocSetLibrary” in the Host Web.

Add the right references:

Secondly, you need to add the following references! Here you can use either the debug version of the files or the non-debug versions. (I’ve used the non-debug versions for debugging purpose).

<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" src="/_layouts/15/SP.DocumentManagement.js"></script> (This is the most important one!)

<script type="text/javascript" src="../Scripts/App.js"></script> (Reference to your app.js file)

image

 

Create Some Cool UI for your APP:

Well next is to design some UI for the APP. (To keep things simple, I’ve just included a “Textbox” and a “Button”)

image

 

Get App/Host Web URL:

Well next is to get the App Web URL or the Host Web URL (get the appropriate URL where your Document Library exists, if in App Web get App Web URL otherwise get a Host Web URL)

You need to use the code below to get the APP/HOST Web Url.

// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    var params = document.URL.split("?")[1].split("&");
    for (var i = 0; i < params.length; i = i + 1) {
        var param = params[i].split("=");
        switch (param[0]) {
            case "SPAppWebUrl":
                SPAppWebUrl = decodeURIComponent(param[1]);
                break;
            case "SPHostUrl":
                SPHostUrl = decodeURIComponent(param[1]);
                break;
        }
    }
});

function convertDataURIToBinary(dataURI) {
    var BASE64_MARKER = ';base64,';
    var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
    var base64 = dataURI.substring(base64Index);
    var raw = window.atob(base64);
    var rawLength = raw.length;
    var array = new Uint8Array(new ArrayBuffer(rawLength));
    for (i = 0; i < rawLength; i++) {
        array[i] = raw.charCodeAt(i);
    }
    return array;
}

What is the Right API”?:

The method to create the document set using the JSOM is SP.DocumentSet.DocumentSet.create. The biggest challenge is to get this work as there’s no documentation (apart from this post) on this API.

The method can be found in the JavaScript file “SP.DocumentManagement.js” which is located at “C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\TEMPLATE\LAYOUTS\SP.DocumentManagement.js

How to use it?

Well, the create method expects some parameters like Client Context, Parent Folder, Document Set Name, and Content Type ID. Now, be aware that the value of Parent Folder and Content Type ID parameters can’t be of type String. You need to assign Folder Object to Parent Folder and Content Type ID Object to Content Type ID parameters.

The value of Content Type ID for Document Set is “0x0120D520”. This is a static value and won’t change but since this of type String, you need to get the object of this ID.

You can use the below method to get the content Type ID Object:

var docSetContentTypeID = "0x0120D520";

var docsetContentType = web.get_contentTypes().getById(docSetContentTypeID);

and then use the docsetContentType.get_id() method to pass the content Type ID Object to the create method.

In case you’ll like to create the Document Set under the parent folder, use the code below:

parentFolder = list.get_rootFolder();

 

Enough of Explanation!  Where’s is the code?

Well, below is the way your final JavaScript function might look like. I’ve called this function on click of the “Create Document Set” button.

function CreateDocumentSet() {

var ctx = new SP.ClientContext(SPHostUrl);
var parentFolder;
var newDocSetName = $('#txtGetDocumentSetName').val();
var docSetContentTypeID = "0x0120D520";

var web = ctx.get_web();
var list = web.get_lists().getByTitle('DocSetLibrary');
ctx.load(list);

parentFolder = list.get_rootFolder();
ctx.load(parentFolder);

var docsetContentType = web.get_contentTypes().getById(docSetContentTypeID);
ctx.load(docsetContentType);

ctx.executeQueryAsync(function () {
var isCreated = SP.DocumentSet.DocumentSet.create(ctx, parentFolder, newDocSetName, docsetContentType.get_id());
ctx.executeQueryAsync(SuccessHandler('Document Set creation successful'), FailureHandler("Document Set creation failed"));
}, FailureHandler("Folder loading failed"));

ctx.add_requestSucceeded(function () {
$('#txtGetDocumentSetName').val('');
alert('Request Succeeded');
});

ctx.add_requestFailed(function (sender, args) {
alert('Request failed: ' + args.get_message());
});
}

// Failure Message Handler

function FailureHandler(message) {
    return function (sender, args) {
        alert(message + ": " + args.get_message());
    }
}

 

// Success Message Handler

function SuccessHandler(message) {
    return function () {
        alert(message);
    }
}

APP Permissions:

Lastly, you need to provide the Write permissions on the List in your AppManifest.xml file.

image

Where’s the final Visual Studio 2012 solution? I want to download it:

You can download the Visual Studio Solution from my Sky Drive folder.

How does the Final APP looks like? :

The sample app looks similar to the one below:

image

 

What’s the Output:

Output will be similar to the one below:

image

Comments (10)

  1. Michael says:

    Great article!

    Do you have a solution to add properties to the created document set? For example "Description" or some additional custom columns.

    I found something about the DocumentSet.Create method parameter "properties" which is working with hashtables but can't realize it in javascript.

    Thank you in advance.

    Regards

    Michael

  2. vamittal says:

    @Michael – Thanks!

    Once you've created the document set. You can then use JavaScript client object model to fetch the newly created document set and update it's properties just like a list item.

    If you check "SP.DocumentSet.DocumentSet.create" method in the file:

    C:Program FilesCommon Filesmicrosoft sharedWeb Server Extensions15TEMPLATELAYOUTSSP.DocumentManagement.js

    You'll find that there's no parameter that corresponds to the document set properties.

  3. Josh says:

    Absolute lifesaver. You made my day.

  4. mahesh says:

    HI,

    Thank you for the great post,

    can you please tell me how to give permission to appmanifest.xml file in visual studio.

    actually how to add appmanifest.xml file to visual studio 2010

    Thanking you in Advance

    Mahesh

  5. Chris Rust says:

    Try as I may I cannot seem to update my Document Set Description property using CSOM. Can this be done? Does any one have a code snippet that works. This is what I am doing:

    Folder f = oSPDocLib.ParentWeb.GetFolderByServerRelativeUrl(oSPDocLib.ParentWebUrl + "/" + oSPDocLib.RootFolder.Name + "/" + sFolderPath + "/" + sDocumentSetName);

               oSPClientContext.Load(f);

                   f.ListItemAllFields["Description"] = "This is a Description Bob";

                   f.ListItemAllFields.update();

                  oSPClientContext.ExecuteQuery();

    Thanks

    Chris

  6. Stef says:

    To update the description, I've managed to do this using JSOM:

    var folder = web.getFolderByServerRelativeUrl(docSetFullFolderURL);

    ctx.load(folder);

    ctx.executeQueryAsync(

      function setLoaded()

      {

         var listitem = folder.get_listItemAllFields();

         ctx.load(listitem);

         listitem.set_item("DocumentSetDescription", "description text here");

         listitem.update();

         ctx.executeQueryAsync(

            function itemUpdated()

            {

               alert('Document set description updated!');

            },

            function itemUpdateFailed(sender, args)

            {

               alert('Failed to update: ' + args.get_message());

            }

         )

      },

      function folderFailed(sender, args)

      {

         alert('Doc set failed to load: ' + args.get_message());

      }

    )

  7. Ferdinando Simonetti says:

    Hello from Italy.

    If I have to perform the creation of a custom content type *based on* Document Set, but with additional columns/fields, I'll need to use *his* specific type ID: Is it correct?

    I'll give this code a try tomorrow, I hope I'll soon report some degree of success

    However, thanks in advance!

  8. Ferdinando Simonetti says:

    By the way, I forgot to mention that I'm trying to create the new "Document Set on steroids" in Office 365 environment, from within a "script editor" web part inside a NewForm.aspx of another list (from which I'll extract the needed values for the fields of the new DocSet).

Skip to main content