Thursday, August 4, 2011

Get Taxonomy terms from the user while configuring a WebPart

In my current SharePoint 2010 project we make use of Managed Metadata terms a lot. We want to be able to select taxonomy terms while configuring WebParts, but the setup of the taxonomy field isn't quite straightforward. For the configuration of WebParts with exotic controls, you need to implement a custom ToolPart and link it to your WebPart. Because I think we will create a lot of custom ToolParts, I created a base class for displaying these taxonomy fields.

   1:  /// <summary>
   2:  /// This class makes it easier to work with Taxonomy data in a <see cref="Microsoft.SharePoint.WebPartPages.ToolPart">ToolPart</see>
   3:  /// </summary>
   4:  public class TaxonomyToolPart : ToolPart
   5:  {
   6:      /// <summary>
   7:      /// Gets or sets the name of the term store.
   8:      /// </summary>
   9:      /// <value>
  10:      /// The name of the term store.
  11:      /// </value>
  12:      public string TermStoreName { get; protected set; }
  13:      /// <summary>
  14:      /// Gets or sets the name of the term group.
  15:      /// </summary>
  16:      /// <value>
  17:      /// The name of the term group.
  18:      /// </value>
  19:      public string TermGroupName { get; protected set; }
  20:      /// <summary>
  21:      /// Gets or sets the name of the term set.
  22:      /// </summary>
  23:      /// <value>
  24:      /// The name of the term set.
  25:      /// </value>
  26:      public string TermSetName { get; protected set; }
  27:      /// <summary>
  28:      /// Gets or sets a value indicating whether multiple terms can be selected.
  29:      /// </summary>
  30:      /// <value>
  31:      ///   <c>true</c> if multiple terms can be selected; otherwise, <c>false</c>.
  32:      /// </value>
  33:      public bool MultiSelect { get; protected set; }
  34:   
  35:      private TaxonomyWebTaggingControl TaxonomyControl { get; set; }
  36:   
  37:      /// <summary>
  38:      /// Called by the ASP.NET page framework to notify server controls that use composition-based 
  39:      /// implementation to create any child controls they contain in preparation for posting back or rendering.
  40:      /// </summary>
  41:      protected override void CreateChildControls()
  42:      {
  43:          // create a panel that will hold all of our controls 
  44:          Panel toolPartPanel = new Panel();
  45:   
  46:          // create the actual control 
  47:          SPContext context = SPContext.Current;
  48:          SPSite site = context.Site;
  49:          TaxonomySession session = new TaxonomySession(site);
  50:          TermStore termStore = session.TermStores[TermStoreName];
  51:          Group group = termStore.Groups[TermGroupName];
  52:          TermSet productsTermSet = group.TermSets[TermSetName];
  53:   
  54:   
  55:          TaxonomyControl = new TaxonomyWebTaggingControl();
  56:          TaxonomyControl.ID = "taxonomyControl";
  57:          TaxonomyControl.SspId.Add(termStore.Id);
  58:          TaxonomyControl.TermSetId.Add(productsTermSet.Id);
  59:          TaxonomyControl.IsAddTerms = false;
  60:          TaxonomyControl.AllowFillIn = true;
  61:          TaxonomyControl.IsMulti = MultiSelect;
  62:   
  63:          TaxonomyControl.Text = GetTextFromWebPart(this.ParentToolPane.SelectedWebPart);
  64:   
  65:          toolPartPanel.Controls.Add(TaxonomyControl);
  66:   
  67:          // finally add the panel to the controls collection of the tool part 
  68:          Controls.Add(toolPartPanel);
  69:   
  70:          base.CreateChildControls();
  71:      }
  72:   
  73:      /// <summary>
  74:      /// Gets the textual representation of the selected terms from the WebPart and sets it on the Taxonomy control.
  75:      /// </summary>
  76:      /// <param name="webPart">The web part.</param>
  77:      /// <returns>a value from the webpart to select in the TaxonomywebTaggingControl</returns>
  78:      /// <remarks>Override this method in your child class to link the webpart property with the taxonomy field.</remarks>
  79:      /// <example>the term string has a value like 'Term 1|db61b704-cf1d-490d-bfc3-4cbcd8d2f453;Term 2|66b5696d-94a2-4299-ae34-63d3072ca357</example>
  80:      protected virtual string GetTextFromWebPart(WebPart webPart) { return string.Empty; }
  81:   
  82:      /// <summary>
  83:      /// Sets the textual representation of the selected terms from the Taxonomy control to the WebPart.
  84:      /// </summary>
  85:      /// <param name="webPart">The parent web part.</param>
  86:      /// <param name="selectedTerms">The selected terms.</param>
  87:      /// <remarks>Override this method in yout child class to link the taxonomy filed with the webpart property</remarks>
  88:      /// <example>the term string has a value like 'Term 1|db61b704-cf1d-490d-bfc3-4cbcd8d2f453;Term 2|66b5696d-94a2-4299-ae34-63d3072ca357</example>
  89:      protected virtual void SetTextToWebPart(WebPart webPart, string selectedTerms) { }
  90:   
  91:      /// <summary>
  92:      /// Called when the user clicks the OK or the Apply button in the tool pane.
  93:      /// </summary>
  94:      public override void ApplyChanges()
  95:      {
  96:          WebPart webPart = this.ParentToolPane.SelectedWebPart;
  97:          SetTextToWebPart(webPart, TaxonomyControl.Text);
  98:      }
  99:  }

This base class can now be used in a new class, where the configuration of the ToolPart and the linking with the WebPart needs to be implemented:

   1:  public class TestToolPart : TaxonomyToolPart
   2:  {
   3:      public TestToolPart()
   4:      {
   5:          this.TermStoreName = "Managed Metadata";
   6:          this.TermGroupName = "NL";
   7:          this.TermSetName = "Brand";
   8:          this.MultiSelect = true;
   9:          this.Title = "Taxonomy Example";
  10:      }
  11:   
  12:     protected override string GetTextFromWebPart(Microsoft.SharePoint.WebPartPages.WebPart webPart)
  13:      {
  14:          return ((TestWebPart)webPart).Text;
  15:      }
  16:   
  17:      protected override void SetTextToWebPart(Microsoft.SharePoint.WebPartPages.WebPart webPart, string selectedTerms)
  18:      {
  19:          ((TestWebPart)webPart).Text = selectedTerms;
  20:      }
  21:  }        

The only thing you need to do is override the GetToolParts() in your WebPart to inject your custom ToolPart in the ToolPart array, and your ToolPart should work.

No comments: