Free cookie consent management tool by TermsFeed

Read-Only Grid Component

On This Page
SAIL Design System guidance available for Grids

Grids should help your users take action and make decisions. Check out the grids design guidance page to learn how to display your data in a structured, easy-to-scan layout to help your users find what they need.

About the read-only grid component

Accepts a set of data and displays it in a grid that supports searching, filtering, selecting, sorting, and paging. You can choose to display your data as text, links, images, rich text, buttons, tags, record actions, or progress bars. For example:

Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to closeimages/example_grid.png

To organize editable inputs in a tabular layout, use an editable grid.

See the Grid Tutorial to learn how to build a read-only grid with selection, conditional formatting, row filtering, and dynamically displaying content.

Where to use the read-only grid component

Use the read-only grid (a!gridField()) in the following components:

You cannot use the read-only grid (a!gridField()) in the following components:

  • a!sideBySideItem()
  • a!barOverlay()
  • a!columnOverlay()
  • a!fullOverlay()

Supported components

The following the read-only grid (a!gridField()) parameters support certain components:

The read-only grid (a!gridField()) does not use editable grid subcomponents like a!gridLayoutHeaderCell(), a!gridLayoutColumnConfig(), or a!gridRowLayout().

Parameters

a!gridField( label, labelPosition, instructions, helpTooltip, emptyGridMessage, data, columns, pageSize, initialSorts, secondarySorts, pagingSaveInto, selectable, selectionStyle, selectionValue, selectionSaveInto, selectionRequired, selectionRequiredMessage, disableRowSelectionWhen, validations, validationGroup, showWhen, spacing, height, borderStyle, shadeAlternateRows, rowHeader, accessibilityText, refreshAlways, refreshAfter, refreshInterval, refreshOnReferencedVarChange, refreshOnVarChange, userFilters, showSearchBox, showRefreshButton, showExportButton, recordActions, openActionsIn, actionsDisplay, actionsStyle, maxSelections, showSelectionCount, loadDataAsync, similarityScoreThreshold, pagingControls, showManageFiltersMenu, smartSearchType, searchFields )

Note:  Not all parameters are immediately available in design mode; some display only after enabling others. For example, after selecting Selectable, other selection-related parameters will be available.

Name Keyword Types Description

Label

label

Text

Text to display as the grid label.

Label Position

labelPosition

Text

Determines where the label appears. Valid values:

  • ABOVE (default) Displays the label above the component.
  • ADJACENT Displays the label to the left of the component.
  • COLLAPSED Hides the label. The label will still be read by screen readers; see accessibility considerations for more information.
  • JUSTIFIED Aligns the label alongside the component starting at the edge of the page.

Instructions

instructions

Text

Supplemental text about this grid.

Help Tooltip

helpTooltip

Text

Displays a help icon with the specified text as a tooltip. The tooltip displays a maximum of 500 characters. The help icon does not show when the label position is "COLLAPSED".

Empty Grid Message

emptyGridMessage

Text

Text to display in the grid when no data is available. Default is "No items available".

Data Source

data

recordType, List of Map and List of Dictionary, DataSubset, or PortalReportDataSubset

The data to display in the grid. Use a record type reference or a!recordData() to source your data from records and use data fabric functionality, such as user filters and export to Excel. For other cases, you can use a query, such as a!queryEntity() with pagingInfo set as fv!pagingInfo to have the grid automatically manage paging. The function a!queryRecordType(), a!queryProcessAnalytics(), a Data Subset, a list of Dictionary, or an array of data can also be used. When using a query that returns a DataSubset, you must pass the total count (fetchTotalCount: true on the query).

Columns

columns

List of a!gridColumn()

The columns to display in the grid, configured using a!gridColumn().

Rows to Display Per Page

pageSize

Number (Integer)

The maximum number of rows to display at a time. Default: 10

Initial Sorts

initialSorts

List of SortInfo

Sorts applied to the grid upon initial load only. Each sort is applied in the order listed. The first sort in the list will display an active-sort arrow indicator (either up or down for ascending or descending) in its corresponding grid column (if applicable).

Secondary Sorts

secondarySorts

List of SortInfo

Sorts applied to the grid after every user interaction. If the user activates a sort on a column, these sorts will be applied to the other columns in the order they're listed. For example, adding a secondary sort on Month will keep them in order when the user sorts on Year. Secondary sorts do not display an active-sort indicator.

Paging Save Into

pagingSaveInto

List of Save

One or more variables that are updated only when user invokes a paging action on the grid. You can reference the current paging of the grid using fv!pagingInfo.

Selectable

selectable

Boolean

Determines if grid rows are selectable. When selection style is "CHECKBOX" (default), the selection column is displayed. Default: false.

Selection Style

selectionStyle

Text

Determines the style when a row is selected. When viewed in Appian Mobile, the default “CHECKBOX” style is used. Valid values: "CHECKBOX" (default), "ROW_HIGHLIGHT", "CHECKBOX_SUBTLE_HIGHLIGHT", "SUBTLE_HIGHLIGHT".

Selection Value

selectionValue

Text Array or Integer Array

Identifiers of the rows that should appear as selected. Can be set to have rows be pre-selected for the user. Supported types: Text Array and Integer Array.

Save Selection To

selectionSaveInto

List of Save

