> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Renderer Templates

> Custom cell renderers in Nextedy RISKSHEET allow you to define JavaScript functions that control how cell values display in the grid.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

<Info title="Verify in application">
  This page has limited source coverage. Some behaviors should be verified against the running application.
</Info>

## Renderer Architecture

Custom renderers sit between the data model and the grid display. When Risksheet renders a cell, it first applies built-in rendering for the column type, then invokes any custom renderer registered for that column binding.

```text theme={null}
sheet configuration        Top Panel Template         Grid Cell
───────────────            ─────────────────          ──────────
columns:                   risksheetTopPanel.vm       Rendered output
  - id: severity     ──>   <script>            ──>   with custom
    cellRenderer:            function renderSev       HTML, styles,
      renderSev              (grid, cell, item,       and formatting
                             value) { ... }
                           </script>
Configuration              Implementation             Display
```

## Configuration Properties

### Column-Level Renderer Assignment

Register a custom renderer on a specific column using the `cellRenderer` property in the column definition. The function name must match a function registered on the global `window.risksheet.cellRenderers` object (typically defined inside `risksheetTopPanel.vm`).

| Name           | Type     | Default     | Description                                                                                                                                                                                                 |
| -------------- | -------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cellRenderer` | `string` | `undefined` | The name of a JavaScript function registered on `window.risksheet.cellRenderers` that controls how the cell value is displayed. The function is invoked during cell rendering for every row in that column. |

```yaml theme={null}
columns:
  - id: severity
    header: Severity
    bindings: severityRating
    width: 120
    type: rating:severity
    cellRenderer: renderSeverityCell
```

### Row Header Renderer

The row header (the leftmost fixed column showing row numbers) supports a custom renderer through the `headers` configuration.

| Name                         | Type     | Default | Description                                                                                                                                                                   |
| ---------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `headers.rowHeader.renderer` | `string` | None    | The name of a cell decorator function applied to row headers. Typically used to apply conditional styling based on row data (for example, coloring row headers by RPN value). |

```yaml theme={null}
headers:
  rowHeader:
    renderer: rowHeaderRpnNew
```

<Warning title="Comparison Mode">
  Custom cell renderers are not applied during comparison mode. When viewing revision differences, cells use the standard comparison highlighting instead of custom rendering logic.
</Warning>

## Renderer Function Signature

Each custom renderer function receives four parameters:

| Parameter | Type          | Description                                                                                                           |
| --------- | ------------- | --------------------------------------------------------------------------------------------------------------------- |
| `grid`    | `object`      | The grid control instance, providing access to grid-level settings, column definitions, and data operations           |
| `cell`    | `HTMLElement` | The DOM element for the cell being rendered. You can modify its `innerHTML`, `style`, `className`, and child elements |
| `item`    | `object`      | The work item data for the current row. Access any bound field value via `item['fieldName']`                          |
| `value`   | `any`         | The current cell value after any formula calculation. May be `null` or `undefined` for empty cells                    |

Define renderer functions in the [Top Panel Template](/risksheet/reference/templates/top-panel-template) using a `<script>` block, or register them on the global `window.risksheet.cellRenderers` object from any script loaded into the page.

## Built-In Column Type Rendering

Risksheet applies built-in rendering for standard column types before custom renderers execute. Understanding these defaults helps you write renderers that augment rather than conflict with standard behavior.

| Column Type                       | Built-In Rendering Behavior                                                                                                                                                                                                                                   |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Item link (`itemLink`)            | Displays as HTML hyperlink from the `_link` postfix property. New items (ID starting with `*`) show an asterisk prefix with a special CSS class. Supports custom property bindings for display.                                                               |
| Multi-item link (`multiItemLink`) | Parses JSON array with `id`, `label`, and `title` properties. Each link renders as a separate `<div>` element with a title tooltip showing the full ID and title. Hidden bracket separators between items support clean copy/paste behavior.                  |
| Multi-enum (`multiEnum:<enumId>`) | Selected values render as `span.multi-enum-list` containing `span.multi-enum-item` elements. Reads enum options from the Polarion enumeration and renders selected values with their display labels. Falls back to raw value if the enum option is not found. |
| Date (`date`)                     | Parses date strings in `YYYY-MM-DD` format to local time `Date` objects. Formats the date according to the column's `format` property using the Globalize library and the configured `global.culture` locale.                                                 |
| Boolean (`boolean`)               | Renders as a checkbox representation.                                                                                                                                                                                                                         |
| Server-rendered (`serverRender`)  | Displays server-generated HTML content as-is without client-side modification.                                                                                                                                                                                |

## Formula Integration with Renderers

Formulas execute during cell rendering and produce the `value` parameter passed to custom renderers. This means your renderer receives the calculated result, not the raw stored data.

| Property  | Type     | Default     | Description                                                                                                                                                                                 |
| --------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `formula` | `string` | `undefined` | Name of a formula function defined in the `formulas` section. Formulas execute with `info.item` context, returning the calculated value. Columns with formulas are automatically read-only. |

```yaml theme={null}
formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null; }"

