Skip to main content

TagCloud Webpart in SharePoint 2007

While everyone else right now seems to be blogging about SharePoint 2010, I decided to blog a little bit about the previous product, SharePoint 2007.

Recently, I had to develop a webpart that shows Tags from either a Site collection level or subsite level.

I will give you the code but firstly, here is how it works:

Assumining that you already have a library/list that has a choice field called Category(it can have any name), the webpart will search the site collection/subsite(depending on the scope you choose) for all columns that are named 'Category', and when found, will pull out the selected choices for display. Remember that this is a choice column, meaning that the choices will be repeatitive, and therefore, the more repeative the choices are, the bigger the font size of the Tag name will appear on the webpart.

Secondly, the tags will get random colors on page load, while at the same time will be hyperlinked, and when you click on a tag, it will be passed to the Search and generate search results for you on the search page to library/list items you have permissions on.

Thirdly, on the webpart properties, you get the privilege of changing the choice column name to point to, the scope(site collection or subsite), as well as change the search string to use, and also enable caching etc.

Fouthly, I have a feeling that this is going to be the longest blog post have ever made, nevertheless, the following is the name space code:

**remember to generate your own GUID.

using System;
using System.Data;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.ComponentModel;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace TagCloud.TagCloud
{
[Guid("9eb18673-6617-4c63-b716-8cf8f935318e")]
public class TagCloudClass : System.Web.UI.WebControls.WebParts.WebPart
{
// Fields
private string documentLibraryType = "1";
private bool isActivatedCache = true;
private string listType = "0";
private bool openItemsInNewWindows;
private readonly Random rnd = new Random(DateTime.Now.Millisecond);
private Enumerations.SearchScopes scope = Enumerations.SearchScopes.SiteCollection;
private char separator = ',';
private string tagField = "Category";
private readonly Dictionary Tags = new Dictionary();
private string targetUrl = "/_layouts/OSSSearchResults.aspx?k=";

// Methods
public TagCloudClass()
{
this.rnd = new Random(DateTime.Now.Millisecond);
this.Tags = new Dictionary();
this.documentLibraryType = "1";
this.listType = "0";
this.scope = Enumerations.SearchScopes.SiteCollection;
this.separator = ',';
this.tagField = "Category";
this.targetUrl = "/_layouts/OSSSearchResults.aspx?k=";
this.isActivatedCache = true;
}


private void AddLinks(string key)
{
Tag tag = this.Tags[key];
this.AddSeparator();
Table child = new Table();
child.Width = new Unit(100.0, UnitType.Percentage);
foreach (TagLink link in tag.Links)
{
TableRow row = new TableRow();
child.Rows.Add(row);
TableCell cell = new TableCell();
row.Cells.Add(cell);
HyperLink link2 = new HyperLink();
link2.Text = link.Title;
link2.NavigateUrl = link.ItemUrl;
cell.Controls.Add(link2);
}
this.Controls.Add(child);
}

private void AddSeparator()
{
Table child = new Table();
child.Width = new Unit(100.0, UnitType.Percentage);
TableRow row = new TableRow();
child.Rows.Add(row);
TableCell cell = new TableCell();
cell.HorizontalAlign = HorizontalAlign.Center;
row.Cells.Add(cell);
Label label = new Label();
label.Text = "----------------";
cell.Controls.Add(label);
this.Controls.Add(child);
}

private void AddTag(DataRow row, string localTag)
{
Tag newTag = new Tag();
newTag.Title = localTag;
SaveTag(newTag, row);
this.Tags.Add(localTag, newTag);
}

private void AddTags(string listType, Enumerations.SearchScopes searchScope)
{
DataTable results = this.GetResults(listType, searchScope);
this.GetTags(results);
}

private void BuildWebPart()
{
try
{
this.AddTags(this.ListType, this.Scope);
this.AddTags(this.DocumentLibraryType, this.Scope);
Table child = new Table();
child.Width = new Unit(100.0, UnitType.Percentage);
TableRow row = new TableRow();
child.Rows.Add(row);
TableCell cell = new TableCell();
cell.HorizontalAlign = HorizontalAlign.Center;
row.Cells.Add(cell);
this.Controls.Add(child);
foreach (KeyValuePair pair in this.Tags)
{
LinkButton button = new LinkButton();
button.Text = pair.Value.Title;
int count = pair.Value.Links.Count;
button.ToolTip = string.Format("{0} occurrance", count);
button.Font.Size = new FontUnit(GetFontSize(count), UnitType.Point);
button.ForeColor = this.GetRandomColor();
button.CommandArgument = pair.Key;
button.Click += new EventHandler(this.Tag_Click);
cell.Controls.Add(button);
Literal literal = new Literal();
literal.Text = " ";
cell.Controls.Add(literal);
}
}
catch (Exception exception)
{
this.SetErrorMessage(exception);
}
}

protected override void CreateChildControls()
{
base.CreateChildControls();
this.BuildWebPart();
}

private static string GetErrorMessage(Exception ex)
{
StringBuilder builder = new StringBuilder();
try
{
StackTrace trace = new StackTrace(ex, true);
builder.AppendLine(string.Format(" Stack trace for current level: {0}", trace));
StackFrame[] frames = trace.GetFrames();
if (frames != null)
{
foreach (StackFrame frame in frames)
{
builder.AppendLine(string.Format(" File: {0}", frame.GetFileName()));
builder.AppendLine(string.Format(" Method: {0}", frame.GetMethod().Name));
builder.AppendLine(string.Format(" Line Number: {0}", frame.GetFileLineNumber()));
builder.AppendLine(string.Format(" Column Number: {0}", frame.GetFileColumnNumber()));
}
}
}
catch
{
}
return builder.ToString();
}

private static double GetFontSize(int count)
{
double num = 8.0;
switch (count)
{
case 2:
num = 10.0;
break;

case 3:
num = 12.0;
break;

case 4:
num = 14.0;
break;

case 5:
num = 16.0;
break;

case 6:
num = 18.0;
break;

case 7:
num = 20.0;
break;

case 8:
num = 22.0;
break;

case 9:
num = 24.0;
break;
}
if (count > 10)
{
num = 26.0;
}
return num;
}

private static string GetItemUrl(string s)
{
string str = string.Empty;
try
{
string str2 = s.Split(new char[] { '#' })[1];
string str3 = str2.Remove(str2.LastIndexOf('/'));
string str4 = s.Substring(s.LastIndexOf('/') + 1);
string str5 = str4.Remove(str4.LastIndexOf('_'));
str = SPContext.Current.Web.Site.Url + "/" + str3 + "/DispForm.aspx?ID=" + str5;
}
catch (Exception)
{
}
return str;
}

private Color GetRandomColor()
{
Color black = Color.Black;
try
{
int red = this.rnd.Next(0, 0xff);
int green = this.rnd.Next(0, 0xff);
int blue = this.rnd.Next(0, 0xff);
black = Color.FromArgb(red, green, blue);
}
catch
{
}
return black;
}

private DataTable GetResults(string listType, Enumerations.SearchScopes searchScope)
{
string str = "";
string str2 = string.Format("", this.TagField);
string str3 = "";
if (!this.isActivatedCache)
{
SPSiteDataQuery query = new SPSiteDataQuery();
query.Lists = str;
query.ViewFields = str2;
query.Webs = str3;
return SPContext.Current.Web.GetSiteData(query);
}
CrossListQueryInfo queryCacheInfo = new CrossListQueryInfo();
queryCacheInfo.WebUrl = SPContext.Current.Site.ServerRelativeUrl;
queryCacheInfo.Lists = str;
queryCacheInfo.Webs = str3;
queryCacheInfo.Query = string.Format("", this.TagField);
queryCacheInfo.ViewFields = str2;
CrossListQueryCache cache = new CrossListQueryCache(queryCacheInfo);
return cache.GetSiteData(SPContext.Current.Site);
}

private void GetTag(DataRow row, string tag)
{
if (this.Tags.ContainsKey(tag))
{
this.UpdateTag(row, tag);
}
else
{
this.AddTag(row, tag);
}
}

private void GetTags(DataTable results)
{
foreach (DataRow row in results.Rows)
{
string[] strArray = row[3].ToString().Split(new char[] { this.Separator });
foreach (string str in strArray)
{
this.GetTag(row, str.Trim());
}
}
}

private static void SaveTag(Tag newTag, DataRow row)
{
TagLink item = new TagLink();
item.ListID = new Guid(row[0].ToString());
item.WebID = new Guid(row[1].ToString());
item.ItemUrl = GetItemUrl(row[4].ToString());
item.Title = row[5].ToString();
newTag.Links.Add(item);
}

private void SetErrorMessage(Exception ex)
{
this.Controls.Clear();
Label child = new Label();
child.Text = GetErrorMessage(ex);
child.CssClass = "ms-formvalidation";
this.Controls.Add(child);
}

private void Tag_Click(object sender, EventArgs e)
{
LinkButton button = sender as LinkButton;
if (button != null)
{
if (string.IsNullOrEmpty(this.TargetUrl))
{
this.AddLinks(button.CommandArgument);
}
else
{
this.Page.Response.Redirect(this.TargetUrl + button.CommandArgument);
}
}
}

private void UpdateTag(DataRow row, string localTag)
{
Tag newTag = this.Tags[localTag];
SaveTag(newTag, row);
}

// Properties
public string DocumentLibraryType
{
get
{
return this.documentLibraryType;
}
set
{
this.documentLibraryType = value;
}
}

[Personalizable(PersonalizationScope.Shared), FriendlyName("Enable Cache"), Description("Flag for activating the cache"), Category("Parameters"), PersistenceMode(PersistenceMode.InnerProperty), WebBrowsable(true)]
public bool IsActivatedCache
{
get
{
return this.isActivatedCache;
}
set
{
this.isActivatedCache = value;
}
}

public string ListType
{
get
{
return this.listType;
}
set
{
this.listType = value;
}
}

[Personalizable(PersonalizationScope.Shared), Description("If checked, allows to open all links in a new window Tag"), Category("Parameters"), PersistenceMode(PersistenceMode.InnerProperty), WebBrowsable(true), FriendlyName("Open links in a new window")]
public bool OpenItemsInNewWindows
{
get
{
return this.openItemsInNewWindows;
}
set
{
this.openItemsInNewWindows = value;
}
}

[Category("Parameters"), Personalizable(PersonalizationScope.Shared), FriendlyName("Search Scope"), Description("Set the search scope for Tag: only the current site or the entire site collection"), WebBrowsable(true), PersistenceMode(PersistenceMode.InnerProperty)]
public Enumerations.SearchScopes Scope
{
get
{
return this.scope;
}
set
{
this.scope = value;
}
}

[WebBrowsable(true), Description("Set the value of the separator character for Tag"), Category("Parameters"), PersistenceMode(PersistenceMode.InnerProperty), Personalizable(PersonalizationScope.Shared), FriendlyName("Separator character for Tag")]
public char Separator
{
get
{
return this.separator;
}
set
{
this.separator = value;
}
}

[PersistenceMode(PersistenceMode.InnerProperty), Category("Parameters"), Personalizable(PersonalizationScope.Shared), FriendlyName("Tag Name column to search"), WebBrowsable(true), Description("Sets the name tag on the columns to search")]
public string TagField
{
get
{
return this.tagField;
}
set
{
this.tagField = value;
}
}

[WebBrowsable(true), Personalizable(PersonalizationScope.Shared), Description("Set the URL of the page to search for Tag"), FriendlyName("Url of the page to search for Tag"), Category("Parameters"), PersistenceMode(PersistenceMode.InnerProperty)]
public string TargetUrl
{
get
{
return this.targetUrl;
}
set
{
this.targetUrl = value;
}
}

}
internal class TagLink
{
// Fields
private string itemUrl;
private Guid listID;
private string title;
private Guid webID;

// Properties
public string ItemUrl
{
get
{
return this.itemUrl;
}
set
{
this.itemUrl = value;
}
}

public Guid ListID
{
get
{
return this.listID;
}
set
{
this.listID = value;
}
}

public string Title
{
get
{
return this.title;
}
set
{
this.title = value;
}
}

public Guid WebID
{
get
{
return this.webID;
}
set
{
this.webID = value;
}
}
}


internal class Tag
{
// Fields
private List links = new List();
private string title;

// Properties
public List Links
{
get
{
return this.links;
}
set
{
this.links = value;
}
}

public string Title
{
get
{
return this.title;
}
set
{
this.title = value;
}
}
}


public class Enumerations
{
// Nested Types
public enum SearchScopes
{
SiteCollection,
Recursive,
Web
}
}
}