One or more variables that are updated with the selected identifiers when the user changes selections. Use a!save() to save a modified or alternative value to a variable. You can reference the rows selected and deselected in the most recent user interaction (not all selected or deselected rows) using fv!selectedRows and fv!deselectedRows respectively.

Selection required

selectionRequired

Boolean

Determines if a selection is required to submit the form. Default: false.

Selection Required Message

selectionRequiredMessage

Text

Custom message to display when a selection is required and not provided.

Disable Row Selection

disableRowSelectionWhen

Boolean

Determines for each row if selection is disabled. The condition defined in this parameter is evaluated once for each row. Reference fields from the source using dot notation, such as fv!row.status, or the identifier of the row using fv!identifier. Grids that use record data must use the recordType! domain to reference a record field or related record field. For example, fv!row[recordType!Case.fields.caseName]. Default: false.

Validations

validations

List of Variant

Validation errors to display below the grid when the data is invalid, configured using a!validationMessage(). You can reference the current page of data using fv!currentPage.

Validation Group

validationGroup

Text

When present, the requiredness of the field is only evaluated when a button in the same validation group is pressed. The value for this parameter cannot contain spaces. For example, “validation group” is not a valid value. You need to add an underscore between words: “validation_group”. See the following recipes for more information:

Show When

showWhen

Boolean

Determines whether the component is displayed on the interface. When set to false, the component is hidden and is not evaluated. Default: true.

Spacing

spacing

Text

Determines the spacing within grid cells. Valid values: "STANDARD", "DENSE". Auto default: Uses "STANDARD" in browsers and "DENSE" in Appian Mobile.

Height

height

Text

Determines height of the grid. Valid values: "SHORT", "SHORT_PLUS", "MEDIUM", "MEDIUM_PLUS", "TALL", "TALL_PLUS", "EXTRA_TALL","AUTO" (default). All grid heights besides AUTO have fixed headers that will remain at the top of the grid when scrolling.

Border Style

borderStyle

Text

Determines the grid border style. Valid values: "LIGHT" (default), "LIGHT_WITH_OUTER_BORDERS", "STANDARD". "LIGHT" displays row borders; "LIGHT_WITH_OUTER_BORDERS" displays row and outer borders; "STANDARD" displays all borders.

Shade Alternate Rows

shadeAlternateRows

Boolean

Determines whether alternate rows are shaded. Default: false.

Row Header

rowHeader

Number (Integer)

Index of the column to be used as the row header. Screen readers will announce the value in each row header when navigating to other cells within that row. Used only for accessibility; produces no visible change.

Accessibility Text

accessibilityText

Text

Additional text to be announced by screen readers. Used only for accessibility; produces no visible change.

Refresh after each user interaction

refreshAlways

Boolean

When true, grid data will be refreshed after each user interaction and each interval refresh. Default: false.

Refresh after record action completes

refreshAfter

List of Text String

Refreshes grid data each time a specified action completes. Valid values: "RECORD_ACTION".

Refresh after an interval of time

refreshInterval

Number (Decimal)

How often grid data gets refreshed in minutes. When null, grid data will not be refreshed on an interval. Valid values: "0.5", "1, 2", "3", "4", "5", "10", "30", and "60".

Refresh after referenced variable changes

refreshOnReferencedVarChange

Boolean

When true, grid data will be refreshed each time the value of any variable referenced in the data parameter is updated. To refresh grid data when another variable that is not used in the data parameter changes, use refreshOnVarChange. Default: true.

Refresh after variable changes

refreshOnVarChange

Any Type

Refreshes grid data each time any of these specific variables change. This allows you to refresh the grid data when a variable that is not referenced in the data parameter is updated. You can define a single variable (e.g. refreshOnVarChange: local!var1) or a list of variables (e.g. refreshOnVarChange: {local!var1, local!var2}).

User Filters

userFilters

List of Variant

Displays user filters above the grid. This parameter only applies when a record type is used as the source in the data parameter. Reference user filters from the record type using the recordType! domain. For example, recordType!Case.filters.status. Changing this value removes existing user-saved filters.

Show search box

showSearchBox

Boolean

Determines if the search box is shown above the grid. This parameter only applies when a record type is used as the source in the data parameter. Changing this value resets existing user-saved filters. Default: true.

Show Refresh Button

showRefreshButton

Boolean

Determines if the grid should include a refresh button to manually refresh data. This parameter only applies when a record type is used as the source in the data parameter. Default: true.

Show Export to Excel Button

showExportButton

Boolean

Determines if grid data can be exported. This parameter only applies when a record type is used as the source in the data parameter. This parameter doesn't apply to Appian Mobile. Default: false.

Record Actions

recordActions

List of Variant

List of record action items to display above the grid, configured using a!recordActionItem(). If you use fv!identifier in the identifier parameter of a!recordActionItem(), you will also need to configure selection for the grid. This parameter only applies when a record type is used as the source in the data parameter.

Open Actions In

openActionsIn

Text

Determines how record actions should open to the user. Valid values: "DIALOG" (default), "NEW_TAB", "SAME_TAB".

Actions Display

actionsDisplay

Text

Determines which details are shown for record actions, regardless of style. Valid values: "LABEL_AND_ICON" (default), "LABEL", "ICON".

Actions Display

actionsStyle

Text

Determines how the list of actions should be displayed above the grid. Valid values: "TOOLBAR" (default), "TOOLBAR_PRIMARY". Learn more.

Maximum Selections

maxSelections

