Friday, 3 October 2008

Traffic Lights


While working with clients I am often asked if they can have traffic light indicators on list items. This would be great for rag status on project based WSS sites for example. Unfortunately this is not a straightforward task, indeed 'Key Performance Indicators' are only available with MOSS Enterprise and in anycase these are overkill for many cases.

I had considered creating custom webparts to solve this but a search on the web came up with some good information. (Credit to Christopher at PathtoSharePoint)

The list or library must contain a required choice field named priority, the choices should be (1)High, (2)Normal, (3)Low.

Now create a calculated field to store the indicator. Depending on what type of indicator you would like, choose which of the following calculations to use in this field:

- Traffic light (actually a big bullet!):
=”< DIV style=’font-weight:bold; font-size:24px; color:”&CHOOSE(RIGHT(LEFT(Priority,2),1),”red”,”orange”,”green”)&”;’> •< /DIV> ”

- Indicator (reusing the default SharePoint KPI images):
=”< DIV> < IMG src=’/_layouts/images/KPIDefault-”&(3-RIGHT(LEFT(Priority,2),1))&”.gif’ /> < /DIV> ”

- Font color:
=”< DIV style=’font-weight:bold; font-size:12px; color:”&CHOOSE(RIGHT(LEFT(Priority,2),1),”red”,”orange”,”green”)&”;’> ”&Priority&”< /DIV> ”

- Background color:
=”< DIV style=’font-size:12px; background-color:”&CHOOSE(RIGHT(LEFT(Priority,2),1),”red”,”orange”,”green”)&”;’> ”&Priority&”< /DIV> ”

Now add the list or library as a web part on the page where you would like to see it and the indicator. This will look very odd and the indicator will appear as html text.

Now add a CEWP (Content Editor Web Part) to the page. Set the CEWP to hidden as you do not want to see it on the page. Using the source editor of the CEWP add the following javascript:

< script type="text/javascript">
var theTDs = document.getElementsByTagName("TD");
var i=0;
var TDContent = " ";
while (i < theTDs.length)
{
try
{
TDContent = theTDs[i].innerText || theTDs[i].textContent;
if ((TDContent.indexOf("< DIV") == 0) && (TDContent.indexOf("< /DIV> ") > = 0)) {
theTDs[i].innerHTML = TDContent;
}
}
catch(err){}
i=i+1;
}
< /script>

If everything is correct your list will appear with indicators like the above example.

1 comment:

trojanh0rse said...

Great post Phil, thanks for the info! I wanted to be able to change the Traffic Lights based on a field called 'Health' that contains a word instead of a numeric value. This can be achieved using a nested IF statement instead of CHOOSE. Here is my code:

="<DIV style='font-weight:bold; font-size:24px; color:"&IF(Health="Green","green",IF(Health="Yellow","yellow", "red"))&";'>•</DIV>"