columns:
  - id: rpn
    header: RPN
    width: 80
    formula: commonRpn
    cellRenderer: renderRpnBadge
```

<Note title="Formula-Driven Changes">
  When a formula result differs from the stored value, the system can mark the item as edited. Formula changes respect the `readOnly` column setting. The formula mark changes behavior enables tracking of calculated field changes for audit purposes.
</Note>

## Read-Only Cell Marking

Cells are visually marked as read-only based on cell-level permissions. The `readonly` CSS class is applied to indicate non-editable cells. Read-only state is determined by checking the following conditions:

| Source                | Condition                                                              |
| --------------------- | ---------------------------------------------------------------------- |
| Column `readOnly`     | The column definition has `readOnly: true`                             |
| Formula columns       | The column has a `formula` property set                                |
| Server render columns | The column has a `serverRender` property set                           |
| System fields         | System-managed columns (ID, author, created)                           |
| Item permissions      | `systemReadOnly` or `systemReadOnlyFields` includes the column binding |
| Task permissions      | `systemTaskReadOnly` or `systemTaskReadOnlyFields` for task rows       |

## Comparison and Baseline Highlighting

When a comparison manager is configured (viewing changes against a previous revision or baseline), Risksheet applies specialized cell highlighting that overrides custom renderers.

| Highlight Type      | Applies To      | Description                                                                                                                               |
| ------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Added rows          | Entire row      | New rows not present in the compared revision. Row background indicates addition.                                                         |
| Removed rows        | Entire row      | Rows deleted since the compared revision. Row background indicates removal. Ghost items (deleted in one revision) are handled separately. |
| Modified cells      | Individual cell | Changed property values between revisions. Cell background highlights the change. Tooltips explain the modification.                      |
| Not compared        | Individual cell | Columns that cannot be meaningfully compared (for example, formulas, server-rendered content).                                            |
| Downstream added    | Task columns    | New downstream task items linked to the master work item since the compared revision.                                                     |
| Downstream removed  | Task columns    | Downstream items removed since the compared revision.                                                                                     |
| Downstream modified | Task columns    | Property changes in existing downstream items. Tooltips identify the specific downstream item and change type.                            |

<Note title="Baseline Comparison Sorting">
  During baseline comparisons, sorting operates on the baseline snapshot values rather than current values, except for system identity fields (`systemItemId` and `systemItemRevision`) which always refer to the current item.
</Note>

## Cell Decorator vs. Cell Renderer

Risksheet provides two mechanisms for customizing cell appearance. Understanding the distinction prevents configuration errors.

| Feature                | Cell Decorator                                                         | Cell Renderer                                                                                         |
| ---------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| Configured via         | `cellDecorators` section in sheet configuration                        | `cellRenderer` property on column definition                                                          |
| Registration namespace | Function bodies live under `cellDecorators` in the sheet configuration | Function registered on `window.risksheet.cellRenderers` (typically defined in the top panel template) |
| Function context       | `info` object with `info.value`, `info.cell`, `info.item`              | `grid`, `cell`, `item`, `value` parameters                                                            |
| Purpose                | Toggle CSS classes based on cell value                                 | Full control over cell DOM content                                                                    |
| Typical use            | Conditional background/text colors                                     | Custom HTML badges, icons, progress bars                                                              |
| Multiple per column    | Yes (cell decorator applies independently)                             | One per column                                                                                        |
| Disabled in comparison | Yes                                                                    | Yes                                                                                                   |

## Complete Example

The following example shows a full custom renderer setup for an FMEA risksheet with severity badge rendering, RPN color coding via row headers, and a custom risk acceptance indicator.

**Top panel template (`risksheetTopPanel.vm`):**

```velocity theme={null}
<script>
  window.risksheet = window.risksheet || {};
  window.risksheet.cellRenderers = window.risksheet.cellRenderers || {};

  window.risksheet.cellRenderers.renderSeverityCell = function (grid, cell, item, value) {
    if (!value) return;

    var colors = {
      "catastrophic": "#e53935",
      "critical": "#ff7043",
      "marginal": "#ffb74d",
      "negligible": "#66bb6a"
    };

    var color = colors[value.toLowerCase()] || "#9e9e9e";
    cell.style.backgroundColor = color;
    cell.style.color = "#fff";
    cell.style.fontWeight = "600";
    cell.style.textAlign = "center";
    cell.textContent = value;
  };

  window.risksheet.cellRenderers.renderRiskLevel = function (grid, cell, item, value) {
    if (!value) return;

    var badge = document.createElement("span");
    badge.className = "risk-level-badge risk-" + value.toLowerCase();
    badge.textContent = value;
    cell.innerHTML = "";
    cell.appendChild(badge);
  };
