Overview
In previous post we’ve discussed one of the useful features for TaxonomyWebTaggingControl control that allows to specify ID of parent Term for any valid value in control. This could improve user experience in cases when subset of terms should be displayed for selection based on some conditions instead of displaying all terms from term set.
This time we will dig in a little bit to investigate how TaxonomyWebTaggingControl works and illustrate some examples how to access and manipulate TaxonomyWebTaggingControl on the client side.
TaxonomyWebTaggingControl
Before we proceed let me clarify some details about TaxonomyWebTaggingControl control itself.
TaxonomyWebTaggingControl ASP.NET control is a server side wrapper for ScriptForWebTaggingUI client control. One of the main purposes of TaxonomyWebTaggingControl control is to provide the ability to initialize ScriptForWebTaggingUI control by generating parameters on the server side (see table 1).
It is interesting to note here that ScriptForWebTaggingUI was built using Script#. Script# is a development tool that generates JavaScript by compiling C# source code. It means that ScriptForWebTaggingUI was originally created by Microsoft as C# control and this is another great example of using Script# for building real world applications.
ScriptForWebTaggingUI control properties
Table 1. ScriptForWebTaggingUI client control properties .
InputFieldId | Input field ID that is used for storing term value |
SspId | IDs of the TermStore objects that this control will validate against |
GroupId | Gets and sets the IDs of the Group object that this control will validate against |
TermSetId | Gets the IDs of the TermSet object that this control will validate against |
AnchorId | Get or set the ID of the Taxonomy whose children will be used to validate against |
IsMulti | Gets or sets whether this control accepts multiple Term objects |
AllowFillIn | Gets or sets whether this control will give the option of adding new Term objects if the Open() property is set. |
WidthCSS | Gets or sets a CSS class that will be applied to the control that should specify a width CSS class. |
Lcid | Gets or sets the LCID repesenting the language this control will validate against. |
IsSpanTermSets | Gets and sets whether this control will resolve against all TermSet objects or only the TermSet objects provided. |
IsSpanTermStores | Gets or sets whether this control will resolve against all TermStore objects or only the TermStore objects provided. |
IsIgnoreFormatting | Gets or sets whether this control will format valid and invalid Term objects or leave them as plain text. |
IsIncludeDeprecated | Gets or sets whether this control will resolve against deprecated Term objects. |
IsIncludeUnavailable | Gets or sets whether this control will resolve against unavailable Term objects. |
IsIncludeTermSetName | Gets and sets whether this control will resolve against the names of TermSet object names. |
IsAddTerms | Gets and sets whether this control will try to add unresolved Term objects to the TermSet object. |
IsIncludePathData | Gets or sets whether this control will include the full GUID path for all Term objects. |
IsUseCommaAsDelimiter | Gets or sets whether this control will use a comma in addition to a semi-colon as a delimiter. |
Disable | Gets or sets whether this control is disabled or not |
ExcludeKeyword | Gets and sets whether this control will resolve against keyword Term object or not |
WebServiceUrl | Gets and sets the URL of the TaxonomyInternalService that will be used to resolve against |
FieldName | Gets and sets the value that will be shown in the ToolTip on the client |
FieldId | Gets and sets the id of field |
DisplayPickerButton | Gets or sets whether this control will allow browsing with the picker |
Relevant properties for server side TaxonomyWebTaggingControl control are listed here.
Microsoft.SharePoint.Taxonomy client namespace in SharePoint 2010
Table 2. The following table lists classes used for ScriptForWebTaggingUI control
HighlightResult | |
ScriptForWebTaggingUI | Represents container for ControlObject |
ControlObject | Represents control itself |
Term | Defines Term on the client side |
ScriptResources | |
PanelResizer | |
SelectionMadeEventArgs | |
SuggestionContainer | |
SuggestionGroup | |
Suggestion |
Access and manipulate TaxonomyWebTaggingControl from client side
To manipulate term values in TaxonomyWebTaggingControl control we’ll use Client Object model for Taxonomy listed in table 2, in particular ControlObject capabilities. Below are provided methods for getting and setting values in TaxonomyWebTaggingControl on the client side
To find TaxonomyWebTaggingControl on the client side webTaggingId identifier is used, that corresponds to ContainerId property of control.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Set Taxonomy ControlObject value | |
//webTaggingId – TaxonomyWebTaggingControl ID | |
//termValue – represents a single value held in a TaxonomyField object using the following format: NameOfTerm|GUIDOfTerm | |
function setTaxonomyControlObjectValue(webTaggingId, termValue) { | |
var webTaggingCtl = $get(webTaggingId); | |
var taxCtlObj = new Microsoft.SharePoint.Taxonomy.ControlObject(webTaggingCtl); | |
taxCtlObj.enableControl(true); | |
taxCtlObj.setRawText(termValue); | |
taxCtlObj.retrieveTerms(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Get Taxonomy ControlObject value | |
//webTaggingId – TaxonomyWebTaggingControl ID | |
function getTaxonomyControlObjectValue(webTaggingId) { | |
var webTaggingCtl = $get(webTaggingId); | |
var taxCtlObj = new Microsoft.SharePoint.Taxonomy.ControlObject(webTaggingCtl); | |
var termValue = taxCtlObj.getRawText(); | |
return termValue; | |
} |
Usage
Testing data
For demonstration purposes we’ll use information about countries that has the following structure:
- the first level is the continents
- the second level is the countries
Example 1. Setting TaxonomyWebTaggingControl control value
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Example 1. Setting TaxonomyWebTaggingControl control value during event (page load, button click and etc.) | |
function initCountryTaggingControl() { | |
var countriesControlId = "ctl00_PlaceHolderMain_ctl03"; | |
var continentTermValue = "Africa|43f3b1e7-e40c-45d2-a613-88643668d373"; | |
setTaxonomyControlObjectValue(countriesControlId, continentTermValue); | |
} | |
ExecuteOrDelayUntilScriptLoaded(initCountryTaggingControl, 'ScriptForWebTaggingUI.js'); |
Example 2. Getting TaxonomyWebTaggingControl control value
In this example is demonstrated how to get term value from
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Example 2. Getting TaxonomyWebTaggingControl control value | |
function initCountryTaggingControl2() { | |
var countriesControlId = "ctl00_PlaceHolderMain_ctl03"; | |
var continentTermValue = getTaxonomyControlObjectValue(countriesControlId); | |
} | |
ExecuteOrDelayUntilScriptLoaded(initCountryTaggingControl, 'ScriptForWebTaggingUI.js'); |
Example 3.Retrieve ScriptForWebTaggingUI control properties
For every instance of TaxonomyWebTaggingControl control placed on page is generated corresponding ScriptForWebTaggingUI control that could be used to retrieving properties as shown below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Example 3. Retrieve ScriptForWebTaggingUI control properties | |
function initCountryTaggingControl3() { | |
var tagUI = document.getElementById(taggingWebId); | |
if (tagUI){ | |
console.log(tagUI.TermSetId); //prints TermSet ID | |
console.log(tagUI.SspId); //prints TermStore ID | |
} | |
} | |
ExecuteOrDelayUntilScriptLoaded(initCountryTaggingControl3, 'ScriptForWebTaggingUI.js'); |
Hi, Vadim!
Have you found any way to attach to the event when the user clicks OK button in WebTagging dialog and the value of termset field is changed?
Hi Max,
when the value of termset field is changed, event
Microsoft.SharePoint.Taxonomy.ScriptForWebTaggingUI.onTextChanged
is raised by default.This event is registered for ScriptForWebTaggingUI control with the following line:
RTE.CanvasEvents.registerListener(RTE.CanvasEvents.editableRegionChangedEvent, Function.createDelegate(null, Microsoft.SharePoint.Taxonomy.ScriptForWebTaggingUI.onTextChanged));
It means that you could provide additional event handler when the value of termset field is changed:
function initTaggingControl() {
RTE.CanvasEvents.registerListener(RTE.CanvasEvents.editableRegionChangedEvent, Function.createDelegate(null, onCustomTextChanged));
}
function onCustomTextChanged(sender, args) {
//Some code after value of termset field is changed goes here...
}
ExecuteOrDelayUntilScriptLoaded(initTaggingControl, 'ScriptForWebTaggingUI.js');
Hope it helps,
Vadim
Hi Vadim,
I’m working on a different project now and come across your blog again while searching for different kind of information after a year and just noticed that I asked you a question and you actually answered it! 🙂
I wish I had seen your answer before! Actually, a year ago I handle onchange event differently: http://maxim-dikhtyaruk.blogspot.com/2013/03/client-side-scripting-for-taxonomyterm.html
Solution is definitely not elegant and right, but it worked for me :).
Now, we are looking for possibility of using SharePoint taxonomy picker in our provider-hosted app. Presumably, it will work fine with client context…
Cheers,
Maksym
Great post Vadim! Very helpful.
I need to go a little further. Is there a way to create the TaxonomyWebTaggingControl directly from client side?
I need to create the control dynamically from javascript. Do you think there’s a way to do that?
Thanks!
Hi Guillermo, yes, I’m pretty sure it is doable.
The list of some points that should be considered for implementing JavaScript based taxonomy control:
Thanks Vadim!
I’ll give it a try and let you know.
Hi Guillermo, thank you, it is really interesting idea.
Vadim, I finally managed to create the taxonomy control from client side code. Thanks for the help!
I leave you a function to do this:
//id: the id the control will have
//parent: dom element where the field will be appended
//SspId: SspId for the field in GUID format, ex: {00923257-fabc-4cd2-8442-ff475ed16743}
//TermSetId: TermSetId for the field in GUID format, ex: {00923257-fabc-4cd2-8442-ff475ed16743}
function generateTaxonomyField(id, parent, SspId, TermSetId) {
//Generates required dom elements
var span = $(“”);
span.append($(“”));
span.append($(“”));
parent.append(span);
//Get the site collection url
var wsUrl = window.location.protocol + “//” + window.location.host + _spPageContextInfo.siteServerRelativeUrl;
wsUrl.replace(‘/’, ‘\u002f’);
//initialize control
var tagUI = document.getElementById(id + “_div”);
if (tagUI) {
tagUI[‘InputFieldId’] = id + “_input”;
tagUI[‘SspId’] = SspId;
tagUI[‘GroupId’] = ‘00000000-0000-0000-0000-000000000000’;
tagUI[‘TermSetId’] = TermSetId;
tagUI[‘AnchorId’] = ‘00000000-0000-0000-0000-000000000000’;
tagUI[‘IsMulti’] = true;
tagUI[‘AllowFillIn’] = true;
tagUI[‘WidthCSS’] = ‘ms-taxonomy-width’;
tagUI[‘JavascriptOnValidation’] = “”;
tagUI[‘Lcid’] = 3082;
tagUI[‘IsSpanTermSets’] = false;
tagUI[‘IsSpanTermStores’] = false;
tagUI[‘IsIgnoreFormatting’] = false;
tagUI[‘IsIncludeDeprecated’] = false;
tagUI[‘IsIncludeUnavailable’] = false;
tagUI[‘IsIncludeTermSetName’] = false;
tagUI[‘IsAddTerms’] = false;
tagUI[‘IsIncludePathData’] = false;
tagUI[‘IsUseCommaAsDelimiter’] = false;
tagUI[‘Disable’] = false;
tagUI[‘ExcludeKeyword’] = false;
tagUI[‘WebServiceUrl’] = wsUrl + ‘\u002f_vti_bin\u002fTaxonomyInternalService.json’;
tagUI[‘FieldName’] = ‘Agregar t\u00E9rminos’;
tagUI[‘FieldId’] = ‘00000000-0000-0000-0000-000000000000’;
tagUI[‘DisplayPickerButton’] = true;
var _emmTaggingLoadCall;
if (_emmTaggingLoadCall == null) {
_emmTaggingLoadCall = true;
SP.SOD.executeFunc(‘ScriptForWebTaggingUI.js’, ‘Microsoft.SharePoint.Taxonomy.ScriptForWebTaggingUI.taggingLoad’,
function () { Microsoft.SharePoint.Taxonomy.ScriptForWebTaggingUI.resetEventsRegistered(); }
);
}
SP.SOD.executeFunc(‘ScriptForWebTaggingUI.js’, ‘Microsoft.SharePoint.Taxonomy.ScriptForWebTaggingUI.onLoad’,
function () { Microsoft.SharePoint.Taxonomy.ScriptForWebTaggingUI.onLoad(id + “_div”); }
);
}
}
var container = $(‘#container’);
generateTaxonomyField(‘myTaxonomyField’, container, “{00923257-fabc-4cd2-8442-ff475ed16743}”, “{6abc6553-8a75-4a0b-8100-ce330ce4779b}”);
Hi Guillermo,
oh, that’s a great, thanks for sharing it!
hello, I used Ovsleep’s methods it works fine , i need to add a custom fucntion for edit text ? any idea how can i addthis event for edit ,!!! where can add the call function ?
It is possible to share a sample solution? Thanks.
I’m having problems with getting the pop-up, of the taxonomyWebTaggingControl, to work. It remains empty. Filling out terms directly in the control, the suggestions, etc… all work. Only the the “select pop-up” is giving me a headache.
I’m getting error, and the dialog is remaining empty:
Refused to display ‘http://XXX/_layouts/15/WebTaggingDialog.aspx?Field=XXX&IsDlg=1′ in a frame because it set ‘X-Frame-Options’ to ‘SAMEORIGIN’
any ideas ?
Hi, I’m getting the following error, and the dialog remains empty:
Refused to display ‘http://XXX/_layouts/15/WebTaggingDialog.aspx?Field=XXX&IsDlg=1’ in a frame because it set ‘X-Frame-Options’ to ‘SAMEORIGIN’
Any ideas ?
Got it.. I needed to lazy load init.js and strings.js before the call to ‘Microsoft.SharePoint.Taxonomy.ScriptForWebTaggingUI.onLoad(id + “_div”); }’
My next issue here (I’ve had a lot so far) Is the autolookup in the input control..
In the dialog it works like a charm though 🙂
Any ideas ?
How should the termValue be formatted if the control accepts multiple values?
This post was life saver. Works like charms. Other ways with javascript couldn’t actually save the value of the term on a Form of new item for a particular content type. I introduce the code via JSLink associated to the Content Type.
Reblogged this on Nilsandrey's Weblog.
Not sure how this has worked for others but I found the webTaggingId required isnt the control ID but the div that sits beneath that control ID, which you wont know at runtime. So I had to have this in the get function above:
var webTaggingId = jQuery(“#” + elementId + “> div”).attr(“id”);
Otherwise it doesnt work.
Great ! thanks a lot you saved my life !
In my case The webTaggingId is the div taxonomy fieldName + ‘_$container’
I found the code required to render the taxonomy picker on the web but ovsleep is the only one I’ve found that has sample values. I spent a good number of hours ( more than I would like to admit ) trying to figure out why the picker was not rendering. Eventually I read through this post, and comments, and found out braces were required around the sspId and termSetId guids.
I have problem with
function initTaggingControl() {
RTE.CanvasEvents.registerListener(RTE.CanvasEvents.editableRegionChangedEvent, Function.createDelegate(null, onCustomTextChanged));
}
function onCustomTextChanged(sender, args) {
//Some code after value of termset field is changed goes here…
}
ExecuteOrDelayUntilScriptLoaded(initTaggingControl, ‘ScriptForWebTaggingUI.js’);
or
tagUI[‘JavascriptOnValidation’] = “”
Call more than one time on click or input term