Back

TechnologyApr 19, 2017

Editing Multi-Value Managed Metadata Fields With JavaScript in SharePoint Online

Austin Christenberry

One of the use cases for a recent SharePoint Online (SPO) project required leveraging the JavaScript object model (JSOM) to add or remove managed metadata terms on a list item field. Considering that setting the value for a single-value managed metadata field is fairly straightforward, this task turned out to be slightly trickier than I originally anticipated. This post explains how to add an additional term to the list item field value, as well as how to remove one.

environment setup and assumptions

Let’s assume that our SPO environment consists of the following:

  • A term set within the default tenant term store called “Skills”.

  • A site with a relative path of “/sites/employees”.

  • A custom content type called “Employee” that includes a field called “Skills”, which is configured as a managed metadata column that uses the “Skills” term set and allows multiple values.

  • A list called “Employee List” that has been configured so the only available content type is “Employee”.

  • An item in the list with the title “John Doe”.

    • The list item ID is 1.

    • The Skills field for this list item currently has two terms, with the labels JavaScript and Ruby.

adding new terms to the field value

In order to edit the existing contents of a multi-value field, you’ll need to set a TaxonomyFieldValueCollection object with the appropriate terms. The simplest way to do this is to form a string that contains the GUID, WSS ID, and Label of each term that should be included in the collection, and then convert this string into the TaxonomyFieldValueCollection.

The string should use the following format: WssId;#Label|GUID, with “;#” used as the delimiter. For example, suppose you have the following terms:

Term 1: LabelJavaScriptWSS ID23GUID725abddc-37d1-4675-3364-a9da0020cd1c

Term 2: LabelRubyWSS ID24GUID932dacbd-66d4-2150-5312-b3ac1482ac5d

A TaxonomyFieldValueCollection that includes both of these terms would be represented by the following string: "23;#JavaScript|725abddc-37d1-4675-3364-a9da0020cd1c;#24;#Ruby|932dacbd-66d4-2150-5312-b3ac1482ac5d"

The JavaScript snippet below shows how to add a new term to a managed metadata list item field:

function addTermToFieldValue( termGuidToAdd, //GUID of the term to add to the collection termLabelToAdd, //Label of the term to add to the collection siteUrl, //Relative URL of the relevant site listName, //Title of the relevant list listItemId, //ID of the relevant list item fieldName) //Internal name of the multi-value managed metadata field {        //Code requires sp.js and sp.taxonomy.js        SP.SOD.loadMultiple(['sp.js', 'sp.taxonomy.js'], function () {               //Instantiate the client context               var ctx = new SP.ClientContext(siteUrl);               //Load the list item               var oList = ctx.get_web().get_lists().getByTitle(listName);               self.oListItem = oList.getItemById(listItemId);               ctx.load(self.oListItem);               //Load the managed metadata site column               var field = oList.get_fields().getByInternalNameOrTitle(fieldName);               self.txField = ctx.castTo(field, SP.Taxonomy.TaxonomyField);               ctx.load(self.txField);               //Run query               ctx.executeQueryAsync(function () {               //Get the managed metadata field on the list item               var listField = self.oListItem.get_item(fieldName);               var enumerator = listField.getEnumerator();               //Define variable to contain the string of terms for the field value               var termStr = "";               //Iterate through current terms within the field               while (enumerator.moveNext()) {                 var item = enumerator.get_current();                 var guid = item.get_termGuid();                 var wssId = item.get_wssId();                 var label = item.get_label();                 termStr += wssId + ';#' + label + '|' + guid + ';#';               }               //Add new term to the string. Use -1 for WssId.               termStr += "-1;#" + termLabelToAdd + "|" + termGuidToAdd;               //Convert the term string to a TaxonomyFieldValueCollection               var newTerms = new SP.Taxonomy.TaxonomyFieldValueCollection(ctx, termStr, self.txField);             //Set the field value to the new TaxonomyFieldValueCollection             self.txField.setFieldValueByValueCollection(self.oListItem, newTerms);             //Update the list item             self.oListItem.update();             ctx.load(self.oListItem);             //Run query             ctx.executeQueryAsync(function () {                      //Success                      console.log('Field successfully updated.');                }, function (sender, args) {                      //Error                      console.log('An error occurred:' + args.get_message());                });             });        }); }

Using the environment setup we defined above, you could then call the following in order to add the term “Python” to the Skills field for John Doe (note: Python is assumed to be an existing term in the term set with an existing GUID, it just isn’t on this particular list item field):

var guidToAdd = "00000000-0000-0000-000000000000"; //real GUID goes herevar labelToAdd = "Python"; var siteUrl = "https://<domain>.sharepoint.com/sites/employees";var listName = "Employee List"; var listItemId = 1; //ID for John Doevar fieldName = "Skills"; addTermToFieldValue(guidToAdd, labelToAdd, siteUrl, listName, listItemId, fieldName);

A few important notes:

  • The script uses the SOD.loadMultiple

    method to ensure the dependencies for the logic (sp.js and sp.taxonomy.js) are loaded.

  • After the existing terms in the current field value are loaded, the script iterates through the collection to form the appropriate string.

  • The script then adds the new term using the specified termLabelToAdd and termGuidToAdd, with a WSS ID of -1 (the WSS ID will change once the specified term is added to the field value).

  • Once the new term has been added to the string, it’s converted into a TaxonomyFieldValueCollection variable, which will be used to actually set the new value for the field.

removing terms from the field value

The process to remove a term is very similar. You’ll still need to iterate through all the existing terms within the field value to form the appropriate string—but if the GUID of a term equals the GUID of the term needing to be removed, then you simply won’t include that term in the string that’s being built.

The following shows the full implementation: 

function removeTermFromFieldValue( termGuidToRemove, siteUrl, listName, listItemId, fieldName) { //Code requires sp.js and sp.taxonomy.js SP.SOD.loadMultiple(['sp.js', 'sp.taxonomy.js'], function () { //Instantiate the client context var ctx = new SP.ClientContext(siteUrl); //Load the list item var oList = ctx.get_web().get_lists().getByTitle(listName); self.oListItem = oList.getItemById(listItemId); ctx.load(self.oListItem); //Load the managed metadata site column var field = oList.get_fields().getByInternalNameOrTitle(fieldName); self.txField = ctx.castTo(field, SP.Taxonomy.TaxonomyField); ctx.load(self.txField); //Run query ctx.executeQueryAsync(function () { //Get the managed metadata field on the list item var listField = self.oListItem.get_item(fieldName); var enumerator = listField.getEnumerator(); //Define variable to contain the string of terms for the field value var termStr = ""; //Iterate through current terms within the field while (enumerator.moveNext()) { var item = enumerator.get_current(); var guid = item.get_termGuid(); //As long as the GUID of the current item doesn't match the //GUID of the one to remove, add it to the term string if (guid != termGuidToRemove) { var guid = item.get_termGuid(); var wssId = item.get_wssId(); var label = item.get_label(); termStr += wssId + ';#' + label + '|' + guid + ';#'; } } //Remove the trailing ";#" characters termStr = termStr.slice(0,-2); //Convert the term string to a TaxonomyFieldValueCollection var newTerms = new SP.Taxonomy.TaxonomyFieldValueCollection(ctx, termStr, self.txField); //Set the field value to the new TaxonomyFieldValueCollection self.txField.setFieldValueByValueCollection(self.oListItem, newTerms); //Update the list item self.oListItem.update(); ctx.load(self.oListItem); //Run query ctx.executeQueryAsync(function () { //Success console.log('Field successfully updated.'); }, function (sender, args) { //Error console.log('An error occurred:' + args.get_message()); }); }); }); }

And going back to the “John Doe” example, you could call this method as follows if you wanted to remove “Ruby” from the Skills field:

var guidToRemove = "932dacbd-66d4-2150-5312-b3ac1482ac5d"; //GUID for Rubyvar siteUrl = "https://<domain>.sharepoint.com/sites/employees"; var listName = "Employee List"; var listItemId = 1; //ID for John Doevar fieldName = "Skills"; removeTermFromFieldValue(guidToRemove, siteUrl, listName, listItemId, fieldName);

A few important notes:

  • As mentioned before, the while loop now contains a conditional statement so that the term with the GUID to be removed will

     

    not

     

    be added into the string that represents the new value.

  • The line

     

    termStr = termStr.slice(0,-2)

    ; is used simply to remove the trailing “;#” that would be included at the end of the string after exiting the while loop.

conclusion

If you have questions or comments about this blog post or other aspects of SharePoint Online development, contact us at findoutmore@credera.com.