Second Life of a Hungarian SharePoint Geek

February 15, 2010

Build your own user interface components using the taxonomy controls

Filed under: SP 2010, Taxonomies — Tags: , — Peter Holpar @ 04:48

If you would like to use the built-in taxonomy controls of SharePoint 2010 your best choice might be to go with the TaxonomyWebTaggingControl. This is the class the field control of the TaxonomyField, TaxonomyFieldControl itself uses internally to render its content, although it does not expose the full capability of the control.

In this post I will show you some features of the TaxonomyWebTaggingControl using it in a visual web part project.

First, let’s see how to use it declaratively. Be sure Microsoft.SharePoint.Taxonomy is registered in your user control (.ASCX) file:

<%@ Register Tagprefix="Taxonomy" Namespace="Microsoft.SharePoint.Taxonomy" Assembly="Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

Having this registration, you can add TaxonomyWebTaggingControl using the following declaration:

<Taxonomy:TaxonomyWebTaggingControl AllowFillIn="true" IsMulti="true" SSPList="{29ff8c4f-37a6-4d42-8cef-f610f0a7c7e9}"  TermSetList="{a22cf1f5-427e-41d7-8af4-7aa4dc47197d}" AnchorId="{ec5ee636-f35c-43bd-92a0-56016a0a127c}" runat="server" />

This control instance allows multiple items and filling in values. The SSPList  attribute is to specify the Id of the term store(s) and the TermSetList attribute is to specify the Id of the term set(s). Note, that none of these two attributes are automatically suggested by IntelliSense or recognized by the compiler in Visual Studio 2010 beta 2, but they works as expected. You can specify multiple values in both of these attributes, separating them by semicolons (‘;’). It is a great way to combine multiple term sets even from multiple term stores. The AnchorId attribute sets the Id of the term that serves as the starting point of the term hierarchy used in the control. Only terms below the anchor will be suggested in the control.

Although it is not so hard to get these Ids using a little command line utility, specifying these settings by Guid values is not user friendly. So let’s switch to the coding approach, but before doing that, we add some additional content to the user control:

  1. <Taxonomy:TaxonomyWebTaggingControl ID="TestTaxonomyControl" runat="server" />
  2.  
  3. <asp:Button ID="SendButton" runat="server" Text="Send"
  4.     onclick="SendButton_Click" />
  5. <br />
  6. <br />
  7. <asp:Label ID="MetaDataLabel" runat="server" Text=""></asp:Label>

Having this done, we can alter to the code behind of the user control to the following:

  1. using System;
  2. using System.Web.UI;
  3. using System.Web.UI.WebControls;
  4. using System.Web.UI.WebControls.WebParts;
  5. using Microsoft.SharePoint.Taxonomy;
  6. using Microsoft.SharePoint;
  7. using System.Drawing;
  8.  
  9. namespace VisualWebPartTest1.VisualWebPart1
  10. {
  11.     public partial class VisualWebPart1UserControl : UserControl
  12.     {
  13.         protected void Page_Load(object sender, EventArgs e)
  14.         {
  15.             SPContext context = SPContext.Current;
  16.             SPSite site = context.Site;
  17.             TaxonomySession session = new TaxonomySession(site);
  18.             TermStore termStore = session.TermStores["MyTermStore"];
  19.             Group group = termStore.Groups["MyGroup"];
  20.             TermSet productsTermSet = group.TermSets["Products"];
  21.             TermSet languagesTermSet = group.TermSets["Languages"];
  22.  
  23.             TestTaxonomyControl.SspId.Add(termStore.Id);
  24.             TestTaxonomyControl.TermSetId.Add(productsTermSet.Id);
  25.             TestTaxonomyControl.TermSetId.Add(languagesTermSet.Id);
  26.             TestTaxonomyControl.AllowFillIn = true;
  27.             TestTaxonomyControl.IsMulti = true;
  28.         }
  29.  
  30.         protected void SendButton_Click(object sender, EventArgs e)
  31.         {
  32.             String validationMessage;
  33.             bool valid = TestTaxonomyControl.Validate(out validationMessage);
  34.  
  35.             if (valid)
  36.             {
  37.                 MetaDataLabel.Text = String.Empty;
  38.                 MetaDataLabel.ForeColor = Color.Black;
  39.                 TaxonomyFieldValueCollection values = new TaxonomyFieldValueCollection(String.Empty);
  40.                 values.PopulateFromLabelGuidPairs(TestTaxonomyControl.Text);
  41.  
  42.                 foreach (TaxonomyFieldValue value in values)
  43.                 {
  44.                     MetaDataLabel.Text += value.WssId + " / " + value.TermGuid + " / " + value.Label + "<br />";
  45.                 }
  46.             }
  47.             else
  48.             {
  49.                 MetaDataLabel.ForeColor = Color.Red;
  50.                 MetaDataLabel.Text = validationMessage;
  51.             }
  52.         }
  53.     }
  54. }

As you can see we use the SspId and TermSetId properties of the TaxonomyWebTaggingControl control to specify the term store and term sets. Both of this properties are of type List<Guid>. We specify two term sets for this control, one for the Languages and another one for Products.

image

Just a thought regarding the figure above. It seems that pressing Tab button to autocomplete the suggested value only works in the case of the first tag in taxonomy controls. I hope it is only a bug in beta 2 and will be corrected in the final version.