Happy days!!!
References: http://www.codeplex.com/

Comments

Popular posts from this blog

Zambia's first Helpdesk System on SharePoint

For my 25th birthday today 3rd March, 2009, allow me to present to you another first of its kind in Zambia. Yes we have done it again, having been Project manager, I present to you Zambia's first Helpdesk System which Masialeti and I have developed on Microsoft Office SharePoint Server 2007. The system also implements SharePoint designer workflows, Infopath forms, SharePoint document library and sends email notifications to the relevant personnel. When a user logs in a call, the user automatically receives a mail from the system, telling them that their call has been received and is being attended to, IT section will also receive a notification and the helpdesk manager will assign the call to the right IT guy who will also automatically receive a mail notification from the system. When the call is resolved, the user again automatically gets notified by the system with a mail giving them description of the problem they logged and also how it has been resolved. The user also has an

How to implement a SharePoint "Change Management Process"

Not so much from the technical point of view, SharePoint Change Management is the process of monitoring and controlling changes within a SharePoint project. By managing the implementation of change, you can: • Reduce the impact of changes to the SharePoint project • Identify new issues and risks as a result of changes raised • Ensure that changes do not affect the SharePoint project's ability to achieve its desired objectives • Control the cost of change within the SharePoint project Change Management is comprised of the following processes: Step 1: Identify Change: The first step in the change process is to identify the need for change. Any team member can suggest a change to the SharePoint project, if he or she believes it is needed to keep the SharePoint project producing deliverables to the customer's specified requirements. After identifying a need for change, the team member records relevant information on a Change Request Form (commonly called a CRF), describing the chan

Zambia's first K2 BlackPoint roll-out

Reporting to you live from Code|Influence... My colleague and I have been managing our organization's SharePoint infrastructure for some time now and we have just rolled out the first K2 BlackPoint in the country, intended mostly for SharePoint workflow developments.