Custom field type derived from SPFieldCalculated
I am trying to create a custom field type that will display values based on another field in the same list. (basically displaying some images based on the value of the source column)
Since this column outputs data entirely based on another column, I need to make sure that the column values are not stored in the database.
So, I think I need to create a custom field type that comes from the SPFieldCalculated class.
But, when I try to do this, I get the error "Type 'Microsoft.SharePoint.SPFieldCalculated' has no constructors defined"
How do I create a custom tpye field derived from SPFieldCalculated? If this is not possible, can someone at least tell me how I can satisfy my requirements?
a source to share
In the fieltype xml file, you can add LookupColumn to the template CAML. in your question you can use field type text and in DisplayPattern write something like this.
<RenderPattern Name="DisplayPattern">
<HTML><![CDATA[<img src="]]></HTML>
<LookupColumn Name="FileLeafRef" HTMLEncode="TRUE" />
<HTML><![CDATA["/>]]></HTML>
</RenderPattern>
a source to share
Unfortunately, it is not possible to inherit from the SPCalculatedField class, which is why you get this error: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfieldcalculated.aspx
Windows SharePoint Services 3.0 does not support inheriting from this class.
To display an image based on a different column value in 2007, you'll have to do some nasty CAML work in fldtypes ... xml (as mentioned by @David A). Here's a good place to start: http://msdn.microsoft.com/en-us/library/aa544291.aspx
I also innocently mention that there might be commercial alternatives with this functionality, one of which I may have helped create and may have mentioned here: Sharepoint Web Part for Conditional Formatting?
a source to share
Is there anything from SPFieldCalculated that SPField doesn't have? I would solve the problem by creating a custom field based on SPField, then I would either:
1 Register an event sink in the field editor and use it to set the field value.
or
2 If you want to view the value in edit / new forms, compute the value in the field control. This requires your field to be ordered below the fields you are basing your value on, otherwise you will end up calculating your value based on the old data.
I would also recommend that you store the computed value instead, recalculating it. This is the only sane way if you want to render data in a list view, since you are writing the render template in CAML and not C #.
a source to share
You can get more mileage out of creating a custom browsing style for the list (s).
This will allow you to completely change the way the column is displayed html-wise without adding a calculated field.
Alternativley you might also think you can do some very funny things with a custom field definition in schemaxml only. As an example, I am including an xml XML schema for one of the "name" fields in a regular publishing library.
<Field ID="{9d30f126-ba48-446b-b8f9-83745f322ebe}" ReadOnly="TRUE" Type="Computed" Name="LinkFilenameNoMenu" DisplayName="Name" DisplayNameSrcField="FileLeafRef" Filterable="FALSE" AuthoringInfo="(linked to document)" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="LinkFilenameNoMenu" FromBaseType="TRUE"><FieldRefs><FieldRef Name="FileLeafRef" /><FieldRef Name="FSObjType" /><FieldRef Name="Created_x0020_Date" /><FieldRef Name="FileRef" /><FieldRef Name="File_x0020_Type" /><FieldRef Name="ContentTypeId" /><FieldRef Name="PermMask" /><FieldRef Name="CheckoutUser" /><FieldRef Name="IsCheckedoutToLocal" /></FieldRefs><DisplayPattern><IfEqual><Expr1><LookupColumn Name="FSObjType" /></Expr1><Expr2>1</Expr2><Then><FieldSwitch><Expr><GetVar Name="RecursiveView" /></Expr><Case Value="1"><LookupColumn Name="FileLeafRef" HTMLEncode="TRUE" /></Case><Default><SetVar Name="UnencodedFilterLink"><SetVar Name="RootFolder"><HTML>/</HTML><LookupColumn Name="FileRef" /></SetVar><SetVar Name="FolderCTID"><FieldSwitch><Expr><ListProperty Select="EnableContentTypes" /></Expr><Case Value="1"><Column Name="ContentTypeId" /></Case></FieldSwitch></SetVar><FilterLink Default="" Paged="FALSE" /></SetVar><HTML><![CDATA[<A onfocus="OnLink(this)" HREF="]]></HTML><GetVar Name="UnencodedFilterLink" HTMLEncode="TRUE" /><HTML><![CDATA[" onclick="javascript:EnterFolder(']]></HTML><ScriptQuote NotAddingQuote="TRUE"><GetVar Name="UnencodedFilterLink" /></ScriptQuote><HTML><![CDATA[');return false;">]]></HTML><LookupColumn Name="FileLeafRef" HTMLEncode="TRUE" /><IfEqual><Expr1><GetVar Name="ShowAccessibleIcon" /></Expr1><Expr2>1</Expr2><Then><HTML><![CDATA[<img src="/_layouts/images/blank.gif" class="ms-hidden" border=0 width=1 height=1 alt="]]></HTML><HTML>Use SHIFT+ENTER to open the menu (new window).</HTML><HTML><![CDATA[">]]></HTML></Then></IfEqual><HTML><![CDATA[</A>]]></HTML></Default></FieldSwitch></Then><Else><HTML><![CDATA[<A onfocus="OnLink(this)" HREF="]]></HTML><Field Name="ServerUrl" URLEncodeAsURL="TRUE" /><HTML><![CDATA[" onclick="return DispEx(this,event,']]></HTML><ScriptQuote NotAddingQuote="TRUE"><ServerProperty Select="HtmlTransform" /></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><ServerProperty Select="HtmlTrAcceptType"><Column Name="File_x0020_Type" /></ServerProperty></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><ServerProperty Select="HtmlTrHandleUrl"><Column Name="File_x0020_Type" /></ServerProperty></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><ServerProperty Select="HtmlTrProgId"><Column Name="File_x0020_Type" /></ServerProperty></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><ListProperty Select="DefaultItemOpen" /></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><MapToControl><Column Name="HTML_x0020_File_x0020_Type" /><HTML>|</HTML><Column Name="File_x0020_Type" /></MapToControl></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><Column Name="HTML_x0020_File_x0020_Type" /></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><ServerProperty Select="GetServerFileRedirect"><Field Name="ServerUrl" /><HTML>|</HTML><Column Name="HTML_x0020_File_x0020_Type" /></ServerProperty></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><Column Name="CheckoutUser" /></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><UserID AllowAnonymous="TRUE" /></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><ListProperty Select="ForceCheckout" /></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><Field Name="IsCheckedoutToLocal" /></ScriptQuote><HTML><![CDATA[',']]></HTML><ScriptQuote NotAddingQuote="TRUE"><Field Name="PermMask" /></ScriptQuote><HTML><![CDATA[')">]]></HTML><UrlBaseName HTMLEncode="TRUE"><LookupColumn Name="FileLeafRef" /></UrlBaseName><IfEqual><Expr1><GetVar Name="ShowAccessibleIcon" /></Expr1><Expr2>1</Expr2><Then><HTML><![CDATA[<img src="/_layouts/images/blank.gif" class="ms-hidden" border=0 width=1 height=1 alt="]]></HTML><HTML>Use SHIFT+ENTER to open the menu (new window).</HTML><HTML><![CDATA[">]]></HTML></Then></IfEqual><HTML><![CDATA[</A>]]></HTML><IfNew Name="Created_x0020_Date"><HTML><![CDATA[<IMG SRC="/_layouts/1033/images/new.gif" alt="]]></HTML><HTML>New</HTML><HTML><![CDATA[">]]></HTML></IfNew></Else></IfEqual></DisplayPattern></Field>
Unpleasant but powerful.
a source to share
Well I'm afraid I haven't tried creating custom fields before. However, I have a suggestion that might work. The field can be just an image field. You can use an on-list event receiver that calculates the required field whenever the target field changes. It might be long, but if you don't get a custom field way of working it might be.
a source to share
Assuming this column is really only for display, there are two ways I can think of that might help:
- Use a calculated column to generate HTML and then JavaScript to include it: http://pathtosharepoint.wordpress.com/2008/09/01/apply-color-coding-to-your-sharepoint-lists/
- Perhaps you can do this using SharePoint Designer and the DataForm web part: http://masteringsharepoint.com/blogs/beagle/archive/2008/08/13/DFWP1.aspx
a source to share