Number (Integer)

The maximum number of items the user can select. When the user selects the maximum number of items, row selection is disabled.

Show Selection Count

showSelectionCount

Text

Determines when the number of selected items displays below the grid. Valid values: "AUTO" (default), "ON", "OFF". "AUTO" displays the selection count if the value of the maxSelections parameter is greater than 1.

Load Grid Data in Background

loadDataAsync

Boolean

When a record type is used as the grid's data source, set this to true to load the grid data and filters independently from the rest of the interface. To asynchronously load data that is used in other components as well, instead of setting this to true, use a!asyncVariable to define a local variable and use the local variable in the data parameter. See Asynchronous Loading for more information. Default: false.

Similarity Score Threshold

similarityScoreThreshold

Number (Decimal)

Determines the minimum match quality for semantic search results. Default: 1. Only use this parameter with semantic search. Decrease this value to return a broader range of semantic matches. When this parameter is null, a threshold of 0 is applied. For most use cases, maintain the default value and use smartSearchType to select the search method. Available only when showSearchBox is true.

Paging Controls

pagingControls

Text

Determines if the paging includes the total row count. Only applies when the source is a record type. “STANDARD” may improve performance because it doesn’t query the total row count. “ROW_COUNT” displays the total count and start/end controls; recommended for small datasets. Valid values: “STANDARD” (default), “ROW_COUNT”.

Show Manage Filters menu

showManageFiltersMenu

Boolean

Determines if the Manage Filters menu displays above the grid. The menu only displays if the search box or user filters are visible. This parameter only applies when a record type is used as the source in the data parameter. Default: true.

Smart Search Type

smartSearchType

Text

Determines the smart search method applied to the grid's search box. This parameter is only available when the showSearchBox parameter is true. When configured, the selected search method is applied in addition to keyword search. When null, the search type is determined by the similarityScoreThreshold parameter. Valid values: "SEMANTIC", "LEXICAL". Default: null.

Search Fields

searchFields

List of Variant

Determines the fields that are available in the grid's search box. This parameter is only available when the showSearchBox parameter is true. Reference a list of record fields using the recordType! domain. When null, the search fields configured on the record list is applied. If no search fields are configured on the record list, then all text and number (integer) fields displayed in the grid are searched.

Using the read-only grid component

The following sections cover important details about the read-only grid component.

Choosing the source of the grid

The fastest way to configure a read-only grid is from design mode. When you drag and drop the component into the live view and go to the Data tab of the Component Configuration pane, you can select one of the following options as the grid's data source:

Data Source Action
Record type Select a record type to use as the source. Grids that use a record type as the source are referred to as a records-powered grids.

When you select a record type as the data source, the grid will populate with the record list configured on the record type. You can also reuse other elements from the record type.
Query Create an a!queryEntity() expression from the query editor and use the resulting query as the source.
Variable Select a rule input or local variable as the source.
Rule Select an expression rule to use as the source.
Expression Write an expression directly in the component to use as the source.

Using records-powered grids

When a record type is used as the data source for your read-only grid, Appian automatically generates grid columns based on the columns configured for the record list.

Consider the following when configuring a records-powered grid.

Using records-powered grids in a portal

When you use a records-powered grid in a portal, there are a few things to keep in mind:

  • Some record components don't work in portals: Certain record components, such as record links and record actions, are incompatible with portals. When you create a read-only grid using a record type, it may automatically use these components, so be sure to remove the incompatible components before publishing your portal.
  • Users can't save their filters in a portal: The record list search, refresh button, export to Excel, and user filters will all function in a portal. However, users can't save their filters in a portal since they aren't signed in. The Manage filters button is replaced with a Clear Filters button in a published portal.
  • Asynchronous loading is not compatible with portals.

Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to closefilters in read only grid filters

See Working with Data in Portals for more information about using records as the source for read-only grids in portals.

Specify which fields to query and when

By default, a grid will query and display all the data specified in the columns, pagingSaveInto, and selectionSaveInto parameters. This default behavior can potentially impact performance if your grid includes dynamic behavior since it may result in querying more data than necessary.

For example, let's say you configured the showWhen parameter on the columns in your grid so that certain columns only appear to managers. Even when columns are hidden from the grid, those fields will still be queried since they're specified in the columns parameter of the grid.

To alter this default behavior, you can specify when the grid should query the fields in your columns using the fields parameter in a!recordData(). Learn more about using the fields parameter in a!recordData().

If your record type has relationships configured, you can also reference related record fields in your grid.

If you reference a related record field from a one-to-many relationship as a column in the grid, the maximum number of related records returned for each base record is 100.

To filter, limit, and sort the related record set returned from the one-to-many relationship, you can leverage the relatedRecordData parameter in a!recordData().

Avoid using relationship references to display related one-to-many data. Instead, you should only reference the specific related record field you want to display. This avoids querying more data than necessary, which can impact the grid's performance and export behavior.

For example, to display a list of cases associated with each customer, you should use the related record field reference recordType!Customer.relationships.cases.fields.title in the grid column. You should not use the relationship reference recordType!Customer.relationships.cases.

Use records-specific components

You can use the following components on any records-powered grid:

Changes that affect user-saved filters

The following changes to parameters in a records-powered grid remove existing user-saved filters:

  • A user filter is added or removed from the grid's userFilters parameter.
  • The showSearchBox parameter value is changed.

