Advanced Computed Field


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

<FieldRefs>
     <FieldRef Name="ServerUrl" />
     <FieldRef Name="Title" />
</FieldRefs>

<DisplayPattern>
     <HTML><![CDATA[<a href="]]></HTML>
     <Field Name="ServerUrl" />
     <HTML><![CDATA[" title="]]></HTML>
     <Field Name="ServerUrl" />
     <HTML><![CDATA[">]]></HTML>
     <Field Name="Title" />
     <HTML><![CDATA[</a>]]></HTML>
</DisplayPattern>

Sample 2: Title with ECB

<FieldRefs>
     <FieldRef Name="Title" />
     <FieldRef Name="_EditMenuTableStart" />
     <FieldRef Name="_EditMenuTableEnd" />
</FieldRefs>

<DisplayPattern>
     <FieldSwitch>
         <Expr>
              <GetVar Name="FreeForm" />
          </Expr>
          <Case Value="TRUE">
               <HTML>-</HTML>
          </Case>
          <Default>
               <Field Name="_EditMenuTableStart" />
               <SetVar Name="ShowAccessibleIcon" Value="1" />
               <Field Name="Title" />
               <SetVar Name="ShowAccessibleIcon" Value="0" />
               <Field Name="_EditMenuTableEnd" />
          </Default>
     </FieldSwitch>
</DisplayPattern>

Sample 3: Random formatting

<FieldRefs>
     <FieldRef Name="MyChoiceField" />
</FieldRefs>

<DisplayPattern>
     <HTML><![CDATA[<span style="background-color: red;">]]></HTML>
     <Field Name="MyChoiceField" />
     <HTML><![CDATA[</span><input type="button" value="Click me" />]]></HTML>
</DisplayPattern>

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 !

 


Links to this post

Comments

Wednesday, 1 Apr 2009 10:55 by deyaert
Seems handy!

Monday, 6 Apr 2009 05:55 by frevd
well done, cheers

Thursday, 28 May 2009 05:23 by Mangesh
I dont see the wsp after deployment anywhere. It seems to have been deployed but it doesnt get listed in Site or site collection features. I cant activate it. How do I activate and use it on the Doc Lib?

Thursday, 28 May 2009 12:34 by Ron Verhoeven
Hello Steven, I also tried this webpart. It's working fine. I just have one question. We want a button to 'edit in microsoft office or excel etc.' on a menu item. It's currenty located in the dropdownmenu of the name field in a document library. Can we use this tool to achieve this? Thanks in advance!

Friday, 29 May 2009 09:14 by Steven Van de Craen
Mangesh, did you try an iisreset ?

Friday, 29 May 2009 11:48 by Steven Van de Craen
Ron, this should get you started: http://www.moss2007.be/blogs/vandest/Documents/ACF_Sample1.txt

Wednesday, 3 Jun 2009 03:18 by Mangesh
Yes, I tried IIS reset. I can see the folder VNTG.AdvancedComputedField being created under CONTROLTEMPLATES folder in 12 hive. Also there is a user control under it. But it wont show up in the UI to activate the feature. I tried using stsadm to activate, but then too it isnt available to be added in the Doc Lib view. May be something wrong, I checked the timer service and its running.

Thursday, 4 Jun 2009 07:55 by Steven Van de Craen
Mangesh, verify that the DLL is present in the Global Assembly Cache. If it's not then perhaps you forgot the -allowgacdeployment parameter ?

Tuesday, 9 Jun 2009 07:50 by Mangesh
Not sure where my comment went. I was able to get it working. Was little confused with the naming. I want the title to be a link to open the document and have the menu associated with it as well. Exactly like the out-of-box behavior of the Name (linked to document with edit menu) column. This control gives me either of these depending on the FieldRef and DisplayPattern. I tried adding the HTML of "Title linked to document" FieldRef to HTML of the "Title with ECB" but that results in error. Any pointers? The MSDN documentation is not too helpful.

Thursday, 18 Jun 2009 04:18 by Steven Van de Craen
Mangesh, I think you're talking about 'Sample 2' in my blog post ?

Wednesday, 12 Aug 2009 03:31 by Mimi
Hello, i used your part to ecb menu,it helped me but i have a problem : when i export a site with the ecb webpart i dont have problems but when i tried to import it it doesn't work did you tried to export it and reimported? Regards Emilie

Wednesday, 19 Aug 2009 11:16 by Steven Van de Craen
Emilie, STSADM export/import and backup/restore work fine. Saving the list as template works without content but I do get an error when I save WITH content. That seems to be a restriction indeed...

Friday, 6 Nov 2009 11:37 by Vasssek
Hello, I wonder if you could help me with one problem in association to your computed field... What I want to do is to put some different output HTML rendering based on the value of another field. 1. I've created text field named e.g. TestField which could have 3 options of text: Open, Working, Close. 2. I need to display different colors of text in render method of computed field based on TestField text value. I've tried something like this but it doesn't work. It still show formatting from section in allitems.aspx view. In FieldRefs section I have: ---------------------------------------- In DisplayPattern I have: <span style="color:Green"><b> </b></span> <span style="color:Blue"><b> </b></span> <span style="color:Red"><b> </b></span> <span style="color:Brown"><b> </b></span> Thank you very much yor help... Best regards Svana Vaclav

Saturday, 7 Nov 2009 11:40 by Steven Van de Craen
Svana, i have posted a small sample here: http://www.moss2007.be/blogs/vandest/archive/2009/11/07/conditional-formatting-using-the-advanced-computed-field.aspx Hope this helps !

Monday, 14 Dec 2009 05:25 by Allan
Excellent job on this, it has and will help a ton. I have added an Advanced Computed column with the following as values: ======================================================== ======================================================== <img alt="Amber" src="/_layouts/IMAGES/ewr211m.gif" /> <img alt="Green" src="/_layouts/IMAGES/ewr209m.gif" /> <span>No Value</span> ======================================================== It renders properly but if I try to Edit/View the properties of the document item I get a generic SP error. Any ideas?

Monday, 14 Dec 2009 10:41 by Steven Van de Craen
Allan, did you wrap it with an 'HTML' node ? If you remove the ACF does Edit/View work again ?

Tuesday, 16 Feb 2010 09:06 by Mar Van Eyken
Hello Steven I tried your advanced computed Field on Sharepoint 2010 beta. It works for the most part fine, except one one dtail. When you add in a view of a list the advanced computed field, there is no link displayed here. An empty column is displayed. When you select an item and ask a detailed view of it the correct links are displayed and the functionality is ok. Have you tried your advanced computed field on Sharepoint 2010 and have you a solution for this behaviour? Thanks in advance.

Thursday, 18 Feb 2010 08:44 by Steven Van de Craen
Haven't tried it in SP2010 yet, but the ListViewWebPart is improved into an Xsl ListViewWebPart. Also all Custom Fields should be declared using XSL from then on. Could be the issue. If so it would need to be modified.

Friday, 17 Sep 2010 02:05 by frevd
More info on XSL rendering in 2010: http://social.technet.microsoft.com/Forums/en/sharepoint2010customization/thread/ef0d1d22-47ff-416c-becd-13d48de80e4d RenderPatterns are no longer defined by fields but using by the xsl-Files specified in the list schema and used by the new XsltListViewWebPart. That means there can only be a static rendering for the field type, no longer for the field instance itself. The only possibility seems to use the legacy LVWP, or to have switches in the xsl. Would be rather difficult to implement on-the-fly configuration of the layouts-xsl-file, especially farmwide ;].

Friday, 17 Sep 2010 02:14 by frevd
WAAAIT, IT DOES WORK WITH 2010! You can force the new XsltLVWP to use CAML-Rendering for a custom field by adding the following to the fldtypes_*.xml: "TRUE"

Friday, 17 Sep 2010 02:15 by frevd
ah, you comments section is not very handy, here the code to add (make it xml): [Field Name="CAMLRendering"]TRUE[/Field]

Monday, 4 Oct 2010 08:34 by Ajeet
Hi Steven, I have tried the Advanced computed field and it is working fine. Few issues that I am facing is 1) When trying to delete the Field it is throwing an error "One or mopre field is not installed properly" 2) It works well if we upload a document but causes an error if we create a new document. Can we restric the field appearing if we create a new document through content type. Will this prevent the error 2 from appearing? Any help for error 1.

Tuesday, 5 Oct 2010 10:50 by Steven Van de Craen
Hi Ajeet, Out of the box the ACF doesn't throw that error. Maybe the renderpattern or fieldrefs you have specified are throwing it off ? Try with a default ACF. Each SPField has several ShowOnEdit, ShowOnNew properties that you can set through code. You could write a small application that sets those properties on your fields to control that behaviour.

Tuesday, 10 May 2011 10:00 by HiAll
Hi all, It's a really great job. I use it some time, but a have a question about the advanced computing field: Does-it work with sharepoint 2010, because my boss ask me to know if we could have problems if we upgrade 2007 to 2010. Thank you for your anwser.

Thursday, 24 May 2012 10:50 by Joachim Friedrich
Hi, I have the problem, that I can't use the datasheet view anymore. Everytime when I change an item I get an error message: "Another user has changed the structure of this list...". Any idea? Thanks Joachim

Friday, 25 May 2012 06:55 by Steven Van de Craen
Hi Joachim, does removing the ACF field from the list resolve the issue ?

Friday, 25 May 2012 12:29 by Joachim
yes, it resolve the issue.

Friday, 25 May 2012 03:07 by Joachim
Hi, after I set the properties "ReadOnly" and "ShowInViewForms" to true (with Sharepoint Manager 2007) I can edit items in the datasheet view. Unfortunately the field is then not visible in the list settings anymore and I can't change it in the browser. But for the moment it is an workaround. Do you think, there will be a solution in the future? Thanks again

Tuesday, 29 May 2012 08:38 by Steven Van de Craen
Joachim, ReadOnly has that unfortunate side effect. Is the ACF field included in the DataSheet view ? If so, try to create a DataSheet View without the ACF field and see if that makes it editable.

Thursday, 31 May 2012 08:10 by Joachim
I tested this possibility, before I wrote any comment. Same problem.

Thursday, 25 Oct 2012 10:50 by Garrett
Clever add-on - thanks for sharing. Do you know how I can retrieve the computed value programmatically? CAML queries and all of the SPField.GetValue functions merely return one of the referenced fields' value. Thanks.

CAPTCHA Image Validation