UI Builder Data Grid Component: Cell Readonly

Reece Poulsen
Tera Contributor

I've been working on a custom UI Builder Workspace where I need to create a spreadsheet for quick data editing. I really didn't want to have to build it as a custom component from scratch so I did some looking around other SN workspaces to see if something already existed. I noticed a component in the CWM workspace that looked like a grid with quick editing and it piqued my interest!

 

After some searching, I found the component in the sys_uib_toolbox_component table called Data Grid (sys_id 

7f8222ae7660164207b5c097c90bcf45) but it was flagged as an internal only component. Luckily, I was able to switch scopes and flip the internal flag to false, which allowed me to add it to a page in UI Builder!

 

Since then, I've figured out most of the component's API from other instances of it in SN workspaces. Its met 95% of my requirements, its an awesome component! However, there is one piece that I haven't been able to figure out yet (hence this post).

 

Does anyone know how to flag an individual cell in the grid as read-only?

 

From what I can see, you can pass an editable flag into the column objects and that works for the column but I have tried the same thing for both rows and cells and haven't had any luck.

 

I need to flag read-only on a cell by cell basis, column level read-only isn't specific enough for my use-case. I'm really hoping that this component has the capability to manage read-only at the cell/row level and not just at the column level.

 

If anyone has experience with component and is able to shed some light on this it would be greatly appreciated!

 

It doesn't look like there is any public documentation for it because it is "technically" an internal only component

1 ACCEPTED SOLUTION

Subhash Kumar
ServiceNow Employee

Configuring Readonly Cells, Rows, and Columns in Data Grid

This guide explains how to make specific cells, rows, or columns readonly (non-editable) in the sn-datagrid component using your data source configuration.

Version Requirements

Feature Property Minimum Version Release Date
Grid-level readonly config.readonly 21.1.1 May 2022
Column-level readonly column.editable 21.1.1 May 2022
Cell-level readonly column.criteria 21.4.2 September 2022
Row-level readonly _metadata.disableEditing 24.0.1 February 2024
Visual indication enableSmartCellBackground 24.0.1 February 2024

Note: Current version is 26.0.0. All features documented in this guide are available in the current release.


Table of Contents


Overview

The Data Grid component supports multiple levels of readonly configuration, giving you fine-grained control over which parts of your grid users can edit. You can configure readonly behavior at four different levels:

Level Scope Configuration Location
Grid Entire grid config.readonly
Column All cells in a column column.editable
Row All cells in a row task._metadata.disableEditing
Cell Individual cells column.criteria

1. Grid-Level Readonly

To make the entire grid readonly (no editing allowed anywhere), set the readonly property to true in your config.

Configuration

{
  "config": {
    "readonly": true,
    "editMode": "cellEdit"
  }
}

Properties

Property Type Default Description
readonly Boolean false When true, the entire grid becomes non-editable

Example

{
  "properties": {
    "config": {
      "readonly": true,
      "editMode": "cellEdit",
      "previewRecordIcon": true,
      "rowSelectionCheckbox": true
    }
  }
}

Note: When readonly is true, features like row copy/paste (rowCopyPaste) will not work even if enabled.


2. Column-Level Readonly

To make a specific column readonly while keeping other columns editable, set the editable property to false in the column definition.

Configuration

{
  "columns": [
    {
      "name": "status",
      "label": "Status",
      "type": "choice",
      "editable": false
    }
  ]
}

Properties

Property Type Default Description
editable Boolean true When false, the entire column becomes non-editable

Example

{
  "columns": [
    {
      "name": "title",
      "label": "Title",
      "type": "string",
      "editable": true
    },
    {
      "name": "created_date",
      "label": "Created Date",
      "type": "date",
      "editable": false
    },
    {
      "name": "record_type",
      "label": "Record Type",
      "type": "string",
      "editable": false
    }
  ]
}

In this example:

  • Title column is editable
  • Created Date and Record Type columns are readonly

3. Row-Level Readonly

To make a specific row readonly while keeping other rows editable, use the _metadata.disableEditing property in your task (row) data.

Configuration

Add the _metadata object to your task data with disableEditing: true:

{
  "tasks": [
    {
      "id": "task-1",
      "title": { "displayValue": "Editable Task" },
      "_metadata": {
        "disableEditing": false
      }
    },
    {
      "id": "task-2",
      "title": { "displayValue": "Readonly Task" },
      "_metadata": {
        "disableEditing": true
      }
    }
  ]
}

Properties

Property Type Default Description
_metadata.disableEditing Boolean false When true, the entire row becomes non-editable

 

Example

{
  "tasks": [
    {
      "id": "goal-1",
      "title": { "displayValue": "Q1 Sales Goal", "value": "Q1 Sales Goal" },
      "status": { "displayValue": "In Progress", "value": "in_progress" },
      "_metadata": {
        "disableEditing": false,
        "tableName": "sn_gf_goal",
        "canWrite": true
      }
    },
    {
      "id": "goal-2",
      "title": { "displayValue": "Archived Goal", "value": "Archived Goal" },
      "status": { "displayValue": "Completed", "value": "completed" },
      "_metadata": {
        "disableEditing": true,
        "tableName": "sn_gf_goal",
        "canWrite": false
      }
    }
  ]
}

In this example:

  • Q1 Sales Goal row is editable
  • Archived Goal row is readonly (cannot be edited)

4. Cell-Level Readonly (Using Criteria)

To make specific cells readonly based on conditions in your data, use the criteria property in the column definition. This is the most powerful option as it allows dynamic readonly behavior based on row data.

Configuration

Add a criteria string to your column definition:

{
  "columns": [
    {
      "name": "target_value",
      "label": "Target Value",
      "type": "number",
      "editable": true,
      "criteria": "_metadata.tableName=sn_gf_goal"
    }
  ]
}

How Criteria Works

The criteria property evaluates against each row's data. When the criteria matches (evaluates to true), the cell becomes readonly/disabled for that specific row.

Criteria Syntax

fieldPath=value
fieldPath!=value
fieldPathINvalue1,value2,value3

Examples

Example 1: Disable based on metadata field

Make cells readonly when _metadata.tableName equals sn_gf_goal:

{
  "name": "target_value",
  "label": "Target Value",
  "editable": true,
  "criteria": "_metadata.tableName=sn_gf_goal"
}

Example 2: Disable based on task data field

Make cells readonly when status.value equals completed:

{
  "name": "description",
  "label": "Description",
  "editable": true,
  "criteria": "status.value=completed"
}

Example 3: Using NOT EQUAL operator

Make cells readonly when parent is NOT equal to capex:

{
  "name": "budget",
  "label": "Budget",
  "editable": true,
  "criteria": "parent!=capex"
}

Example 4: Using IN operator

Make cells readonly when parent is in the list capex,opex:

{
  "name": "amount",
  "label": "Amount",
  "editable": true,
  "criteria": "parentINcapex,opex"
}

Example 5: Multiple conditions with AND (^)

Make cells readonly when BOTH conditions are true:

{
  "name": "actual_value",
  "label": "Actual Value",
  "editable": true,
  "criteria": "_metadata.isActualValueNotEditable=true^status.value=locked"
}

Visual Indication for Readonly Cells

Use the enableSmartCellBackground property to visually indicate readonly cells with a grey background.

Configuration

{
  "columns": [
    {
      "name": "calculated_field",
      "label": "Calculated Field",
      "editable": false,
      "enableSmartCellBackground": true
    }
  ]
}

Properties

Property Type Default Description
enableSmartCellBackground Boolean false When true, readonly cells display with a grey background to visually indicate they cannot be edited

Example with Criteria

{
  "name": "total_actual",
  "label": "Total Actual",
  "editable": true,
  "criteria": "_metadata.isCalculated=true",
  "enableSmartCellBackground": true
}

This will:

  1. Make cells readonly when _metadata.isCalculated is true
  2. Display those readonly cells with a grey background

Complete Example

Here's a complete example showing all levels of readonly configuration:

{
  "properties": {
    "config": {
      "readonly": false,
      "editMode": "cellEdit",
      "previewRecordIcon": true,
      "rowSelectionCheckbox": true
    },
    "columns": [
      {
        "name": "title",
        "label": "Title",
        "type": "text",
        "section": "left",
        "editable": true,
        "width": 300
      },
      {
        "name": "status",
        "label": "Status",
        "type": "choice",
        "section": "center",
        "editable": true,
        "width": 150
      },
      {
        "name": "target_value",
        "label": "Target Value",
        "type": "number",
        "section": "center",
        "editable": true,
        "criteria": "_metadata.tableName=sn_gf_goal",
        "enableSmartCellBackground": true,
        "width": 160
      },
      {
        "name": "actual_value",
        "label": "Actual Value",
        "type": "number",
        "section": "center",
        "editable": true,
        "criteria": "_metadata.isActualValueNotEditable=true",
        "enableSmartCellBackground": true,
        "width": 160
      },
      {
        "name": "created_by",
        "label": "Created By",
        "type": "reference",
        "section": "center",
        "editable": false,
        "enableSmartCellBackground": true,
        "width": 200
      },
      {
        "name": "sys_created_on",
        "label": "Created Date",
        "type": "date",
        "section": "center",
        "editable": false,
        "enableSmartCellBackground": true,
        "width": 150
      }
    ],
    "tasks": [
      {
        "id": "goal-1",
        "title": { "displayValue": "Increase Revenue", "value": "Increase Revenue" },
        "status": { "displayValue": "In Progress", "value": "in_progress" },
        "target_value": { "displayValue": "1,000,000", "value": 1000000 },
        "actual_value": { "displayValue": "750,000", "value": 750000 },
        "created_by": { "displayValue": "John Doe", "value": "user-123" },
        "sys_created_on": { "displayValue": "2024-01-15", "value": "2024-01-15" },
        "_metadata": {
          "tableName": "sn_gf_goal",
          "disableEditing": false,
          "isActualValueNotEditable": false
        }
      },
      {
        "id": "target-1",
        "title": { "displayValue": "Q1 Target", "value": "Q1 Target" },
        "status": { "displayValue": "Active", "value": "active" },
        "target_value": { "displayValue": "250,000", "value": 250000 },
        "actual_value": { "displayValue": "200,000", "value": 200000 },
        "created_by": { "displayValue": "Jane Smith", "value": "user-456" },
        "sys_created_on": { "displayValue": "2024-01-20", "value": "2024-01-20" },
        "_metadata": {
          "tableName": "sn_gf_goal_target",
          "disableEditing": false,
          "isActualValueNotEditable": true
        }
      },
      {
        "id": "goal-2",
        "title": { "displayValue": "Archived Goal", "value": "Archived Goal" },
        "status": { "displayValue": "Completed", "value": "completed" },
        "target_value": { "displayValue": "500,000", "value": 500000 },
        "actual_value": { "displayValue": "520,000", "value": 520000 },
        "created_by": { "displayValue": "Admin User", "value": "user-789" },
        "sys_created_on": { "displayValue": "2023-06-01", "value": "2023-06-01" },
        "_metadata": {
          "tableName": "sn_gf_goal",
          "disableEditing": true,
          "isActualValueNotEditable": true
        }
      }
    ]
  }
}

Result Summary

Row Title Status Target Value Actual Value Created By Created Date
goal-1 ✏️ Editable ✏️ Editable 🔒 Readonly (criteria: tableName=goal) ✏️ Editable 🔒 Readonly (column) 🔒 Readonly (column)
target-1 ✏️ Editable ✏️ Editable ✏️ Editable 🔒 Readonly (criteria) 🔒 Readonly (column) 🔒 Readonly (column)
goal-2 🔒 Readonly (row) 🔒 Readonly (row) 🔒 Readonly (row) 🔒 Readonly (row) 🔒 Readonly (row) 🔒 Readonly (row)

Criteria Operators Reference

Operator Syntax Example Description
Equals = status.value=completed Cell is readonly when field equals value
Not Equals != parent!=capex Cell is readonly when field does not equal value
In IN parentINcapex,opex Cell is readonly when field is in the comma-separated list
Is Empty ISEMPTY fieldISEMPTY Cell is readonly when field is empty
Is Not Empty ISNOTEMPTY fieldISNOTEMPTY Cell is readonly when field is not empty
Greater Than > amount>1000 Cell is readonly when field is greater than value
Greater Than or Equal >= amount>=1000 Cell is readonly when field is greater than or equal to value
Less Than < amount<100 Cell is readonly when field is less than value
Less Than or Equal <= amount<=100 Cell is readonly when field is less than or equal to value

Combining Criteria

Use ^ (caret) to combine multiple conditions with AND logic:

condition1^condition2^condition3

Example:

"criteria": "_metadata.tableName=sn_gf_goal^status.value!=draft"

This makes the cell readonly when:

  • _metadata.tableName equals sn_gf_goal AND
  • status.value does not equal draft

Best Practices

1. Use the Right Level of Configuration

  • Grid-level: Use when the entire grid should be view-only (e.g., report views)
  • Column-level: Use for system fields that should never be edited (e.g., created date, ID fields)
  • Row-level: Use for records with specific states (e.g., archived, locked, completed)
  • Cell-level: Use for conditional editability based on business rules

2. Provide Visual Feedback

Enable enableSmartCellBackground: true for readonly columns/cells so users can easily identify which cells they cannot edit.

3. Use Metadata Wisely

Structure your _metadata object to contain all the information needed for readonly decisions:

"_metadata": {
  "tableName": "my_table",
  "disableEditing": false,
  "canWrite": true,
  "isLocked": false,
  "isArchived": false
}

4. Test Criteria Expressions

Before deploying, test your criteria expressions with different data scenarios to ensure they work as expected.


Troubleshooting

Cell is not becoming readonly

  1. Verify config.readonly is false (grid-level must allow editing)
  2. Check if column.editable is true
  3. Verify your criteria syntax is correct
  4. Check that the field path in criteria matches your task data structure

Visual indication not showing

  1. Ensure enableSmartCellBackground: true is set on the column
  2. Verify the cell is actually readonly (criteria is matching)

Row context menu still appears for readonly rows

Use _metadata.disableRowContextMenu: true in addition to disableEditing:

"_metadata": {
  "disableEditing": true,
  "disableRowContextMenu": true
}

 

View solution in original post

4 REPLIES 4

Subhash Kumar
ServiceNow Employee

Configuring Readonly Cells, Rows, and Columns in Data Grid

This guide explains how to make specific cells, rows, or columns readonly (non-editable) in the sn-datagrid component using your data source configuration.

Version Requirements

Feature Property Minimum Version Release Date
Grid-level readonly config.readonly 21.1.1 May 2022
Column-level readonly column.editable 21.1.1 May 2022
Cell-level readonly column.criteria 21.4.2 September 2022
Row-level readonly _metadata.disableEditing 24.0.1 February 2024
Visual indication enableSmartCellBackground 24.0.1 February 2024

Note: Current version is 26.0.0. All features documented in this guide are available in the current release.


Table of Contents


Overview

The Data Grid component supports multiple levels of readonly configuration, giving you fine-grained control over which parts of your grid users can edit. You can configure readonly behavior at four different levels:

Level Scope Configuration Location
Grid Entire grid config.readonly
Column All cells in a column column.editable
Row All cells in a row task._metadata.disableEditing
Cell Individual cells column.criteria

1. Grid-Level Readonly

To make the entire grid readonly (no editing allowed anywhere), set the readonly property to true in your config.

Configuration

{
  "config": {
    "readonly": true,
    "editMode": "cellEdit"
  }
}

Properties

Property Type Default Description
readonly Boolean false When true, the entire grid becomes non-editable

Example

{
  "properties": {
    "config": {
      "readonly": true,
      "editMode": "cellEdit",
      "previewRecordIcon": true,
      "rowSelectionCheckbox": true
    }
  }
}

Note: When readonly is true, features like row copy/paste (rowCopyPaste) will not work even if enabled.


2. Column-Level Readonly

To make a specific column readonly while keeping other columns editable, set the editable property to false in the column definition.

Configuration

{
  "columns": [
    {
      "name": "status",
      "label": "Status",
      "type": "choice",
      "editable": false
    }
  ]
}

Properties

Property Type Default Description
editable Boolean true When false, the entire column becomes non-editable

Example

{
  "columns": [
    {
      "name": "title",
      "label": "Title",
      "type": "string",
      "editable": true
    },
    {
      "name": "created_date",
      "label": "Created Date",
      "type": "date",
      "editable": false
    },
    {
      "name": "record_type",
      "label": "Record Type",
      "type": "string",
      "editable": false
    }
  ]
}

In this example:

  • Title column is editable
  • Created Date and Record Type columns are readonly

3. Row-Level Readonly

To make a specific row readonly while keeping other rows editable, use the _metadata.disableEditing property in your task (row) data.

Configuration

Add the _metadata object to your task data with disableEditing: true:

{
  "tasks": [
    {
      "id": "task-1",
      "title": { "displayValue": "Editable Task" },
      "_metadata": {
        "disableEditing": false
      }
    },
    {
      "id": "task-2",
      "title": { "displayValue": "Readonly Task" },
      "_metadata": {
        "disableEditing": true
      }
    }
  ]
}

Properties

Property Type Default Description
_metadata.disableEditing Boolean false When true, the entire row becomes non-editable

 

Example

{
  "tasks": [
    {
      "id": "goal-1",
      "title": { "displayValue": "Q1 Sales Goal", "value": "Q1 Sales Goal" },
      "status": { "displayValue": "In Progress", "value": "in_progress" },
      "_metadata": {
        "disableEditing": false,
        "tableName": "sn_gf_goal",
        "canWrite": true
      }
    },
    {
      "id": "goal-2",
      "title": { "displayValue": "Archived Goal", "value": "Archived Goal" },
      "status": { "displayValue": "Completed", "value": "completed" },
      "_metadata": {
        "disableEditing": true,
        "tableName": "sn_gf_goal",
        "canWrite": false
      }
    }
  ]
}

In this example:

  • Q1 Sales Goal row is editable
  • Archived Goal row is readonly (cannot be edited)

4. Cell-Level Readonly (Using Criteria)

To make specific cells readonly based on conditions in your data, use the criteria property in the column definition. This is the most powerful option as it allows dynamic readonly behavior based on row data.

Configuration

Add a criteria string to your column definition:

{
  "columns": [
    {
      "name": "target_value",
      "label": "Target Value",
      "type": "number",
      "editable": true,
      "criteria": "_metadata.tableName=sn_gf_goal"
    }
  ]
}

How Criteria Works

The criteria property evaluates against each row's data. When the criteria matches (evaluates to true), the cell becomes readonly/disabled for that specific row.

Criteria Syntax

fieldPath=value
fieldPath!=value
fieldPathINvalue1,value2,value3

Examples

Example 1: Disable based on metadata field

Make cells readonly when _metadata.tableName equals sn_gf_goal:

{
  "name": "target_value",
  "label": "Target Value",
  "editable": true,
  "criteria": "_metadata.tableName=sn_gf_goal"
}

Example 2: Disable based on task data field

Make cells readonly when status.value equals completed:

{
  "name": "description",
  "label": "Description",
  "editable": true,
  "criteria": "status.value=completed"
}

Example 3: Using NOT EQUAL operator

Make cells readonly when parent is NOT equal to capex:

{
  "name": "budget",
  "label": "Budget",
  "editable": true,
  "criteria": "parent!=capex"
}

Example 4: Using IN operator

Make cells readonly when parent is in the list capex,opex:

{
  "name": "amount",
  "label": "Amount",
  "editable": true,
  "criteria": "parentINcapex,opex"
}

Example 5: Multiple conditions with AND (^)

Make cells readonly when BOTH conditions are true:

{
  "name": "actual_value",
  "label": "Actual Value",
  "editable": true,
  "criteria": "_metadata.isActualValueNotEditable=true^status.value=locked"
}

Visual Indication for Readonly Cells

Use the enableSmartCellBackground property to visually indicate readonly cells with a grey background.

Configuration

{
  "columns": [
    {
      "name": "calculated_field",
      "label": "Calculated Field",
      "editable": false,
      "enableSmartCellBackground": true
    }
  ]
}

Properties

Property Type Default Description
enableSmartCellBackground Boolean false When true, readonly cells display with a grey background to visually indicate they cannot be edited

Example with Criteria

{
  "name": "total_actual",
  "label": "Total Actual",
  "editable": true,
  "criteria": "_metadata.isCalculated=true",
  "enableSmartCellBackground": true
}

This will:

  1. Make cells readonly when _metadata.isCalculated is true
  2. Display those readonly cells with a grey background

Complete Example

Here's a complete example showing all levels of readonly configuration:

{
  "properties": {
    "config": {
      "readonly": false,
      "editMode": "cellEdit",
      "previewRecordIcon": true,
      "rowSelectionCheckbox": true
    },
    "columns": [
      {
        "name": "title",
        "label": "Title",
        "type": "text",
        "section": "left",
        "editable": true,
        "width": 300
      },
      {
        "name": "status",
        "label": "Status",
        "type": "choice",
        "section": "center",
        "editable": true,
        "width": 150
      },
      {
        "name": "target_value",
        "label": "Target Value",
        "type": "number",
        "section": "center",
        "editable": true,
        "criteria": "_metadata.tableName=sn_gf_goal",
        "enableSmartCellBackground": true,
        "width": 160
      },
      {
        "name": "actual_value",
        "label": "Actual Value",
        "type": "number",
        "section": "center",
        "editable": true,
        "criteria": "_metadata.isActualValueNotEditable=true",
        "enableSmartCellBackground": true,
        "width": 160
      },
      {
        "name": "created_by",
        "label": "Created By",
        "type": "reference",
        "section": "center",
        "editable": false,
        "enableSmartCellBackground": true,
        "width": 200
      },
      {
        "name": "sys_created_on",
        "label": "Created Date",
        "type": "date",
        "section": "center",
        "editable": false,
        "enableSmartCellBackground": true,
        "width": 150
      }
    ],
    "tasks": [
      {
        "id": "goal-1",
        "title": { "displayValue": "Increase Revenue", "value": "Increase Revenue" },
        "status": { "displayValue": "In Progress", "value": "in_progress" },
        "target_value": { "displayValue": "1,000,000", "value": 1000000 },
        "actual_value": { "displayValue": "750,000", "value": 750000 },
        "created_by": { "displayValue": "John Doe", "value": "user-123" },
        "sys_created_on": { "displayValue": "2024-01-15", "value": "2024-01-15" },
        "_metadata": {
          "tableName": "sn_gf_goal",
          "disableEditing": false,
          "isActualValueNotEditable": false
        }
      },
      {
        "id": "target-1",
        "title": { "displayValue": "Q1 Target", "value": "Q1 Target" },
        "status": { "displayValue": "Active", "value": "active" },
        "target_value": { "displayValue": "250,000", "value": 250000 },
        "actual_value": { "displayValue": "200,000", "value": 200000 },
        "created_by": { "displayValue": "Jane Smith", "value": "user-456" },
        "sys_created_on": { "displayValue": "2024-01-20", "value": "2024-01-20" },
        "_metadata": {
          "tableName": "sn_gf_goal_target",
          "disableEditing": false,
          "isActualValueNotEditable": true
        }
      },
      {
        "id": "goal-2",
        "title": { "displayValue": "Archived Goal", "value": "Archived Goal" },
        "status": { "displayValue": "Completed", "value": "completed" },
        "target_value": { "displayValue": "500,000", "value": 500000 },
        "actual_value": { "displayValue": "520,000", "value": 520000 },
        "created_by": { "displayValue": "Admin User", "value": "user-789" },
        "sys_created_on": { "displayValue": "2023-06-01", "value": "2023-06-01" },
        "_metadata": {
          "tableName": "sn_gf_goal",
          "disableEditing": true,
          "isActualValueNotEditable": true
        }
      }
    ]
  }
}

Result Summary

Row Title Status Target Value Actual Value Created By Created Date
goal-1 ✏️ Editable ✏️ Editable 🔒 Readonly (criteria: tableName=goal) ✏️ Editable 🔒 Readonly (column) 🔒 Readonly (column)
target-1 ✏️ Editable ✏️ Editable ✏️ Editable 🔒 Readonly (criteria) 🔒 Readonly (column) 🔒 Readonly (column)
goal-2 🔒 Readonly (row) 🔒 Readonly (row) 🔒 Readonly (row) 🔒 Readonly (row) 🔒 Readonly (row) 🔒 Readonly (row)

Criteria Operators Reference

Operator Syntax Example Description
Equals = status.value=completed Cell is readonly when field equals value
Not Equals != parent!=capex Cell is readonly when field does not equal value
In IN parentINcapex,opex Cell is readonly when field is in the comma-separated list
Is Empty ISEMPTY fieldISEMPTY Cell is readonly when field is empty
Is Not Empty ISNOTEMPTY fieldISNOTEMPTY Cell is readonly when field is not empty
Greater Than > amount>1000 Cell is readonly when field is greater than value
Greater Than or Equal >= amount>=1000 Cell is readonly when field is greater than or equal to value
Less Than < amount<100 Cell is readonly when field is less than value
Less Than or Equal <= amount<=100 Cell is readonly when field is less than or equal to value

Combining Criteria

Use ^ (caret) to combine multiple conditions with AND logic:

condition1^condition2^condition3

Example:

"criteria": "_metadata.tableName=sn_gf_goal^status.value!=draft"

This makes the cell readonly when:

  • _metadata.tableName equals sn_gf_goal AND
  • status.value does not equal draft

Best Practices

1. Use the Right Level of Configuration

  • Grid-level: Use when the entire grid should be view-only (e.g., report views)
  • Column-level: Use for system fields that should never be edited (e.g., created date, ID fields)
  • Row-level: Use for records with specific states (e.g., archived, locked, completed)
  • Cell-level: Use for conditional editability based on business rules

2. Provide Visual Feedback

Enable enableSmartCellBackground: true for readonly columns/cells so users can easily identify which cells they cannot edit.

3. Use Metadata Wisely

Structure your _metadata object to contain all the information needed for readonly decisions:

"_metadata": {
  "tableName": "my_table",
  "disableEditing": false,
  "canWrite": true,
  "isLocked": false,
  "isArchived": false
}

4. Test Criteria Expressions

Before deploying, test your criteria expressions with different data scenarios to ensure they work as expected.


Troubleshooting

Cell is not becoming readonly

  1. Verify config.readonly is false (grid-level must allow editing)
  2. Check if column.editable is true
  3. Verify your criteria syntax is correct
  4. Check that the field path in criteria matches your task data structure

Visual indication not showing

  1. Ensure enableSmartCellBackground: true is set on the column
  2. Verify the cell is actually readonly (criteria is matching)

Row context menu still appears for readonly rows

Use _metadata.disableRowContextMenu: true in addition to disableEditing:

"_metadata": {
  "disableEditing": true,
  "disableRowContextMenu": true
}

 

Thank you for the incredibly thorough response! This is exactly what I need!

RaviAmbati
ServiceNow Employee

@Reece Poulsen ^^^ documentation for making cells readonly. Hope this is useful.

Thank you @RaviAmbati and @Subhash Kumar for helping get this answer!