For more information about user-saved filters, including record type changes that affect saved values, see User-saved filters.

Export data to Excel

When set to true, the showExportButton parameter allows users to export the grid data to Microsoft Excel. By default, any columns visible in the grid will export to Excel. You can specify which columns are exported by configuring the exportWhen parameter on individual grid columns.

The showExportButton parameter only applies to records-powered grids. If your grid doesn't use a record type as the source, you can use the Export Data Store Entity to Excel smart service to create a custom export button that exports your grid data to Excel.

Users should only export grid data from applications and sites. You should not export grid data from an interface in Appian Designer.

Review how much data can be exported from the grid, and how certain display elements are exported to Excel.

Display record actions

The recordActions parameter allows you to display record actions, like related actions or record list actions, on the grid. You can display actions from different record types.

See the record action component and the record action item component for other details to consider when adding record actions to a grid.

Style record actions

You can then use the actionsStyle parameter to determine whether all actions display as with standard styling, or if the first record action displays as a primary button style. Appian recommends using the "TOOLBAR_PRIMARY" option when you want the first action, typically the most common action, to stand out.

When actionsStyles is set to "TOOLBAR", the buttons display like this:

Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to closeimages/grid-toolbar-standard.png

When actionsStyles is set to "TOOLBAR_PRIMARY", the buttons display like this:

Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to closeimages/grid-toolbar-primary.png

Toolbar item positioning

The position of toolbar items in a records-powered grid, such as search, refresh, export, manage filters menu, and record actions, isn't configurable. These items always display in their default positions.

Record action security

Each action specified in the recordActions parameter has security that is checked to ensure only the right users can see the right actions. In most cases where you use security rules, Appian evaluates the security for the entire grid before it is shown to the user. Because security rules are verified in bulk, the overall grid loading time will be shorter than if security expressions are used.

Note:  If you use a!localVariables() inside an a!recordActionItem(), Appian cannot perform a bulk security evaluation, so the grid may load slower than expected. Whenever possible, create local variables outside a!recordActionItem().

Row limit for records-powered components

Interface components that use a record type as the data source are known as records-powered components.

Records-powered components can display a maximum of 5,000 rows. As a best practice, you should not display all 5,000 rows in a component since it may impact performance.

Query timeout for records-powered components

Queries to synced and unsynced record types will timeout after 65 seconds. If you are querying large volumes of data, this may cause the interface or expression to error.

To resolve timeout errors, reduce the amount of data in your query by:

  • Reducing the batch size.
  • Limiting the number of fields returned.
  • Applying more specific filters.

Some complex queries may result in reduced performance. Ensure you're following query best practices.

Using the showManageFiltersMenu parameter

Setting the showManageFiltersMenu parameter to false hides the Manage Filters menu. Users can still access their existing user-saved filters, but they cannot save new filters or manage existing ones while the menu is hidden.

Use a!queryRecordType() as a data source

You can use a!queryRecordType() as the data source for your grid when you need manual control over paging or want to retain the user's current page after a data refresh. However, grids that use a!queryRecordType() are not considered records-powered and won't have access to features like user filters, search, and export to Excel.

Because a!queryRecordType() returns a Map rather than a DataSubset, you must construct a DataSubset from the query results using a!dataSubset().

The following example shows how to query record data with a!queryRecordType() and pass the results to the grid as a properly constructed DataSubset:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
a!localVariables(
  local!pagingInfo: a!pagingInfo(
    startIndex: 1,
    batchSize: 10
  ),
  local!queryResult: a!queryRecordType(
    recordType: recordType!Case,
    fields: {
      recordType!Case.fields.id,
      recordType!Case.fields.title,
      recordType!Case.fields.status
    },
    pagingInfo: local!pagingInfo,
    fetchTotalCount: true
  ),
  a!gridField(
    label: "Cases",
    data: a!dataSubset(
      data: local!queryResult.data,
      startIndex: local!queryResult.startIndex,
      batchSize: local!queryResult.batchSize,
      sort: local!queryResult.sort,
      totalCount: local!queryResult.totalCount
    ),
    columns: {
      a!gridColumn(
        label: "Title",
        value: fv!row[recordType!Case.fields.title]
      ),
      a!gridColumn(
        label: "Status",
        value: fv!row[recordType!Case.fields.status]
      )
    },
    pageSize: 10
  )
)

To enable paging controls, set fetchTotalCount: true in the query. To let the grid manage page navigation, pass fv!pagingInfo to the pagingInfo parameter of a!queryRecordType().

Note:  Do not use todatasubset() to convert the query results. The todatasubset() function nests the data an additional level down instead of mapping the fields directly. Always use a!dataSubset() to construct the DataSubset from a!queryRecordType() results.

Async loading considerations

Asynchronous (async) loading can provide a better user experience. When you configure a grid to load asynchronously, a placeholder will display in the grid's place, enabling users to interact with other parts of the interface while the grid's data loads in the background.

Using loadDataAsync vs a!asyncVariable()

There are two ways to enable async loading in a read-only grid:

  • Using the loadDataAsync parameter: When you use a record type as the grid's data source, you can set the loadDataAsync parameter to true.
  • Use an async local variable for the data parameter using the a!asyncVariable() function: If the grid's data is reused elsewhere in the interface, use a!asyncVariable() to create an async variable instead.

See Asynchronous Loading for detailed guidance on how async loading works and when to use it.