We handle the Click event of the SendButton control to validate the values specified in our taxonomy control. We can use the Validate method of the TaxonomyWebTaggingControl control for that. This method returns with a boolean value that represents the result of the validation, and an out String parameter that is the validation error message.

If the validation fails we display the error message. Note that the text box is empty now, since we don’t set its value on post back.

image

BTW, if you want the control to be able to add new terms:

  • There should be only a single term set attached to the control.
  • The term set must be open.
  • You should set the IsAddTerms property to true.

On success we display the selection values. The Text property of the TaxonomyWebTaggingControl control contains the label – Id pairs of the selected terms. To convert it to TaxonomyFieldValueCollection, we should use the PopulateFromLabelGuidPairs method.

image

Note, that the WssId is –1 for both values, since in this case the control is not bound to a site, not like in the case of a TaxonomyField (see my former post about the WssId).

Advertisements

14 Comments »

  1. Hi Peter,

    Thanks a lot for the very complete and informative posts !
    I have a question for you: I created a tabbed form in Silverlight 3 to create data programatically in a Sharepoint 2010 custom list and after some fighting I got it working (I display the SP 2010 custom list fields in Silverlight and when I click submit, the item is created in the list).

    Everything was fine until I added today a “Managed Metadata” column to the list and now I cannot find a way to set the right value of the term when I insert a new item on the custom list. My term set it pretty simple and, of course, it workd when you use the SP 2010 Vanilla forms (insert, edit, etc.)
    I have been struggling with the taxonomy feature and Silverlight because I cannot use it from the client model. Then I realized that I could probaly make a JSON call from Silverlight to get the terms from my data store and programatically (and automatically) assign them to the item and then perform the item creation with the term appended to it.

    But I have not be succesful so far because of the ssid, lcid, termstoreId, and many other IDs that the term store methods require as parameters.
    Do you have any articles or hints on how to successfully do this ?
    I would appreciate it very much.
    Thanks and best regards,

    Javier Lagos
    Montreal

    Comment by Javier Lagos — March 16, 2010 @ 23:03

  2. Thanks for this post.. was just looking for this bit :

    TaxonomyFieldValueCollection values = new TaxonomyFieldValueCollection(String.Empty);
    values.PopulateFromLabelGuidPairs(TestTaxonomyControl.Text);

    And it helped me 😉

    Comment by Robin — October 14, 2010 @ 10:32

    • Hi Robin,

      Nice to see that you at zevenseas read my blog. I hope I meet you guys at TechEd Berlin next month.

      Peter

      Comment by Peter Holpar — October 14, 2010 @ 20:02

  3. Thanks Peter for this information.
    I want to create custom webpart and also want to provide Property Pane when User can select tag and based on this tag webpart filter result.
    can you please help me on this

    Comment by Ronak — October 21, 2010 @ 19:19

  4. Thanks for the post.

    This method will show me the whole taxonomy term set. Is there a way to limit it to just a specific node?

    Comment by jared — December 19, 2010 @ 19:26

    • Hi Jared,

      As I wrote, you can use the AnchorId attribute to narrow the result to a specific branch of the term set.

      Peter

      Comment by Peter Holpar — December 21, 2010 @ 21:59

  5. Hi Peter,

    Is there a way to make a postback from this control once a value is entered. Basically, I have a scenario where I want to pull some additional fields based on Managed Metadata column value on a form. I want to do that as soon as the user selects or enters the value, instead of on a button click.

    -mswin

    Comment by mswin — July 5, 2011 @ 14:07

    • @mswin: I’ve not played with that, but probably you can do that with jQuery and the client object model.

      Comment by Peter Holpar — July 8, 2011 @ 07:22

  6. Thank you so much for this sample!!!

    Comment by K.H. — October 13, 2011 @ 07:13

  7. Having a problem updating metadata field with the following,
    the code below only updates the list metadata field, with the last value of TestTaxonomyControl, please help

    TaxonomyFieldValueCollection values = new TaxonomyFieldValueCollection(String.Empty);
    values.PopulateFromLabelGuidPairs(TestTaxonomyControl.Text);
    TaxonomyField entKeyword;
    entKeyword = (TaxonomyField)item.Fields[“Metadata”];

    foreach (TaxonomyFieldValue value in values)
    {
    TaxonomyFieldValue term = new TaxonomyFieldValue(“1;#” + value.Label + “|” + value.TermGuid + “;#”);

    entKeyword.SetFieldValue(item, term);
    entKeyword.Update();

    }

    Comment by surfy1h — March 4, 2012 @ 06:20

  8. how can i search for part of a word
    for example i wont to find the word “product1” so i should be able to type “ropd”

    Comment by debbi — April 4, 2012 @ 09:42

  9. (the last response wasn’t exact- so im sending it again):

    how can i search for part of a word
    for example if i want to find the word “product1″
    i should be able to type “rodu”
    thanks!!

    Comment by debbi — April 4, 2012 @ 10:22

    • I wanted to do it with SP 2010 beta 2 as well, but the query format was fixed in one of the SP assemblies. An SQL query filter like this was sent to SQL server: “rodu%”, that means you cannot achieve your goal without re-implementing SP 2010 functionality and direct database tampering, that is not a supported solution.

      Comment by Peter Holpar — April 9, 2012 @ 20:24


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: