1

I want to collect items from lists which are located on several subsites and copy them to one list on the main site using JavaScript and SharePoint2013.

Example: There are two subsites sub1 and sub2, both containing a list called list1. list1 in sub1 contains itemA and itemB. list1 in sub2 contains itemC and itemD. The masterList on the main site should then contain itemA, itemB, itemC, itemD.

The number of subsites will change, since it is part of a project structure (subsite = customer). The lists located on each subsite have always the same name.

It should be something like this (the code does not work):

// SubURL contains all subsite URLs
for (var j=0; j<SubURL.length; j++) {

    var currentSubURL = SubURL[j];  // pick an url from the array
    var clientContextSub = new SP.ClientContext(currentSubURL); // clientcontext of the subsite
    var oListPR = clientContextSub.get_web().get_lists().getByTitle(prListTitle);   // list located in subsite
    var camlQuery = new SP.CamlQuery();
    this.collListItem = oListPR.getItems(camlQuery);
    clientContextSub.load(collListItem);    // load the list item collection

    clientContextSub.executeQueryAsync(function() {

        var listItemInfo = '';
        var listItemEnumerator = collListItem.getEnumerator();

        while (listItemEnumerator.moveNext()) { // loop through the items

            var objListItem = listItemEnumerator.get_current();

            // copy the list items
            var clientContextMain = new SP.ClientContext(mainURL);
            var oListMaster = clientContextMain.get_web().get_lists().getByTitle(ovListTitle); // master list containing all subsite list items
            var itemCreateInfo = new SP.ListItemCreationInformation();
            var oListItemMaster = oListMaster.addItem(itemCreateInfo);
            oListItemMaster.set_item('Title', objListItem.get_item('Title'));             
            oListItemMaster.update();
            clientContextMain.load(oListItemMaster);                
            clientContextMain.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceededFinal), Function.createDelegate(this, this.onQueryFailedFinal));
        }

    }, function(sender, args) {
            //failure stuff
            alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
        }); 
}

I know calling the executeQueryAsync in a loop isn't a good idea and will cause errors. I have also tried stacking the load-commands and then calling only one executeQueryAsync, but this also did not work since the client context is different for every list (correct?)

I have no idea how to get this working. I hope you can help me with this, any hint will be appreciated :)

  • Would you mind sharing the final code to achieve this? – AXA240778 May 19 '16 at 14:22
1

I got it working with help of this: technet

I had to modify in the function onLoadTaskDetails(sender, args) to something like this

function onLoadTaskDetails(sender, args) {

var clientContext = new SP.ClientContext(mainURL);

var oListPR = clientContext.get_web().get_lists().getByTitle(listTitleMain);

    for (var x = 0; x < items.length; x++) {   

        var itemDetails = items[x];

        var listItemEnumerator = itemDetails.ListItems.getEnumerator();

        while (listItemEnumerator.moveNext()) {

            var oListItem = listItemEnumerator.get_current();

            var itemCreateInfo = new SP.ListItemCreationInformation();

            var oListItemPR = oListPR.addItem(itemCreateInfo);

            oListItemPR.set_item('Title', oListItem.get_item('Title'));

            oListItemPR.update();

            clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));               

        }
    }
}
0

So, here is my complete code. I am not a professional, so maybe the code is not beautiful and could be shorter, but it works for my application. I hope someone can use it.

// In this case, there is one main site containing one main list and many subsites, each containing a subsite-list.
// The code below fetches the items from all the subsite-lists and copies them to the main list.
// If there are items in the main list but no corresponding item in a subsite-list, the item will be deleted.
// This syncing works in one direction. Since all the lists contain a field with an URL (called 'projectsite'),
// I decided to find a match by comparing these URLs.

ExecuteOrDelayUntilScriptLoaded(RetrieveMainListItems, "sp.js");

// ************************************************************************************
// global

var listTitleSub = "TitleOfListInSubsites";
var mainURL = 'yourURL';
var listTitleMain = 'TitleOfListInMainSite';

var allMainListTitles = new Array();
var allMainListIds = new Array();
var allMainListUrls = new Array();

var clientContext = null;
var spListobj = null;
var items;


// retrieve all elements from main list
function RetrieveMainListItems() {

    var clientContext = new SP.ClientContext(mainURL);
    var oList = clientContext.get_web().get_lists().getByTitle(listTitleMain);
    var camlQuery = new SP.CamlQuery();
    this.collListItem = oList.getItems(camlQuery);       
    clientContext.load(collListItem);
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceededListItems),
    Function.createDelegate(this, this.onQueryFailed));
    }


function onQuerySucceededListItems(sender, args) {
    var listItemEnumerator = collListItem.getEnumerator();
    var counter = 0;

        while (listItemEnumerator.moveNext()) {
            var oListItem = listItemEnumerator.get_current();
            // collect some date for later comparing
            allMainListTitles[counter] = oListItem.get_item('Title');
            allMainListUrls[counter] = oListItem.get_item('Projectsite').get_url();
            allMainListIds[counter] = oListItem.get_id();
            counter = counter + 1;
       }
    RetrieveSubsites();
}


