I've been through a couple iterations on how to do this, and I'm not sure exactly what is going on. I'm currently working on an administration tool that will allow easy duplication of our SharePoint sites. I've been faced with the task of adding Site Columns onto the Content Types, and through my research the only way that I know how to do that is through the JSOM API. I can get a few site Columns added (max. 7 - 8). However no matter what I do, I get 1 of 2 errrors when attempting the full amount of site columns (17 or 22) dependent upon the content type.
Failed to fetch columns and Content Type. Error:Invalid field name. {b0af08d3-136c-43c6-8c0c-df48df70c2c3} - This is based upon the initial function call of SPPostCTFIeldLinksData. This isn't a field ID, why would it be populating?
Unknown Error. - This is an odd issue to me. I'm not exactly sure where this is stemming from, but it seems as if the query is executing, it is just returning an error with no discernable messages.
Ultimately, I want to be able to give this code a list of site columns to add to given content types (particularly in an array of objects), and have them be added. Any suggestions on how I should go about fixing this would be greatly appreciated.
Code below:
var ctx = new SP.ClientContext.get_current();
var web = ctx.get_web();
var columns = new Array();
function SPPostCTFieldLinksData(configData) {
document.getElementById('text').value += 'Posting Site Columns to Content Types...\n';
$.get({
url: siteURL,
method: 'GET',
headers: {
"Accept": "application/json;odata=verbose"
},
async: false
}, function (data) {
for (var i = 0; i < data.d.results.length; i++) {
IDs.push({ id: data.d.results[i].Id.StringValue, name: data.d.results[i].Name });
}
});
for (var iFieldsCounter = 0; iFieldsCounter < configData[IDs[0].name]["FieldLinksTitle"].length; iFieldsCounter++) {
columns[iFieldsCounter] = web.get_fields().getByInternalNameOrTitle(configData[IDs[0].name]["FieldLinksTitle"][iFieldsCounter]);
ctx.load(columns[iFieldsCounter]);
}
cttypes = web.get_contentTypes();
ctx.load(cttypes);
ctx.executeQueryAsync(
function () {
addColumns(IDs[0].name, configData[IDs[0].name]["FieldLinksTitle"], columns);
},
function onItemsRefetchedFail(sender, args) {
console.log('Failed to fetch columns and Content Type. Error:' + args.get_message() + '\n' + args.get_stackTrace());
});
}
function addColumns(ctypeName, fieldsInternalName, createdFields) {
var createdContentType;
var contentTypeEnumerator = cttypes.getEnumerator();
while (contentTypeEnumerator.moveNext()) {
var contentType = contentTypeEnumerator.get_current();
if (contentType.get_name() === ctypeName) {
createdContentType = contentType;
var fieldRef = new Array();
for (var iAddFieldsCounter = 0; iAddFieldsCounter < 11; iAddFieldsCounter++) {
fieldRef[iAddFieldsCounter] = new SP.FieldLinkCreationInformation();
fieldRef[iAddFieldsCounter].set_field(createdFields[iAddFieldsCounter]);
createdContentType.get_fieldLinks().add(fieldRef[iAddFieldsCounter]);
createdContentType.update(true);
}
ctx.load(createdContentType);
ctx.executeQueryAsync(onAddFieldToContentTypeSuccess, onAddFieldToContentTypeFail);
}
}
}
function onAddFieldToContentTypeSuccess() {
alert('Site Columns added to Content Type.');
}
function onAddFieldToContentTypeFail(sender, args) {
alert('Failed to add Site Columns to Content Type. Error:' + args.get_message() + '\n' + args.get_stackTrace());
}
Found the answer using the enumerators provided in the JSOM API. Had to add a second enumerator for the fields inside the content type enumerator after gathering all content types and fields listed on the site.
Success Callback:
function onQuerysuccess() {
var oEnumerator = oSiteContentTypes.getEnumerator();
var oContentType;
var oSiteColumn;
var cttypeskeys =Object.keys(config["SiteContentTypes"]);
while (oEnumerator.moveNext()) {
oContentType = oEnumerator.get_current();
var oColEnumerator = oSiteColumns.getEnumerator();
while (oColEnumerator.moveNext()) {
oSiteColumn = oColEnumerator.get_current();
if (cttypeskeys.indexOf(oContentType.get_name()) > -1 && config["SiteContentTypes"][oContentType.get_name()]["FieldLinksTitle"].indexOf(oSiteColumn.get_title()) > -1) {
var newSiteCol = new SP.FieldLinkCreationInformation();
newSiteCol.set_field(oSiteColumn);
oContentType.get_fieldLinks().add(newSiteCol);
oContentType.update(true);
clientContext.load(oContentType);
}
}
if (Content Type Name Check) {
clientContext.executeQueryAsync(onsuccess, onfailed);
}
}
}
function onQueryfailed(sender, args) {
document.getElementById('text').value += ('Failed to fetch content type and field data. (' + args.get_message() + ')\n' + args.get_stackTrace());
}
function onsuccess() {
document.getElementById('text').value += 'Content Type Updated.\n';
}
function onfailed(sender, args) {
document.getElementById('text').value += ('Content Type Update failed. (' + args.get_message() + ')\n' + args.get_stackTrace());
}