Skip to main content

How Conditional Formatting Works

The conditional formatting pipeline flows through three stages: a formula calculates the cell value, a cell decorator evaluates that value and toggles CSS classes, and the style definitions apply visual properties to those classes. diagram

Configuration Components

ComponentJSON PropertyTypeRole
FormulaformulasobjectNamed JavaScript functions that compute derived values from item fields. Referenced by the formula property on column definitions.
Cell DecoratorcellDecoratorsobjectNamed JavaScript functions that evaluate cell values and toggle CSS classes on the cell DOM element. Mapped to columns by matching the column id to the decorator key name.
StylestylesobjectCSS class definitions that specify visual properties (background color, text color, font weight, borders). Keys are CSS selectors prefixed with ..

Cell Decorators Reference

cellDecorators Property

NameTypeDefaultDescription
cellDecoratorsobject{}Collection of named JavaScript functions that apply conditional CSS classes to cells based on their values. Each key is a decorator name that maps to a column’s id property. The function receives an info object and uses jQuery toggleClass to add or remove CSS classes.

Decorator Function Signature

Each cell decorator function receives a single info parameter object:
PropertyTypeDescription
info.valueanyThe current cell value (after formula calculation if applicable)
info.cellHTMLElementThe DOM element for the cell. Use jQuery $(info.cell).toggleClass() to add/remove CSS classes
info.itemobjectThe complete work item data for the current row. Access any field via info.item['fieldName']

Built-In Decorator: rpn

Applies conditional CSS classes to RPN cells based on risk thresholds:
{
  "cellDecorators": {
    "rpn": "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val > 150 && val <= 350); $(info.cell).toggleClass('rpn3', val > 350);}"
  }
}
CSS ClassConditionRisk Level
boldColAlwaysAll RPN cells displayed bold
rpn1val > 0 && val <= 150Low risk
rpn2val > 150 && val <= 350Medium risk
rpn3val > 350High risk

Built-In Decorator: rowHeaderRpnNew

Applies conditional CSS classes to row headers based on the revised RPN value (after mitigations):
{
  "cellDecorators": {
    "rowHeaderRpnNew": "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val>0 && val > 150 && val <= 350); $(info.cell).toggleClass('rpn3', val>0 && val > 350);}"
  }
}
Row header decorators read from info.item (the full item data), not info.value, because the row header does not have a bound column value. The decorator name must match the headers.rowHeader.renderer value.

Styles Reference

styles Property

NameTypeDefaultDescription
stylesobject{}Collection of CSS class definitions. Each key is a CSS selector (prefixed with .) and the value is a CSS declaration block. Styles defined here are injected into the page and available for use by cell decorators.

Style Definition Format

Style keys use CSS selector syntax with a leading dot. The value contains CSS properties.
{
  "styles": {
    ".className": "property: value; property: value;"
  }
}
CSS styles in Risksheet typically require !important to override the grid’s default cell styling. Without !important, your custom background colors and text colors may not appear. This is a common source of issues when setting up conditional formatting.

Default RPN Style Definitions

CSS SelectorPropertiesPurpose
.boldColfont-weight:600;Bold text for RPN cells
.rpn1background-color: #eaf5e9 !important; color: #1d5f20 !important;Low risk: light green background, dark green text
.rpn2background-color: #fff3d2 !important; color: #735602 !important;Medium risk: light yellow background, dark yellow text
.rpn3background-color: #f8eae7 !important; color: #ab1c00 !important;High risk: light red background, dark red text

Header Group Styles

Styles can target header group rows using compound selectors:
CSS SelectorPropertiesPurpose
.firstRow .headSysReqbackground-color:rgba(62, 175, 63, 0.12) !important; color:#2A792D !importantFirst row of System Requirement column group: light green background
.lastRow .headSysReqbackground-color:#FFF !important; color:#2A792D !importantLast row of System Requirement column group: white background
.firstRow .headFinalRankingbackground-color:rgba(62, 175, 63, 0.12) !important; color:#2A792D !importantFirst row of Final Ranking column group: light green background
.lastRow .headFinalRankingbackground-color:#FFF !important; color:#2A792D !importantLast row of Final Ranking column group: white background

