Using Calculated Fields in CAML to Display Conditional Images

Came across a nice gem in the newsgroups that I thought I would share here. Someone had a choice field with three values: failed; pass; re-run; and wanted to display a red image for items in the list matching the failed value, green for pass, and yellow for re-run (oh yeah, can you see where this is going).

I pointed them immediately to Ian Morrish’s article here on conditional formatting using a DataView Web Part which works nicely for this. However Colin Gardner came up with a nice solution that used the RenderPattern tag in CAML for a list to do the job. Here’s his solution:

1. Edit the FieldTypes.xml file (make backups for safety) and look for the row definition for the calculated field type (search for <Field Name="TypeName" DisplayName="TypeName">Calculated</Field>).

2. Modify the deafult render pattern in the <FieldSwitch> statement so that it handles the values returned by a calculated file in such a way that will return you an image/icon/traffic light.  You will see that the <FieldSwitch> statement handles Boolean, Number, Currency and DateTime field types but anything else falls through and is processed by the code in the <Default> tag which is: <Column HTMLEncode="TRUE" AutoHyperLink="TRUE" AutoNewLine="TRUE"/>

You need to replace this default rendering with you're own custom logic.  In my implementation I replaced it with another complete switch statement like the one below:

<Switch>
<Expr>
<GetFileExtension><Column/></GetFileExtension>
</Expr>
<Case Value="giF">
<HTML><![CDATA[<IMG SRC="]]></HTML><Column HTMLEncode="TRUE"/><HTML>"</HTML>
</Case>
<Default>
<Column HTMLEncode="TRUE" AutoHyperLink="TRUE"
AutoNewLine="TRUE"/>
</Default>
</Switch>

In this example the the Switch <Expr> calles the GetFileExtension function which processes the value in the calculated field and tries to extract a file extension.  You can then use a Case statement to render the value returned by the calculated field in a way that makes sense. In the example above - if the GetFileExtension returns the string "giF" then I process the value as an image and render it as an HTML <IMG> tag.

Note that I chose to take advantage of the fact that the comparison is case sensitive but the source url for the image is not.  This means that if my calculated field returns a string that ends with ".gif" rather than ".giF" then it will slip through the case statement and be rendered as before i.e. not as an image.

Of course you can modify the above to handle jpeg or any other graphics format that WSS can render.

3.  Save the modified FieldTypes.xml file.

4.  Create a Caluclated field in your list in the standard way with a formula that checks the value of your Choice field and returns a URL (relative will work) to the appropriate graphic file making sure that it is a format that will be handled by the newly modified render pattern.  Something like:

=IF(Choice="A","/imagepath/red.giF", IF(Choice="B", "/imagepath/yellow.giF", "/imagepath/green.giF"))

Now you can use the calculated field wherever you like.

This is pretty elegant and nice to do since a) you don’t need to create a DVWP and therefore unghost a page b) it uses CAML which is always cool and c) you can set up a list with this in it so anyone creating a new list of this type will get the results. RenderPattern is a pretty powerful little thing because basically you can do anything in it, including conditional logic.

NUnit test results stored in a SharePoint list anyone? Yeah, who needs Team Server Foundation when you do stuff like this.

Published Wednesday, April 26, 2006 6:42 PM by Bil Simser
Filed under:

Comments

# re: Using Calculated Fields in CAML to Display Conditional Images

Thursday, April 27, 2006 1:05 PM by Mark Kruger
Very creative solution. However, I disagree with your statement:

This is pretty elegant and nice to do since a) you don’t need to create a DVWP and therefore unghost a page

If you have a sandbox document library and create a sandbox web part page, you can create your dataviews and only unghost your sandbox page. Once you've finished your dataview, you can export the web part to any page you want and simply delete your development page. You can then store your exported dataview web part in any site you want for anyone to pick up and modify without having to make modifications to an xml file sitting on the web server(s) depending on your farm setup.

Just my $.02 but I love hearing new and creative methods. Nice post.

# re: Using Calculated Fields in CAML to Display Conditional Images

Thursday, April 27, 2006 1:17 PM by Bil Simser
@Mark: I agree that you don't need to unghost pages for this. The main advantage to this approach is that you are not tied to the GUID for the list that you have a data view on which is probably a better reason to do it this way.

# re: Using Calculated Fields in CAML to Display Conditional Images

Monday, May 08, 2006 12:29 PM by Jeff
Anybody get this to work? I could use another example with more code above and below to make sure I get the placement correct.

# re: Using Calculated Fields in CAML to Display Conditional Images

Friday, May 19, 2006 2:55 AM by Alistair
Thanks for the tip Bill, works great!

One gotcha is that the fldtypes.xml seems to get "compiled" into a site - so you cannot apply this technique to an existing site.

# Using Calculated Fields in CAML to Display Conditional Images

Wednesday, June 28, 2006 1:56 PM by SharePointKicks.com
Trackback from SharePointKicks.com