// retrieve all the subsites
function RetrieveSubsites() {
    clientContext = new SP.ClientContext.get_current();
    this.site = clientContext.get_web();
    this.webSubSites = site.get_webs();
    clientContext.load(this.webSubSites, 'Include(Title, ServerRelativeUrl)');
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onLoadSubWebs), Function.createDelegate(this, this.onQueryFailed));
}

// load the list in every subsite
function onLoadSubWebs(sender, args) {
    items = [];              
    for (var x = 0; x < this.webSubSites.get_count(); x++) {        
        web = this.webSubSites.itemAt(x);
        var siteUrl = web.get_serverRelativeUrl();             
        spListobj = web.get_lists().getByTitle(listTitleSub);
        var spCamlQuery = new SP.CamlQuery();               
        var spListobjItems = spListobj.getItems(spCamlQuery);                                 
        var itemDetails = new Object;
        itemDetails.ListItems = spListobjItems;
        itemDetails.WebTitle = web.get_title();
        items.push(itemDetails);
        clientContext.load(spListobjItems);         
        }
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onLoadTaskDetails), Function.createDelegate(this, this.onQueryFailed));
 }

// refresh the main list by updating existing items, adding new ones or deleting them
function onLoadTaskDetails(sender, args) {

    var clientContext = new SP.ClientContext(mainURL);
    var oListPR = clientContext.get_web().get_lists().getByTitle(listTitleMain);

    for (var x = 0; x < items.length; x++) {   

        var subProjectExistsInListFlag = false;

        var itemDetails = items[x]; // get a list from the array

        var listItemEnumerator = itemDetails.ListItems.getEnumerator();

        while (listItemEnumerator.moveNext()) { // loop through all the list elements
            var oListItem = listItemEnumerator.get_current();   // this is a list item from a subsite list

            var j = 0;

            // check if the subsite list items are already existing in the main list by comparing the URLs
            for (j=0; j<allMainListUrls.length; j++) {  
                var subUrlTemp = oListItem.get_item('Projectsite').get_url();
                var mainUrlTemp = allMainListUrls[j]

                if (subUrlTemp == mainUrlTemp) { 
                    subProjectExistsInListFlag = true; // match found
                    break;                      
                    }
                else {  
                    subProjectExistsInListFlag = false;
                }
            }


            // if the entry existst: edit
            if (subProjectExistsInListFlag) {
                //alert(oListItem.get_item('Title') + ' exists.');
                var oListItemPR = oListPR.getItemById(allMainListIds[j]);

                // copy data
                oListItemPR.set_item('Title', oListItem.get_item('Title'));
                oListItemPR.set_item('Projectsite', oListItem.get_item('Projectsite'));
                oListItemPR.set_item('Begin', oListItem.get_item('Begin'));
                oListItemPR.set_item('End', oListItem.get_item('End'));
                oListItemPR.set_item('Comment', oListItem.get_item('Comment'));
                // ... an so on

                oListItemPR.update();
                clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceededFinal), Function.createDelegate(this, this.onQueryFailed));              
            }

            // else: create new item
            else {
                //alert(oListItem.get_item('Title') + ' does not exist.');

                var itemCreateInfo = new SP.ListItemCreationInformation();
                var oListItemPR = oListPR.addItem(itemCreateInfo);

                // copy data
                oListItemPR.set_item('Title', oListItem.get_item('Title'));
                oListItemPR.set_item('Projectsite', oListItem.get_item('Projectsite'));
                oListItemPR.set_item('Begin', oListItem.get_item('Begin'));
                oListItemPR.set_item('End', oListItem.get_item('End'));
                oListItemPR.set_item('Comment', oListItem.get_item('Comment'));
                // ... an so on

                oListItemPR.update();
                clientContext.load(oListItemPR);
                clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceededFinalWithRefresh), Function.createDelegate(this, this.onQueryFailed));           
            }
        }
    }


// if there are items in the main list, but the items in the subsites lists do not exist anymore, delete them from the main list
for (var m=0; m<allMainListUrls.length; m++) {

    var mainUrlTemp = allMainListUrls[m];
    var listProjectExistsInSubFlag = false;

        // loop through all the subs
        for (var x = 0; x < items.length; x++) {   
            var itemDetails = items[x];

            var listItemEnumerator = itemDetails.ListItems.getEnumerator();

            while (listItemEnumerator.moveNext()) {
                var oListItem = listItemEnumerator.get_current();
                var subUrlTemp = oListItem.get_item('Project').get_url();

                if (subUrlTemp == mainUrlTemp) { 
                        listProjectExistsInSubFlag = true;  
                        break;                      
                        }
                    else {  
                        listProjectExistsInSubFlag = false;
                    }
            }
            if (listProjectExistsInSubFlag == true) break;
        }

        if (listProjectExistsInSubFlag) {
            //alert('List in subsites matches ' + allMainListTitles[m]);
            }
        else {
            alert('Found no subsite matching "' + allMainListTitles[m] + '". This item will be deleted.');

            var oListItemPR = oListPR.getItemById(allMainListIds[m]);
            oListItemPR.deleteObject();
            clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceededFinalWithRefresh), Function.createDelegate(this, this.onQueryFailed));   
            }

}

//alert("done");
}


function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
 }


function onQuerySucceededFinal(sender, args) {

}

function onQuerySucceededFinalWithRefresh(sender, args) {
    location.href = location.href;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.