Formulas Reference

formulas Property

NameTypeDefaultDescription
formulasobject{}Collection of named JavaScript functions for calculating derived values in cells. Each key is a formula name referenced by the formula property on column definitions. Functions receive an info object with info.item for accessing row data.

Formula Function Signature

PropertyTypeDescription
info.itemobjectThe work item data for the current row. Access field values via info.item['fieldName'].
Return valueanyThe calculated value to display in the cell. Return null to display an empty cell.

Built-In Formula: commonRpn

Calculates the initial RPN by multiplying Occurrence, Detection, and Severity:
{
  "formulas": {
    "commonRpn": "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}"
  }
}

Built-In Formula: commonRpnNew

Calculates the revised RPN (after mitigations) using the new rating values:
{
  "formulas": {
    "commonRpnNew": "function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew']; return value?value:null; }"
  }
}

Enum Value Formatting

When applying conditional formatting to enum columns, cell decorator functions must compare against enum IDs, not display values.
Cell decorator functions compare against enum IDs (e.g., 'yes'), not display values (e.g., 'Y'). This is the most common mistake when setting up enum-based conditional formatting. If your decorator is not working, verify that you are using the id property from the enum definition, not the name property.
{
  "enums": {
    "approvalStatus": [
      { "id": "yes", "name": "Y", "description": "Approved" },
      { "id": "no", "name": "N", "description": "Not Approved" }
    ]
  },
  "cellDecorators": {
    "approvalStatus": "function(info){ var val = info.value; $(info.cell).toggleClass('approved', val === 'yes'); $(info.cell).toggleClass('notApproved', val === 'no'); }"
  },
  "styles": {
    ".approved": "background-color: #e8f5e9 !important; color: #2e7d32 !important;",
    ".notApproved": "background-color: #ffebee !important; color: #c62828 !important;"
  }
}
Columns using type: "rating:ENUMID" show enum descriptions in their dropdown, while columns using type: "enum:ENUMID" show only the enum name. Both types store the enum ID as the cell value. Choose rating for risk parameters (severity, occurrence, detection) where the description adds context.

Row Header Formatting

Apply conditional formatting to row headers based on item data. The row header renderer reads from the full item data object rather than a specific column value.
{
  "headers": {
    "rowHeader": {
      "renderer": "rowHeaderRpnNew"
    }
  },
  "cellDecorators": {
    "rowHeaderRpnNew": "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val>0 && val > 150 && val <= 350); $(info.cell).toggleClass('rpn3', val>0 && val > 350);}"
  }
}
PropertyTypeDefaultDescription
headers.rowHeader.rendererstringNoneName of a cell decorator function to apply to row headers. The function name must match a key in cellDecorators.

Severity-Based Cell Styling

Apply color gradients based on individual severity ratings (not the combined RPN):
{
  "cellDecorators": {
    "sevColor": "function(info){ var val = info.value; $(info.cell).toggleClass('highSev', val >= 8); $(info.cell).toggleClass('medSev', val >= 4 && val < 8); $(info.cell).toggleClass('lowSev', val > 0 && val < 4); }"
  },
  "styles": {
    ".highSev": "background-color: #ffcdd2 !important; color: #b71c1c !important;",
    ".medSev": "background-color: #fff9c4 !important; color: #f57f17 !important;",
    ".lowSev": "background-color: #c8e6c9 !important; color: #1b5e20 !important;"
  }
}

Conditional Editability

Use cell decorators to dynamically control which fields are editable based on item state. This pattern modifies the systemReadOnlyFields array on the item to lock specific columns.
{
  "cellDecorators": {
    "lockWhenApproved": "function(info){ if(info.item['reviewStatus'] === 'approved'){ info.item['systemReadOnlyFields'] = info.item['systemReadOnlyFields'] || []; info.item['systemReadOnlyFields'].push('severity','occurrence'); } }"
  }
}
This pattern adds severity and occurrence to the systemReadOnlyFields array when the item’s reviewStatus enum equals approved, preventing edits to risk parameters on already-reviewed items.