Note:  While you can use the loadDataAsync parameter when you are using a query function in the data parameter, we don't recommend it. Instead, use an async local variable for reused data or a record type for grid-only data.

Offline and portal considerations

In offline mobile and portal interfaces, read-only grids that are configured to load asynchronously will load with the rest of the interface, instead of loading in the background.

Async loading placeholder

If the grid data uses async loading, a placeholder will be displayed for the entire grid until the async data is finished loading.

For grids with one or two columns that load slowly, you can wrap the column's value parameter in a rich text display component to display a placeholder for the column while the rest of the grid loads normally. The data for the column must be queried separately in an async local variable and be used directly in the read-only grid column component. See Async column example for an example expression.

See a!asyncVariable() for more information on how the placeholder behavior works.

async-loading-grid-column

Configuring grid display

  • If the value for a column is empty or null, the grid still renders the column with just the label.
  • Grid column header styling, such as background color or font size, isn't configurable.
  • To display multiple components side by side in a single grid cell, use a!sideBySideLayout() in the value parameter of a!gridColumn(). See Display multiple components in a grid cell for details.
  • For accessibility purposes, every grid should have a row header configured. The first column containing text is usually the correct choice for row header. See the SAIL Design System for more information.

Choosing a selection style

When the selectable parameter is set to true, you can choose one of the following styles for the grid:

  • "CHECKBOX": (Default style) Displays a selection column.
  • "CHECKBOX_SUBTLE_HIGHLIGHT": Displays a selection column and applies a light blue highlight to the selected row.
  • "SUBTLE_HIGHLIGHT": Applies a light blue highlight to the selected row without a selection column.
  • "ROW_HIGHLIGHT": Applies a solid blue highlight to the selected row without a selection column.

When choosing your selection style, consider the following:

  • The "SUBTLE_HIGHLIGHT" and "ROW_HIGHLIGHT" styles provide no visual feedback if you disable selection using the disableRowSelectionWhen parameter.
  • On Appian Mobile, the grid always uses the "CHECKBOX" style, regardless of the value set for this parameter.

See the Grid with Selection Pattern for an example.

Configuring grid paging

To ensure a smooth user experience and optimal performance, consider the following when configuring grid paging:

  • Performance and Paging Controls: By default, the grid does not display the total row count or paging controls to jump to the first or last page. This improves performance because the grid does not need to query the total number of records. To display the total count, set the pagingControl parameter to "ROW_COUNT".
  • Dynamic Paging Adjustment: To reduce clutter, the grid automatically hides certain paging controls based on the data volume:
    • Paging controls are hidden if all rows fit on a single page.
    • First and last page jump controls are hidden if the grid has fewer than 3 pages.
  • Fetch Total Count Requirement: When providing a query in the data parameter (either directly, or indirectly from a rule reference), the query must return the total count (fetchTotalCount: true).
  • Manual Paging Constraints: If you are managing your own paging, you can't use a paging configuration with a batch size of -1 in your datasubset.
  • Sorting with Composite Keys: If a records-powered grid uses a record type with a composite primary key, you'll need to configure a sort based on a single field.
  • Offline Limitations: Paging and sorting are disabled when a grid is used offline, and images will not render.

Grid height and column width

  • Mobile Considerations: Grid heights behave as a fixed height on web but a maximum height on mobile.

  • Auto column width: When you set a column width to "AUTO", each column's width is determined by the length of the longest value in that column. For more information on using and choosing column widths, see the read-only grid column component and Column Widths.

Design mode guidance

Note:  This guidance does not apply to grids that use a record type as the data source. See Configuring the Read-Only Grid to learn how to configure a records-powered grid in design mode.

The following guidance applies when configuring a read-only grid in design mode:

  • Generated columns:
    • When you populate the data parameter from design mode and let the grid manage the paging, the grid will automatically generate an initial set of columns in the order they appear.
    • Grid columns are not automatically generated when you select VARIABLE as the data source and use a local variable to power the read-only grid.
    • The initial values for automatically-generated columns are:

      Parameter Value Description
      label fv!row.<fieldname> The field name is converted to title case. If the field name is in camel case, it will be split and converted to title case. If the field name is too long, it will be truncated with ellipses (...).
      value fv!row.<fieldname> The field value to display.
      sortField <fieldname> The field name of the primary key.
      align "END" or fixed() The alignment depends on the field's data type. If the data type for the column value is numerical or date-based, then it will set align : "END". If the data type for the column value is a decimal, then it will be wrapped in the fixed() function to two decimal places. Ex. value: fixed(fv!row.cost, 2).
  • Updating columns:
    • After initial columns have been generated, the grid will automatically update with new columns to match any new fields added to the data source.
    • However, automatic updates do not occur when the data source is an RULE or EXPRESSION. To update the columns displayed in the grid, you must update the data source, and add or remove the columns manually.
  • Selecting QUERY as the data source:
    • If you select QUERY as the data source, you'll use the query editor to configure the query that powers your grid.
    • Appian will automatically use the following query values in your grid:
      • The query's batchSize will be the value of the grid's pageSize parameter.
      • The query's sortInfo will be used as the grid's initialSort parameter.
  • Batch size limitation:
    • The grid cannot use a query that has a paging info with a batch size of -1 in design mode.

By default, when the showSearchBox parameter is true, the search box in a read-only grid uses a keyword search to find exact and partial matches to a user's search terms. You can implement smart search in the default search box to apply semantic search or lexical search in addition to keyword search.

