2008-01-29

Enabling HTML and/or Images in a SharePoint List using a calculated field

A client asked me to highlight a row based on the value of a status field... If figured easy, just use a dataview wp, but no, they want to be able to maintain it without using SPDesigner. I always like to give clients what they want, and I wasn't about to tell them to start changing the dataview in notepad... The "proper" way to enable HTML would probably be to create a bew custom field type, but since we need a formula this is not a trivial task; there is however a file which controls the way fields are rendered (see previous post).


We need to modify this to stop sharepoint encoding the HTML. This method has zero performance impact and only takes a few minutes.


To do this the first step is to open \Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\XML\FLDTYPES.XML

There are a couple of ways to change FLDTYPES.XML that will stop it encoding HTML; the one I've chosen is to look for a hidden tag in the value returned by a calculated field.

You can change any field type, but I need to change the calculated field type as I need to use conditional formating based on a formula.

  1. Locate <FieldName="TypeName">Calculated</Field> in FLDTYPES.XML.

  2. Move down to the <RenderPattern Name="DisplayPattern"> node.

  3. Find the <Default> node.

  4. Add your logic between the <Default> and </Default> nodes.


You can use various functions and properties to enable your logic, please see http://msdn2.microsoft.com/en-us/library/ms439798.aspx for a list. In my case I just needed an If Else as I didn't want to impact on existing calculated fields, so I opted for the <IfSubString> function, as follows:


<IfSubString>
<Expr1><![CDATA[<.RP>]]></Expr1>
<Expr2><Column/></Expr2>
<Then><HTML><Column/></HTML></Then>
<Else><Column HTMLEncode="TRUE" AutoHyperLink="TRUE" AutoNewLine="TRUE"/></Else>
</IfSubString>



The above basically means if the data in the column contains <.RP> then just render the contents. Otherwise do the MOSS default.


You could of course complicate the above and use a switch with <GetFileExtension> like:


<Switch>
<Expr><GetFileExtension><Column/></GetFileExtension></Expr>
<Case Value="RP>">
<HTML><Column/></HTML>
</Case>
<Default>
<Column HTMLEncode="TRUE" AutoHyperLink="TRUE" AutoNewLine="TRUE"/>
</Default>
</Switch>



The above has the benfit of allowing different logic for different scenarios.

The final step is to create a calculated field that returns <.RP>. Any record with this tag will enable the logic, and since <.RP> is an unknown tag browsers won't render it.

Using <GetFileExtension> you need to make sure your <.RP> is at the end.

The calculated field formula will look something like:


=IF([Active],"<.RP><b style='color:0000ff'>","<.RP><b style='color:ff0000'>") & [Title] &" "& [Column1] &" "& [Column2] &"</b>"


Look here for formulas http://msdn2.microsoft.com/en-us/library/bb862071.aspx


Now just create a view with just your calculated field and you have a list highlighting active records (with limited sorting)... but you could always just create a calculated field for each.


OK now you've probably realized your filtering has HTML... the fix for that is to disable filtering if the column has your tag... create a variable (<SetVar Scope="Request">) in your logic and set it, then check if it's been set outside <RenderPattern> set <Field Name="Filterable">FALSE</Field>. I haven't figured out how to render the heading as it displays without using Javascript... I could write this up one days. Notes: CAML is case sensative, and you'll need to restart IIS for any change to FLDTYPES.XML.

10 comments :

  1. Hi - fantastic tips here. One thing, how do you use SetVar in fieldtypes.xml and how would I then set it etc?

    Hope you can help.

    Cheers, Steve

    ReplyDelete
  2. There seems to be a fundamental problem here when using XSLT dataviews in Sharepoint Designer. SP seems to be escaping the contents of the calculated field no matter what you do e.g. disable-output-escaping etc.

    Therefore you cannot render the calculated field properly in the browser.

    Please please can you provide help here?

    Thanks

    Simon

    ReplyDelete
  3. Hi,

    I need to display column1 only if the values of column2 is equal to a particular value , otherwise column 1 should not even be visible.

    Can I acheive this using Calculated columns? How do i do it?
    Any help is greatly appreciated....

    ReplyDelete
  4. I've made the changes in the ftdtypes.xml exactly as you and other guys said but I did not get the result as I expected. Is there any step that I may forgot? Do I have to restart something?

    ReplyDelete
  5. Yes you'll need to restart the application pool, or just do an IISRESET

    ReplyDelete
  6. Hi
    Great example, works in SP2007, but somehow I can't get it to work in SP2010 - any ideas why?

    ReplyDelete
  7. Hi,

    That was helpful.

    Thanks for Sharing. As asked by tsw_mik it works in SP2007, but somehow I can't get it to work in SP2010 - any ideas why?

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. Hiiii...
    Hey... I follow this steps but when the field is calculated on the star of value appere <.RP> if I erase this tag don't do the HTMLEncode...
    can you help me pls?

    ReplyDelete
  10. Be careful with this solution. Editing the FieldTypes.xml file is not supported.

    ReplyDelete