> ## 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.

# Configure Read-Only Column

> Prevent users from editing specific columns in Nextedy POWERSHEET by setting the `isReadOnly` property or applying a read-only formatter in your sheet configuration.

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

## Prerequisites

Before configuring read-only columns, ensure you have:

* A working sheet configuration YAML file
* Access to the project's sheet configuration in **Administration > Nextedy Powersheet**
* Familiarity with the [column properties](/powersheet/reference/sheet-config/index) available in Powersheet

<Warning title="Formatters style only -- they do not enforce">
  A read-only **formatter** applies visual styling only (for example, a grey background). It does **not** prevent editing on its own. To actually enforce that a column cannot be changed, set `isReadOnly: true` on the column (UI-level) and/or `updatable: false` on the property in the data model (server-level). Use the formatter alongside these to signal read-only status to users -- not in place of them.
</Warning>

<Steps>
  <Step title="Set isReadOnly on a Column">
    Add `isReadOnly: true` to any column definition in your sheet configuration to disable editing for that column:

    ```yaml theme={null}
    columns:
      outlineNumber:
        title: "#"
        width: 80
        isReadOnly: true

      systemRequirements.systemRequirement.id:
        title: "Req ID"
        width: 120
        isReadOnly: true
    ```

    The `isReadOnly` property accepts a boolean value and defaults to `false`. When set to `true`, cells in that column cannot be modified regardless of user permissions or formatter rules.

    | Property     | Type    | Default | Description                          |
    | ------------ | ------- | ------- | ------------------------------------ |
    | `isReadOnly` | boolean | `false` | Prevents user editing of this column |

    <Warning title="Document-level override">
      The `isReadOnly` value on a column can be overwritten by the user's permission level or the global configuration of the document. If a user has read-only access to the entire document, all columns become read-only regardless of individual column settings.
    </Warning>
  </Step>

  <Step title="Add Visual Feedback with a Read-Only Formatter">
    Setting `isReadOnly: true` prevents editing but does not change the column's appearance. To add a visual cue so users can immediately see which columns are non-editable, combine the property with a formatter:

    ```yaml theme={null}
    formatters:
      readOnlyFormat:
        - expression: "true"
          style: readOnlyStyle

    styles:
      readOnlyStyle:
        backgroundColor: grey100

    columns:
      outlineNumber:
        title: "#"
        width: 80
        isReadOnly: true
        formatter: readOnlyFormat
    ```

    This approach provides both functional protection (the cell cannot be edited) and a visual indicator (the grey background signals read-only status to users).

    <Note>
      `grey100` is one of Powersheet's built-in **color tokens**. For the full palette of valid token names (each color family runs from `100` lightest to `700` darkest) and the predefined style names, see the [Styles reference](/powersheet/reference/sheet-config/styles#color-token-reference).
    </Note>

    <Tip title="Use a shared formatter for consistency">
      Define a single `readOnlyFormat` formatter and reference it across all read-only columns. This keeps your configuration DRY and ensures a uniform appearance throughout the sheet.
    </Tip>
  </Step>

  <Step title="Use Conditional Read-Only with Formatters">
    For columns that should be read-only only under certain conditions, use a formatter with a conditional expression instead of a static `isReadOnly` flag:

    ```yaml theme={null}
    formatters:
      lockedWhenApproved:
        - expression: "context.item.Status === 'Approved'"
          style: readOnlyStyle

    styles:
      readOnlyStyle:
        backgroundColor: grey100

    columns:
      title:
        title: "Title"
        width: 300
        formatter: lockedWhenApproved
    ```

    In this example, the `title` column becomes visually styled as read-only when the work item's `Status` is `Approved`. The formatter expression has access to the `context` object, which provides:

    * `context.item` -- the current entity (row data)
    * `context.value` -- the current cell value
    * `context.document` -- the document data

    <Warning title="Property names are case-sensitive">
      In client-side expressions, `context.item.<Property>` must match the property name as defined in your data model **exactly**, including case. The examples here use `Status` because that is the property name in the demo model; substitute your own model's casing. This client-side accessor is distinct from the server-side Velocity form `$item.status.id` used in [server-rendered templates](/powersheet/reference/server-rendering/velocity-templates) -- do not mix the two notations.
    </Warning>

    <Info title="Verify in application">
      Conditional formatter expressions apply visual styling. To fully enforce editing restrictions based on status, combine formatters with data model constraints or document-level permissions.
    </Info>
  </Step>
</Steps>

## How Read-Only Resolution Works

Powersheet evaluates multiple conditions to determine whether a column is editable. A column becomes read-only if **any** of these conditions are true:

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/-WiVljKlDztH36bB/powersheet/diagrams/guides/sheet-configuration/configure-read-only-column/diagram-1.svg?fit=max&auto=format&n=-WiVljKlDztH36bB&q=85&s=64d26b69d2e21cd2b9640f6bf517e69d" alt="diagram" style={{ width: "520px", maxWidth: "100%" }} width="520" height="220" data-path="powersheet/diagrams/guides/sheet-configuration/configure-read-only-column/diagram-1.svg" />
</Frame>