When smart search is implemented on the default search box, both keyword search and the selected smart search type are applied. Each search type targets different fields and returns different similarity scores:

  • Semantic search applies to any Text field, Extra Long Text field, or document that is enabled for smart search and displayed as a column in the grid or specified in the searchFields parameter. Semantic search matches return a similarityScore less than 1.
  • Lexical search applies to any Text field, Extra Long Text field, or document that is enabled for smart search and displayed as a column in the grid or specified in the searchFields parameter. Lexical search matches return a similarityScore greater than 1.
  • Keyword search always applies to searchable field types (Text, Number, User, or Group) displayed in the grid or specified in the searchFields parameter. Keyword search matches return a similarityScore of 1.

If you want to customize the grid's search box and its styling, you must build a custom search box. To build a custom search box that uses smart search, use one or more a!queryFilter() expressions in a!recordData() instead of the grid's search parameters. For full implementation details and steps, see Use smart search in a custom search box.

Note:  Before implementing smart search in a grid, you must first enable fields for smart search and ensure the record type's indexing status is Completed.

In the default search box of a read-only grid, you can apply semantic search or lexical search on top of keyword search. Compare the search methods to determine which search method is best for your use case.

To configure smart search in the default search box:

  1. In a read-only grid, ensure the showSearchBox parameter is true.

  2. Configure the smartSearchType and similarityScoreThreshold parameters to set your preferred smart search type:
    • Semantic search: Set smartSearchType to "SEMANTIC" and similarityScoreThreshold to a value less than 1. See Using the similarityScoreThreshold parameter for guidance on choosing a threshold value.
    • Lexical search: Set smartSearchType to "LEXICAL". Keep the default similarityScoreThreshold value of 1.

    Tip:  See How smartSearchType and similarityScoreThreshold interact for all parameter combinations and their resulting search behavior.

  3. Add columns to the grid for each field enabled for smart search. If you need to search on documents or Extra Long Text fields, use the searchFields parameter to specify all fields to search on.

  4. In the initialSorts parameter, sort by the primary similarity score in descending order so the most relevant results appear first. Add a secondary sort to determine the order when the search box is empty.

How smartSearchType and similarityScoreThreshold interact

The smartSearchType and similarityScoreThreshold parameters together determine what search types are applied in the default search box.

Use the following table as a reference when configuring your grid:

smartSearchType similarityScoreThreshold Search behavior
null 1 (default) Keyword search only.
null Less than 1 Keyword search and semantic search. Only semantic matches at or above the threshold are returned.
"SEMANTIC" 1 (default) Keyword search only. Semantic search scores are almost always less than 1, so the threshold excludes all semantic matches.
"SEMANTIC" Less than 1 Keyword search and semantic search. Only semantic matches at or above the threshold are returned.
"SEMANTIC" null Keyword search and semantic search. When similarityScoreThreshold is null, a threshold of 0 is applied.
"LEXICAL" null Keyword search and lexical search. The threshold does not affect results because lexical and keyword scores are 1 or greater.
"LEXICAL" 1 (default) Keyword search and lexical search. The threshold does not affect results because lexical and keyword scores are 1 or greater.
"LEXICAL" Less than 1 Keyword search and lexical search. The threshold does not affect results because lexical and keyword scores are 1 or greater.

Using the similarityScoreThreshold parameter

The similarityScoreThreshold parameter controls how closely search results must match the search term to be returned in the grid. This parameter is only available when the showSearchBox parameter is true.

By default, the similarityScoreThreshold parameter is set to 1, which limits the search box to traditional keyword search only. You should only modify this value if you're using semantic search on the grid.

Note:  Do not use the similarityScoreThreshold parameter when the smartSearchType is "LEXICAL". Because lexical scores are unbounded and do not have a standard scale, filtering by a specific similarity score may lead to inconsistent results.

The threshold you choose depends on your specific data set. What qualifies as a strong or weak match is variable, but generally:

  • Higher values (closer to 1) set a stricter similarity requirement, returning fewer and more relevant results.
  • Lower values (closer to 0) set a broader requirement, returning more results with a wider range of relevance.

When the similarityScoreThreshold parameter is null, a threshold of 0 is applied. If you specify a smartSearchType and similarityScoreThreshold is null, then keyword search and the specified smart search type are applied with no threshold.

Using the searchFields parameter

The searchFields parameter allows you to specify which record fields are searched in a grid. These search fields apply across all search types—keyword search, semantic search, and lexical search. The searchFields parameter is only available when the showSearchBox parameter is set to true.

Use the searchFields parameter when you want to:

  • Search over unsupported field types: Extra Long Text fields can't display as columns in a read-only grid. Use the searchFields parameter to search these fields without displaying them in the grid.
  • Tailor search for a specific grid: The customized record list search configuration applies to all grids that use the same record type. Use searchFields to customize which fields a particular grid searches without affecting other grids.
  • Improve search performance: Limit the search to only the fields that are relevant to the grid's purpose, rather than searching all columns.
Supported field types

The searchFields parameter accepts record fields of the following types:

To search on documents and Extra Long Text fields, you must configure the smartSearchType parameter. If smartSearchType is null and similarityScoreThreshold is 1, document and Extra Long Text fields are not valid in searchFields since a keyword search is only applied.