</script>

<style>
  .risk-level-badge {
    padding: 2px 8px;
    border-radius: 3px;
    font-size: 11px;
    font-weight: 600;
    display: inline-block;
  }
  .risk-unacceptable { background: #e53935; color: #fff; }
  .risk-undesirable { background: #ff7043; color: #fff; }
  .risk-acceptable { background: #66bb6a; color: #fff; }
  .risk-negligible { background: #9e9e9e; color: #fff; }
</style>
```

**Sheet configuration:**

```yaml theme={null}
columns:
  - id: id
    header: ID
    width: 80
    readOnly: true

  - id: title
    header: Failure Mode
    bindings: title
    width: 200

  - id: severity
    header: Severity
    bindings: severityRating
    width: 120
    type: rating:severity
    cellRenderer: renderSeverityCell

  - id: rpn
    header: RPN
    width: 80
    formula: commonRpn

  - id: riskLevel
    header: Risk Level
    width: 120
    formula: riskAcceptance
    cellRenderer: renderRiskLevel

formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null; }"
  riskAcceptance: "function(info){ var rpn = info.item['occ']*info.item['det']*info.item['sev']; if(!rpn) return null; if(rpn>250) return 'Unacceptable'; if(rpn>150) return 'Undesirable'; if(rpn>50) return 'Acceptable'; return 'Negligible'; }"

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<=250); $(info.cell).toggleClass('rpn3', val>250); }"
  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 <= 250); $(info.cell).toggleClass('rpn3', val>0 && val > 250);}"

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;}"

headers:
  rowHeader:
    renderer: rowHeaderRpnNew
  columnHeader:
    height: 32
  columnGroupHeader:
    height: 32
```

## Related Pages

* [Top Panel Template](/risksheet/reference/templates/top-panel-template) -- where to define renderer function implementations
* [Cell Decorators](/risksheet/reference/styling/cell-decorators) -- CSS class toggling based on cell values
* [Conditional Formatting](/risksheet/reference/styling/conditional-formatting) -- style definitions for cell decorator classes
* [CSS Classes](/risksheet/reference/styling/css-classes) -- available CSS classes and custom style definitions
* [Calculated Columns](/risksheet/reference/columns/calculated-columns) -- formula-driven column values that feed into renderers
* [Column Type Reference](/risksheet/reference/columns/column-types) -- all column type options and their rendering behavior
* [Velocity Templates](/risksheet/reference/templates/velocity-templates) -- Velocity template system overview

<LastReviewed date="2026-06-24" />
