Introduction
This project originally started as ‘TitleLinkField’ because I needed a way to display the Title field as a hyperlink to the document in a document library, but it ended up being more than just that so I chose a more generic name for it.
I had some experience with Custom Field Types but event then I spent too many hours (even days) on figuring this one out. It started with standard functionality such as Calculated Field and Computed Field, both having their flaws and limitations. I quickly realised that Custom Field Types might be the only way to tackle the scenario at hand.
Use
When creating a field based on this type (“Advanced Computed Field”) you need to provide two properties; FieldRefs (MSDN FieldRefs Element (List)) and DisplayPattern (MSDN: DisplayPattern Element (List)). The former requires a list of referenced fields that exist in the collection of our field while the latter contains CAML used for displaying our field. See the MSDN pages on both elements for the schema and possible values.
What better way than demonstrating by showing ?
Sample 1: Title linked to document
]]>
]]>
Sample 2: Title with ECB
-
Sample 3: Random formatting
]]>
]]>
You can learn a lot by examining the default fields in a document library or list. A tool such as Stramit SharePoint 2007 Caml Viewer is invaluable here.
Technical
A Custom Field Types derives from a parent class (MSDN: Custom Field Classes). Furthermore you have to define the ParentType field declaratively in the FieldTypes XML definition. It is advised (maybe even required) for them to be the same type.
Choose the ‘parent class’ that most closely matches your requirements. If you need a ‘text field with regular expression validation’ then go for SPFieldText because that has a lot of textbox relation functionality (especially on the New, Edit and Display Forms).
The ‘ParentType’ field seems to be the key for CAML related functionality (such as the AllItems View). In my case setting it to “Text” meant that my field didn’t retrieve the values of the referenced fields so it needed to be “Computed”.
The main issues with the standard Computed Field is that it is invisible from any view; Site Columns, Field in a Content Type, etc. and can only be created declaratively via XML/CAML or through code. Other than these issues the Computed Field did exactly what was needed; render columns in a way that I wanted via the RenderPattern. It turns out that the visibility of a Custom Field Type can be controlled in the declarative XML via the ”ShowOn…” fields.
For storing and retrieving the DisplayPattern and FieldRefs properties my custom field type exposes two methods that make calls to internal SharePoint methods:
public void SetInnerXmlForNode(string nodeName, string innerXml)
{
Type fldType = this.GetType();
XmlDocument doc = new XmlDocument();
doc.LoadXml(String.Format("<{0}>{1}{0}>", nodeName, innerXml));
MethodInfo miSetXml = fldType.GetMethod("SetInnerXmlForNode", BindingFlags.Instance | BindingFlags.NonPublic);
miSetXml.Invoke(this, new object[] { nodeName, doc.DocumentElement.InnerXml });
}
public string GetInnerXmlForNode(string nodeName)
{
string result = null;
Type fldType = this.GetType();
MethodInfo miGetXml = fldType.GetMethod("GetNodeFromXmlDom", BindingFlags.Instance | BindingFlags.NonPublic);
XmlNode resultNode = miGetXml.Invoke(this, new object[] { nodeName }) as XmlNode;
if (resultNode != null)
{
StringBuilder sb = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlWriter writer = XmlTextWriter.Create(sb, settings))
{
resultNode.WriteContentTo(writer);
}
result = sb.ToString();
}
return result;
}
Download and installation
If you’re interested in reusing or modifying the code feel free to do so. If you just want this installed and available on your SharePoint farm then go for the WSP and deploy via STSADM.
STSADM -o addsolution -filename VNTG.CustomFieldTypes.AdvancedComputedField.wsp
STSADM -o deploysolution -name VNTG.CustomFieldTypes.AdvancedComputedField.wsp -allowgacdeployment -immediate -allcontenturls
Word of caution
There isn’t a lot of validation on the input of the XML properties. It has to be valid XML but that’s about it. Please follow the schema for FieldRefs and DisplayPattern to make sure you don’t break other functionality. It cannot ‘bring down the farm’ or anything, but it could definitely mess up the rendering of the View.
Have fun with it !