Sort by similarity score

You can sort a read-only grid by similarity score to show the most relevant search matches first.

When you sort by similarity score, you must also configure a secondary sort. The secondary sort determines the grid's order when a user has not entered a search term, which means the similarity score is null.

To sort the grid by the highest similarity score:

  1. In the initialSorts parameter of the read-only grid, define an array {} containing two a!sortInfo() functions.
  2. In the first a!sortInfo() function, configure the following:
    • For field, enter recordType!<Record Type Name>.searchResults.allSearchFields.similarityScore. This will sort by the primary similarity score.
    • For ascending, enter false. This will sort from highest to lowest similarity score, placing more relevant results first in the list.
  3. In the second a!sortInfo() function, choose a field to sort by when the grid first loads or when the search box is empty.

    For example:

1
2
3
4
5
6
7
8
9
10
11
12
  initialSorts: {
    /* Sorts by similarity score in descending order if there is a search */
    a!sortInfo(
      field: recordType!SSTA Case.searchResults.allSearchFields.similarityScore,
      ascending: false()
    ),
    /* Defaults to sorting by id field when there is no search */
    a!sortInfo(
     field: recordType!SSTA Case.fields.id,
     ascending: true
    )
  },
  • Search persistence:
    • Smart search and keyword search apply to their respective fields even if the columns are hidden in the grid (via the showWhen parameter) or if the fields are only referenced in the searchFields parameter and not displayed as columns.
  • Performance:
    • Search time increases as the number of rows and searchable fields grows. To improve performance, limit the number of fields enabled for smart search, or use the searchFields parameter to restrict which fields are searched in the grid.
  • Sorting and filtering:
    • In the initialSorts parameter, add a sort on the similarity score to show the most relevant results first by default.
    • Add a secondary sort to determine how to sort the grid when the search box is empty.
    • Use recordType!<Record Type Name>.searchResults.allSearchFields.similarityScore whenever possible to sort and filter since it will use the primary similarity score.
    • Only use recordType!<Record Type Name>.searchResults.<Field Name>.similarityScore to sort or filter by a similarity score for a specific field if your use case requires it.

Examples

The following example demonstrates the read-only grid component. The examples reference record types from another environment and will error if you try to use them in yours. Use them as a reference only.

Use async loading

This example shows how to use async loading for a specific column while the rest of the grid loads normally.

In the following expression, the status column uses an async local variable to query data separately and displays a placeholder until the data loads.

read-only-grid-async-example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
a!localVariables(
  local!statusId: a!asyncVariable(
    a!queryRecordType(
      recordType: recordType!IT Task,
      fields: {
        recordType!IT Task.fields.statusId
      },
      pagingInfo: a!pagingInfo(startIndex: 1, batchSize: 10)
    ).data
  ),
  {
    a!gridField(
      label: "Record List",
      data: recordType!IT Task,
      columns: {
        a!gridColumn(
          label: "Tasks",
          value: fv!row[recordType!IT Task.fields.task]
        ),
        a!gridColumn(
          label: "Grid Column",
          value: a!richTextDisplayField(
            value: {
              a!match(
                value: index(
                  local!statusId,
                  fv!identifier,
                  recordType!IT Task.fields.statusId,
                  null
                ),
                equals: 1,
                then: {
                  a!richTextIcon(icon: "circle-o-notch", color: "SECONDARY"),
                  " Not Started"
                },
                equals: 2,
                then: {
                  a!richTextIcon(icon: "spinner", color: "ACCENT"),
                  " In Progress"
                },
                equals: 3,
                then: {
                  a!richTextIcon(icon: "check-circle", color: "POSITIVE"),
                  " Done"
                },
                default: "-"
              )
            }
          )
        )
      }
    )
  }
)

This example shows how to apply semantic search to a grid using the default search box.

In the following expression, the grid searches on the support case title (shown as a column in the grid) and the case description (an extra long text field not displayed in the grid).

read-only-grid-async-example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
{
  a!gridField(
    label: "Support Cases",
    labelPosition: "ABOVE",
    data: recordType!RE Case,
    showRefreshButton: true,
    /* Enables default search box */
    showSearchBox: true,
    /* Specifies the fields to search on */
    searchFields: {
      recordType!RE Case.fields.title,
      recordType!RE Case.fields.description
    },
    /* Sets the type of smart search to apply */
    smartSearchType: "SEMANTIC",
    /* This similarity score range is for example purposes only */
    /* The similarity scores you choose will depend on your data and search criteria */
    similarityScoreThreshold: 0.4,
    columns: {
      a!gridColumn(
        label: "Title",
        value: a!defaultValue(
          fv!row[recordType!RE Case.fields.title],
          "–"
        ),
        sortField: recordType!RE Case.fields.title
      ),
      a!gridColumn(
        label: "Status",
        value: if(
          isnull(
            fv!row[recordType!RE Case.fields.isOpen]
          ),
          "–",
          a!richTextDisplayField(
            value: if(
              fv!row[recordType!RE Case.fields.isOpen],
              a!richTextIcon(
                icon: "pencil",
                altText: "In progress",
                color: "SECONDARY"
              ),
              a!richTextIcon(
                icon: "check",
                altText: "Closed",
                color: "#138901"
              )
            )
          )
        ),
        sortField: recordType!RE Case.fields.isOpen,
        align: "CENTER"
      ),
      a!gridColumn(
        label: "Created On",
        value: if(
          isnull(
            fv!row[recordType!RE Case.fields.createdOn]
          ),
          fv!row[recordType!RE Case.fields.createdOn],
          datetext(
            fv!row[recordType!RE Case.fields.createdOn],
            "default"
          )
        ),
        sortField: recordType!RE Case.fields.createdOn,
        align: "END"
      ),
      a!gridColumn(
        label: "Modified On",
        value: if(
          isnull(
            fv!row[recordType!RE Case.fields.modifiedOn]
          ),
          fv!row[recordType!RE Case.fields.modifiedOn],
          datetext(
            fv!row[recordType!RE Case.fields.modifiedOn],
            "default"
          )
        ),
        sortField: recordType!RE Case.fields.modifiedOn,
        align: "END"
      )
    },
    initialSorts: {
    /* Sorts by similarity score in descending order if applicable */
      a!sortInfo(
        field: recordType!RE Case.searchResults.allSearchFields.similarityScore,
        ascending: false
      ),
      a!sortInfo(
        field: recordType!RE Case.fields.title,
        ascending: true
      )
    },
    refreshAfter: "RECORD_ACTION",
  )
}