1. **Configuration flag** -- `isReadOnly: true` is set on the column in the sheet configuration YAML
2. **Historical revision** -- The user is viewing a past revision of the document (all columns automatically become read-only)
3. **User permission** -- The document access control grants the user only viewer (not editor) access

<Tip title="Troubleshooting: a column is read-only when you did not expect it">
  Because the conditions above are combined with OR, any single one makes the column read-only. Work backwards from the symptom:

  * **Every column in the document is read-only** -- check conditions 2 and 3: you are most likely viewing a past revision, or your access to the document is viewer-only.
  * **One specific column is always read-only** -- check condition 1 (`isReadOnly: true` on that column) and the data model (`updatable: false`, or a `serverRender` annotation, on the underlying property).
  * **A formatter-styled column looks locked but still edits** -- that is expected: a formatter only styles, it does not enforce (see the warning at the top of this page).
</Tip>

<Note title="System-managed and server-rendered columns are always read-only">
  Certain columns such as `outlineNumber` are inherently managed by Polarion and should always have `isReadOnly: true`. In addition -- **this is the canonical rule referenced from the server-rendering pages** -- any property that defines a `serverRender` annotation, or that has `updatable: false` in the data model, is automatically read-only regardless of the sheet configuration. For server-rendered properties this override cannot be disabled: even `updatable: true` is ignored, because the value is always recomputed from the template.
</Note>

## Complete Configuration Example

Here is a full sheet configuration excerpt showing multiple read-only patterns in a requirements traceability context:

```yaml theme={null}
formatters:
  readOnlyFormat:
    - expression: "true"
      style: readOnlyStyle
  lockedOnApproval:
    - expression: "context.item.Status === 'Approved'"
      style: readOnlyStyle

styles:
  readOnlyStyle:
    backgroundColor: grey100

columns:
  outlineNumber:
    title: "#"
    width: 80
    isReadOnly: true
    formatter: readOnlyFormat

  id:
    title: "ID"
    width: 100
    isReadOnly: true
    formatter: readOnlyFormat
    hasUrl: true

  title:
    title: "Title"
    width: 300
    hasFocus: true
    formatter: lockedOnApproval

  systemRequirements.systemRequirement.id:
    title: "Sys Req ID"
    width: 120
    isReadOnly: true
    formatter: readOnlyFormat

  systemRequirements.systemRequirement.title:
    title: "Sys Req Title"
    width: 250
```

In this example:

* `outlineNumber` and `id` are always read-only with grey background styling
* `title` becomes visually styled when the item status is `Approved`
* The expanded `systemRequirement.id` column is read-only since IDs should not be user-editable
* `systemRequirement.title` remains editable (no `isReadOnly` flag)

## Property-Level Permissions in the Data Model

You can also control editability at the data model level using the `readable` and `updatable` properties on entity type definitions:

```yaml theme={null}
domainModelTypes:
  UserNeed:
    properties:
      id:
        readable: true
        updatable: false
      title:
        readable: true
        updatable: true
```

| Property    | Default | Description                                            |
| ----------- | ------- | ------------------------------------------------------ |
| `readable`  | `true`  | Controls whether the property is visible to users      |
| `updatable` | `true`  | Controls whether the property can be modified by users |

When `updatable` is `false`, the column becomes read-only for that property regardless of the sheet configuration `isReadOnly` setting.

<Note>
  `updatable` defaults to `true` for ordinary properties. The one exception is a property with a `serverRender` annotation: there, Powersheet forces the effective value to `false` (see the [Velocity Templates reference](/powersheet/reference/server-rendering/velocity-templates#server-rendered-property-configuration)). So a `false` default documented on the server-rendering pages refers specifically to server-rendered properties, not to the general case.
</Note>

<Tip title="Combine approaches for defense in depth">
  Use `isReadOnly` in the sheet configuration for UI-level protection and `updatable: false` in the data model for server-level enforcement. This ensures data integrity even if a configuration is accidentally changed.
</Tip>

## Verification

After saving your sheet configuration changes, reload the Powersheet document in Polarion:

1. Open the sheet and click on a cell in the read-only column -- you should see that the cell does not enter edit mode and the selection marquee shows a read-only indicator
2. If you applied a formatter, verify the grey background (or your custom style) appears on the read-only cells
3. Try pasting into a read-only column -- the paste operation should be blocked
4. Confirm that editable columns next to the read-only ones still accept input normally

You should now see that the configured columns are protected from editing, with visual styling distinguishing them from editable columns.

## See Also

* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- basic column setup and property binding
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- conditional formatting and style rules
* [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style) -- custom visual styling for columns
* [Configure Permissions](/powersheet/guides/administration/configure-permissions) -- document-level access control
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- complete property reference

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