4

I need to go through all web parts of a page (e.g. default Display page of a list) and set the JSLink property on a particular web part. I can enumerate the web parts on a page and set the property on any of them. However, if there are multiple web parts on the page, I am not able to get the Type for each web part. For e.g. if I put Content Editor web part on Display page in addition to the default view web part, I get two web parts while enumerating but not able to determine which one is content editor and which one is list item display web part.

Reading web part properties using JavaScript Object Model in SharePoint 2013 explains how to get 'Title' property, but this doesn't work for something like TypeName. Is there a standard way to do this in JavaScript and conclusively determine the 'Type' of web part at least for built in web parts? Also, it will be great if it can be done without making multiple load requests to server.

Thanks.

1

Better late than never. Here is a way to get what you need from JS but via CSOM instead of JSOM. This outputs all of the web part types and IDs to the console for the current page.

var soapEnv =
'<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  \
    <soap:Body>  \
        <GetWebPartProperties2 xmlns="http://microsoft.com/sharepoint/webpartpages">  \
            <pageUrl>' + location.pathname + '</pageUrl>   \
            <storage>Shared</storage>   \
            <behavior>Version3</behavior>   \
        </GetWebPartProperties2>  \
    </soap:Body>   \
</soap:Envelope>';

$.ajax({
    url: _spPageContextInfo.webAbsoluteUrl + '/_vti_bin/WebPartPages.asmx',
    type: 'POST',
    dataType: 'xml',
    data: soapEnv,
    complete: function(xhr,textStatus) {
        $(xhr.responseXML).find('WebPart').each(function() {
            var wp = $(this);
            var wpTypeName = wp.find('TypeName').text() || wp.find('type').attr('name');
            console.log(wp.attr('ID') + ' - '+ wpTypeName);
        });
    },
    error: function(xhr,textStatus,errorThrown) {
        console.log(errorThrown);
    },
    contentType: 'text/xml; charset=\"utf-8\"'
});

Most of this was lifted from Get web part TypeName using CSOM. I got lazy and left the jQuery in there.

  • thanks for your answer. I will try this if I need it in future. Currently I don't recall where I wanted it :) – Prakash - Crow Canyon Jul 25 '18 at 11:26
1

Even though TypeName property is available via web part schema it is not exposed via SP.WebParts.WebPartDefinition object or SP.WebParts.WebPart object

But there is at least one solution how to determine web part type via JSOM API. For that matter SP.WebParts.LimitedWebPartManager.exportWebPart method needs to be utilized which returns web part schema and TypeName property could be extracted from it as demonstrated below:

let webPartManager = file.getLimitedWebPartManager(SP.WebParts.PersonalizationScope.shared);
let webPartXml = webPartManager.exportWebPart(webPartId);
await executeQuery(ctx);
let props = parseWebPartSchema(webPartXml.get_value());
console.log(props.TypeName);

where

function parseXml(xmlStr) {
   return new window.DOMParser().parseFromString(xmlStr, "text/xml");
}


function parseWebPartSchema(schema){
    let properties = {};
    let schemaXml = parseXml(schema);
    let node = schemaXml.querySelector('WebPart');
    if(node) {//V2 format?
       Array.from(node.childNodes).map( node => {
          if(node.nodeName !== "#text")
             properties[node.nodeName] = node.innerHTML;
       })
    }
    else{
        let node = schemaXml.querySelector('webPart');
        properties["TypeName"] = node.querySelector('type').getAttribute('name');
        Array.from(node.querySelector('properties').childNodes).map( node => {
            if(node.nodeName !== "#text")
                 properties[node.getAttribute('name')] = node.innerHTML;
        })
    }
    return properties;   
}

async function executeQuery(context) {
    return new Promise((resolve, reject) => {
        context.executeQueryAsync(function () {
            resolve();
        }, function (sender, args) {
            reject(args);
        });
    });
}

Demo

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.