See the Display Semantic Search Match Quality in a Read-Only Grid recipe to learn how to display a column in a read-only grid that illustrates if the semantic search results are strong, moderate, fair, or weak.

Image next to text in a grid column

The following example shows how to display a user image next to their name in a single grid column using a!sideBySideLayout().

Note:  These examples reference record types and fields from another environment and will error if you try to use them in yours. Use the examples as a reference only.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
a!gridField(
  label: "Employees",
  data: recordType!Employee,
  columns: {
    a!gridColumn(
      label: "Employee",
      sortField: recordType!Employee.fields.name,
      value: a!sideBySideLayout(
        items: {
          a!sideBySideItem(
            width: "MINIMIZE",
            item: a!imageField(
              images: a!userImage(user: fv!row[recordType!Employee.fields.username]),
            )
          ),
          a!sideBySideItem(
            item: a!richTextDisplayField(
              value: a!richTextItem(
                text: fv!row[recordType!Employee.fields.name],
                style: "STRONG"
              )
            )
          )
        }
      )
    ),
    a!gridColumn(
      label: "Department",
      sortField: recordType!Employee.fields.department,
      value: fv!row[recordType!Employee.fields.department]
    )
  }
)

Plain text in a side by side item

Plain text strings aren't compatible with a!sideBySideItem(). To display text alongside another component, wrap it in a!richTextDisplayField().

The following expression shows the correct way to combine text with a tag:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
a!gridField(
  label: "Employees",
  data: recordType!Employee,
  columns: {
    a!gridColumn(
      label: "Employee",
      sortField: recordType!Employee.fields.name,
      value: a!sideBySideLayout(
        items: {
          a!sideBySideItem(
            width: "MINIMIZE",
            item: a!imageField(
              images: a!userImage(user: fv!row[recordType!Employee.fields.username]),
            )
          ),
          a!sideBySideItem(
            item: a!richTextDisplayField(
              value: fv!row[recordType!Employee.fields.name]
            )
          )
        }
      )
    ),
    a!gridColumn(
      label: "Department",
      sortField: recordType!Employee.fields.department,
      value: fv!row[recordType!Employee.fields.department]
    )
  }
)

Feature compatibility

The table below lists this component's compatibility with various features in Appian.
Feature Compatibility Note
Portals Compatible
Offline Interfaces Compatible
Sync-Time Custom Record Fields Incompatible
Real-Time Custom Record Fields Incompatible

Custom record fields that evaluate in real time must be configured using one or more Custom Field functions.

Process Reports Incompatible

Cannot be used to configure a process report.

Process Events Incompatible

Cannot be used to configure a process event node, such as a start event or timer event.

Process Autoscaling Incompatible

Cannot be used in autoscaled processes.

Event Consumer Filter Conditions Compatible

Can be used in filter conditions.

Event Consumer Event Handlers Compatible

Can be used in event handler expressions.

Old versions

There are older versions of this interface component. You can identify older versions by looking at the name to see if there is a version suffix. If you are using an old version, be sure to refer to the corresponding documentation from the list below.

Old Versions Reason for Update
a!gridField_19r1

Now supports embedded queries, columns widths, and rich text.

a!gridField_23r3

Enhanced read-only grids that use a record type as the source so they only query the record fields specified in the columns, pagingSaveInto, and selectionSaveInto parameters. This allows for more optimal grid performance. Additionally, if your grid includes dynamic behavior, you can configure the fields parameter in a!recordData() to specify when to query fields in the grid.

a!gridField_24r3

Enhanced records-powered grids so they can automatically detect if fields have been queried from a different relationship and skip any redundant queries. Additionally, updated the grid's default border style and shading.

a!gridField_25r2

Enhanced records-powered grids so the relatedRecordData parameter can accept a limit of up to 100 related records.

For more on what's changed, see New version details.

a!gridField_25r3

Evolved to support a simplified similarity score range for smart search.

For more on what's changed, see New version details.

a!gridField_26r2

To improve performance, the grid no longer displays the total row count by default. Use the pagingControl parameter if you need to display the total row count.

To learn more about how Appian handles this kind of versioning, see the Function and Component Versions page.

The following recipes include usage of the Read-Only Grid Component.

Feedback