Question

I'm trying to add conditional formatting to a custom list based on whether or not a field contains a number in a certain range (i.e., if the field contains a number less than 15, i'd like the background to be red. It the field contains a number between 15 and 30, I'd like the background to be yellow). After much searching, I think I have the right code for the less than 15 scenario, but no formatting is being applied to the list when I save it. Does anyone have any idea what I am doing wrong? Here's the code I am using:

<Xsl>
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"     xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-  result-prefixes="xsl msxsl ddwrt"  xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"  xmlns:asp="http://schemas.microsoft.com/ASPNET/20"  xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas- microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls"  xmlns:ddwrt2="urn:frontpage:internal" xmlns:o="urn:schemas-microsoft- com:office:office"> 
<xsl:include href="/_layouts/xsl/main.xsl"/> 
<xsl:include href="/_layouts/xsl/internal.xsl"/> 
<xsl:param name="AllRows" select="/dsQueryResponse/Rows/Row[$EntityName = '' or (position() &gt;= $FirstRow and position() &lt;= $LastRow)]"/>
<xsl:param name="dvt_apos">&apos;</xsl:param>
<xsl:template name="FieldRef_body.Days_x0020_On_x0020_Hand" ddwrt:dvt_mode="body" match="FieldRef[@Name='Days_x0020_On_x0020_Hand']" mode="body" ddwrt:ghost="" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:param name="thisNode" select="."/>
<span>
    \
<xsl:attribute name="style">
        <xsl:if test="number($thisNode/@Days_x0020_On_x0020_Hand) &lt; 15" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" ddwrt:cf_explicit="1">color: #FFFFFF; vertical-align: middle; text-align: center; background-color: #CC0000;</xsl:if>
    </xsl:attribute>
    </span></xsl:template>
<xsl:template name="FieldRef_Attachments_header.Attachments" ddwrt:dvt_mode="header" match="FieldRef[(@Type='Attachments') and @Name='Attachments']" mode="header" ddwrt:ghost="" xmlns:ddwrt2="urn:frontpage:internal">
<th class="ms-vh-icon" nowrap="nowrap" scope="col" onmouseover="OnChildColumn(this)">
  <xsl:call-template name="dvt_headerfield">
    <xsl:with-param name="fieldname">Attachments</xsl:with-param>
    <xsl:with-param name="fieldtitle">&lt;img border=&apos;0&apos; alt=&apos;<xsl:value-of select="'Attachments'"/>&apos; src=&apos;/_layouts/images/attachhd.gif&apos;</xsl:with-param>
    <xsl:with-param name="displayname">Attachments</xsl:with-param>
    <xsl:with-param name="fieldtype">Attachments</xsl:with-param>
  </xsl:call-template>
</th>

Was it helpful?

Solution

Note:

in June 2017, Microsoft disabled the use of JavaScript in a Calculated Column

That means given answers may not apply for newer SharePoint versions

For long explanation and work arounds see:
June 13th 2017 Microsoft blocked handling HTML markup in SharePoint calculated fields - how to get the same functionality back


## Calculated Column (**SP2010** / 2013 / Online)

You can get the same effect without any complex XSLT by creating a Calculated Column and setting the output type to Date (or anything but Single Line Text) which will execute the HTML, but only in a View, this does NOT work on Forms

="<DIV style='background:"
&IF([Days On Hand]<15,"lightcoral",IF([Days On Hand]<30,"yellow","white"))
&";color:black;font-weight:bold;text-align:center'>"
&[Days On Hand]
&"</DIV>"

Client Side Rendering (CSR - SP2013/Online)

The modern 2013, Online solution solution (which also works in Forms) would be to use Client Side Rendering (CSR) JavaScript

You do not need an extra Calculated Column then to change the look, you override (same as with XSLT) how the field is rendered by SharePoint

See iCSR which makes CSR development a bit easier.

With iCSR loaded in a View or Form, all you need in the CSR file is:

iCSR.Me({
  file:'~sitecollection/Style Library/daysonhand.js',
  Fields:{
    Days_x0020_On_x0020_Hand:{
      View:function(ctx){
        var value=ctx.CurrentItem[this.Name];
        var style="text-align:center;color:black;font-weight:bold";
        var color='white';
        if(value<15){
          color='lightcoral';
        } else if(value<30){
          color='yellow'
        }
        return String.format("<DIV style='background:{0};{1}'>{2}</DIV>",color,style,value);
      }
    }
  }
});

Without the iCSR library you need some 10 more lines of standard SharePoint CSR boilerplate code.

Days on Hand is a calculation based on a Date?

I presume DaysOnHand is a Calculated Column based on a SubmitDate Date field?

The real power of iCSR then is:

iCSR.Me({
  file:'~sitecollection/Style Library/daysonhand.js',
  Fields:{
    SubmitDate:iCSR.DueDate({
        ranges: [      15   ,    30        ],
        colors: ['red' , 'yellow' , 'white']
    })
  }
});

iCSR does the DaysOnHand (Today calculation) for you.. so you do not need that Column
(except when you use it for something more (eg. workflow) then just display in SharePoint)

OTHER TIPS

You want <xsl:choose>:

<xsl:attribute name="style">
    <xsl:choose>
        <xsl:when test="number($thisNode/@Days_x0020_On_x0020_Hand) &lt; 15">
            color: yellow;
        </xsl:when>
        <xsl:when test="number($thisNode/@Days_x0020_On_x0020_Hand) &lt; 30">
            color: red;
        </xsl:when>
        <xsl:otherwise>
            color: blue;
        </xsl:otherwise>
    </xsl:choose>
</xsl:attribute>

Or use template rules:

<xsl:attribute name="style">
  <xsl:apply-templates select="@Days" mode="style"/>
</xsl:attribute>

<xsl:template match="@Days[. &lt; 30]" priority="3">color: red;</xsl:template>
<xsl:template match="@Days[. &lt; 15]" priority="2">color: yellow;</xsl:template>
<xsl:template match="@Days" priority="1">color: blue;</xsl:template>
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top