Column-Level CSS

In addition to cell decorators, you can apply static CSS classes to all cells in a column using the cellCss property:
NameTypeDefaultDescription
cellCssstringundefinedCSS class name(s) to apply to all cells in the column. Unlike cell decorators, this applies unconditionally.
headerGroupCssstringundefinedCSS class name(s) to apply to the header group row for this column.
{
  "columns": [
    {
      "id": "severity",
      "header": "Severity",
      "type": "rating:severity",
      "cellCss": "risk-param-col"
    }
  ],
  "styles": {
    ".risk-param-col": "text-align: center !important; font-weight: 600 !important;"
  }
}

Complete Example

Full FMEA conditional formatting configuration with initial and revised risk color coding, row header formatting, and enum-based styling:
{
  "formulas": {
    "commonRpn": "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}",
    "commonRpnNew": "function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew']; return value?value:null; }"
  },
  "cellDecorators": {
    "rpn": "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val>0 && val<=150); $(info.cell).toggleClass('rpn2', val>150 && val<=350); $(info.cell).toggleClass('rpn3', val>350); }",
    "rpnNew": "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val>0 && val<=150); $(info.cell).toggleClass('rpn2', val>150 && val<=350); $(info.cell).toggleClass('rpn3', val>350); }",
    "rowHeaderRpnNew": "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val>0 && val<=150); $(info.cell).toggleClass('rpn2', val>0 && val>150 && val<=350); $(info.cell).toggleClass('rpn3', val>0 && val>350); }"
  },
  "styles": {
    ".boldCol": "font-weight:600;",
    ".rpn1": "background-color: #eaf5e9 !important; color: #1d5f20 !important;",
    ".rpn2": "background-color: #fff3d2 !important; color: #735602 !important;",
    ".rpn3": "background-color: #f8eae7 !important; color: #ab1c00 !important;",
    ".firstRow .headSysReq": "background-color:rgba(62, 175, 63, 0.12) !important; color:#2A792D !important",
    ".lastRow .headSysReq": "background-color:#FFF !important; color:#2A792D !important",
    ".firstRow .headFinalRanking": "background-color:rgba(62, 175, 63, 0.12) !important; color:#2A792D !important",
    ".lastRow .headFinalRanking": "background-color:#FFF !important; color:#2A792D !important"
  },
  "headers": {
    "rowHeader": { "renderer": "rowHeaderRpnNew" },
    "columnHeader": { "height": 32 },
    "columnGroupHeader": { "height": 32 }
  },
  "columns": [
    { "id": "sev", "header": "S", "width": 60, "type": "rating:severity" },
    { "id": "occ", "header": "O", "width": 60, "type": "rating:occurrence" },
    { "id": "det", "header": "D", "width": 60, "type": "rating:detection" },
    { "id": "rpn", "header": "RPN", "width": 80, "formula": "commonRpn" },
    { "id": "sevNew", "header": "S*", "width": 60, "type": "rating:severity" },
    { "id": "occNew", "header": "O*", "width": 60, "type": "rating:occurrence" },
    { "id": "detNew", "header": "D*", "width": 60, "type": "rating:detection" },
    { "id": "rpnNew", "header": "RPN*", "width": 80, "formula": "commonRpnNew" }
  ]
}

Troubleshooting

SymptomCauseSolution
Cell colors not appearingMissing !important in style definitionAdd !important to background-color and color properties
Enum decorator not matchingComparing against display name instead of IDUse the enum id value (e.g., 'yes') not the name value (e.g., 'Y')
Row header not coloredDecorator name mismatchEnsure headers.rowHeader.renderer value matches a key in cellDecorators
Styles overriddenCSS specificity conflictUse compound selectors or add !important
Decorator not firingColumn ID mismatchEnsure the cellDecorators key matches the column id property exactly
KB ArticlesSupport TicketsSource Code
  • AppConfig.ts
  • risksheet.json
  • SheetConstants.ts
  • ApprovalBasedReview.java
  • CellEditorFormatter.ts