Skip to main content


This page explains how to use a Table widget to display data in tabular format, trigger actions based on user interaction, and work with paginated data sets of any size.

Using the Table Widget

Display data

To display data in a Table widget, you can use the Table Data property.

The data should be specified as an array of objects, where each object in the array represents a row, and the properties of the object represent the columns in the table. In the given example format, the table has three columns: step, task, and status.

"step": "#1",
"task": "Drop a table",
"status": "approved"
"step": "#2",
"task": "Create a query fetch_users with the Mock DB",
"status": "pending"
"step": "#3",
"task": "Bind the query using =>",
"status": "pending"

You can dynamically generate table by fetching data from queries or JS functions by binding the response to the Table Data property.

Example 1: suppose you have data stored in a database and you want to display it in the Table widget.

  1. Fetch data from the sample database users using a SELECT query fetchData to retrieve the data.
  1. In the Table's Table Data property, display the data using:

Example 2: if the data retrieved from the query is not in the desired format, you can use JavaScript to transform it before passing it to the Table widget.

  1. Fetch data from the sample API users using the following URL:
  1. Use JavaScript to transform the data by adding it to the Table Data property.
{{ => {
return {

This code is using the map() function to extract specific data, such as the name,and email, from the fetchApi query.

Server-side pagination

Appsmith can handle query responses of up to 5 MB. To display large datasets and optimise performance, use server-side pagination. It can be implemented using Offset-based pagination or Cursor-based pagination:

Offset-based pagination works by using the page number and size to calculate the offset of records to fetch from a database or API.

  1. Fetch data from the sample database users using pageSize and pageOffset reference properties to implement pagination.

     SELECT * FROM users LIMIT {{ Table1.pageSize }} OFFSET {{ Table1.pageOffset }}; 

    In an API query, the page number can be passed as a query parameter to retrieve the corresponding subset of data, as shown in the example URL:{{Table1.pageNo}}
  2. Enable the Server-side pagination property in the table.

  3. Set the table widget's onPageChange event to run the query.

  4. To provide the user with information about the number of records in the table, you can configure the Total records property to be displayed in the table header. Create a new Query, and add:


You can use {{[0].count}} COUNT query to display the count. Additionally, you can use the total record count to enable or disable the next/previous controls.

Display images on table row selection
Offset-based pagination

Server-side searching

Server-side searching is a technique of searching for specific records from the server using search terms, without relying on the client-side. To enable the search bar in the table header for server-side searching, you can turn on the Allow Searching property.

The searchText reference property can be used to filter records displayed in a table based on the user's search terms. When the user types into the search bar, the onSearchTextChange event of the table is triggered, which can be configured to query the table's datasource for the matching results.

To use the server-side search with the Table widget, follow these steps:

  1. Create a SQL query using the searchText reference property:

    SELECT * FROM users WHERE name LIKE {{"%" + Table1.searchText + "%"}} ORDER BY id LIMIT 10;

    You can also pass the searchText property as a URL parameter in an API request:{{Table1.searchText}}
  2. Set the table widget's onSearchTextChange event to run the query.

Watch this video to learn how to set up server-side search for the Table widget.

Server-side filtering

Server-side filtering involves using a value to narrow down the results of a query in a similar way to server-side searching. However, instead of searching for a specific term, the selected value is used to filter out unwanted data from the requested dataset.

To enable server-side filtering, you can use widgets such as the Select widget to provide users with a list of supported filters to choose from.

  1. Drag a Select widget to the canvas and add options that you might use to filter your data.

  2. Create a query, and add the Select widget's selectedOptionValue:

    As a SQL query:

    SELECT * FROM users WHERE gender = {{genderDropdown.selectedOptionValue}};

    As an API request with URL parameters:{{genderDropdown.selectedOptionValue}}
  3. Set the Select widget's onOptionChange event to run the query.

Edit table data

To edit and update table data directly from the UI, you can use Inline editing. To enable inline editing for a table, you can make individual columns editable by checking the Editable checkbox in the Columns section of the Table widget properties panel. Once inline editing is enabled, you can double-click on a cell to edit its contents.

Learn more about Inline editing.

Refresh table data

When changes are made to the datasource that supplies your table with data, the table won't automatically reflect these changes. Therefore, it is necessary to use events and/or write code that re-executes the query responsible for populating data into the table whenever new data is submitted to the datasource.

Example: For instance, suppose you have a table that receives its data from a query called getData, and you have a button that submits a form with new user input through a query called sendNewData.

  1. When the form is submitted via the button's onClick, it executes
    {{ }}
  2. On success, it executes as a callback to get the latest version of the dataset that includes the new changes:
    {{ =>, () => {}) }}

Now when sendNewData succeeds, your table automatically refreshes itself.


Properties allow you to edit the widget, connect it with other widgets and customize the user actions.

Widget properties

These properties allow you to edit the widget. All of these properties are present in the property pane of the widget.

PropertyData typeDescription
Table DataArray/ObjectUse this field to provide the data to be displayed in the table, either by writing an array of objects to display as table rows or by binding data from an API/Database using the mustache syntax, like {{<query_name>.data}}.
ColumnsArrayAutomatically populated from the Table Data. This lets you edit the column label, show/hide each column (with the eye icon), and also manage the individual column settings.
EditableBooleanA property that determines whether a field or cell can be modified by the user. Learn more about Inline editing.
Add a New ColumnButtonA button that allows users to insert a new column into an existing table.
Primary key columnStringAssigns a unique column which helps maintain selectedRows and triggeredRows based on value. Affects the performance of caching the dataset for quick loading and access.
Show PaginationBooleanToggles visibility for the page information and control buttons in the table header.
Server Side PaginationBooleanEnables you to implement pagination by limiting the number of results fetched per API / query request. Use this property when your table data is bound to an API / query.
Total RecordsNumberThis number value is displayed in the table header to inform the user of how many records exist in the table. This property is only visible when you enable Server Side Pagination.
Allow SearchingBooleanToggles visibility of the search bar in the table header.
Client Side SearchBooleanSets search behavior for the search bar in the table header. When turned on, the bar searches only the data currently loaded in the table. Otherwise, it searches the entire data set.
Default Search TextStringSets the default search query for the search bar in the table header.
Allow FilteringBooleanToggles visibility for the "Filters" button and its features in the table header.
Default Selected RowNumber/ArraySets which rows are selected in the table by default. When Enable multi-row selection is turned on, this setting expects an array of numbers corresponding to the indices of the selected rows. Otherwise, it expects a single number.
Enable multi-row selectionBooleanAllows multiple rows of a table to be selected at the same time. The rows are accessible by the {{ Table1.selectedRows }} property.
Column SortingBooleanToggles whether table columns are sort-able. When turned on, users may click column headers to sort the table rows by that column's value. This setting only applies while the app is in View mode.
VisibleBooleanControls the widget's visibility on the page. When turned off, the widget won't be visible when the app is published.
Animate LoadingBooleanWhen turned off, the widget loads without any skeletal animation. You can use a toggle switch to turn it on/off. You can also turn it off/on using JavaScript by enabling the JS label next to it.
Allow DownloadBooleanToggles visibility of the "Download" button in the table header. When turned on, users are able to download the table data as a .csv file or Microsoft Excel file.
Allow Column FreezeBooleanEnables freezing and unfreezing the columns via a dropdown in the columns' header cells.
CSV SeparatorStringSets the separator character to use for formatting the downloaded .csv file. Only applies when Allow Download is turned on. Default: ,

Reference properties

These properties can be referenced in other widgets, queries, or JS functions using the dot operator. For instance, you can use Table1.isVisible to get the visibility status.

Reference PropertyData typeDescription
selectedRowObjectContains the data of the row selected by the user. It's an empty object if no row is selected.
selectedRowsArrayContains an array of rows selected by the user when multi-select is enabled. It's [null] if no row is selected.
triggeredRowObjectWhen a user interacts with an actionable item (like button) in a row, triggeredRow fetches the data of that column.
isVisibleBooleanReflects whether the widget is visible or not.
sortOrderObjectReflects the current column sort criteria. For example, if table rows are being sorted by the value of column id in ascending order, this property contains {"column": "id", "order": "asc"}.
tableDataArrayContains all the table data in JSON format.
selectedRowIndexBooleanContains the index of the row selected by the user. Not applicable when multiple rows are selected.
selectedRowIndicesArrayContains an array of the index of the rows selected by the user. Not applicable when multi-row selection is turned off.
filteredTableDataBooleanContains the data of the rows left after applying any selected filters, sort rule, or search terms.
pageNoNumberContains the current page number that the user is on. APIs can use it for pagination.
pageOffsetNumberContains a calculated value to represent how many records to skip when using Server side pagination. Use this value in your query to fetch the correct set of results.
pageSizeNumberContains the number of rows that can fit inside a page of the table. Changes along with the height & row height of the table.
searchTextStringContains the search text entered by the user in the Table.
isAddRowInProgressBooleanIt indicates whether a new row is currently being added to the table.
newRowObjectContains data related to newly added row.
nextPageVisitedBooleanIndicates whether the next page of data has been visited by the user.
previousPageVisitedBooleanIndicates whether the previous page of data has been visited by the user.
tableHeadersArrayIndicates whether the table headers are visible.
totalRecordsCountNumberIndicates the number of pages in server-side pagination.
updatedRowObjectContains data related to recently updated added row.
updatedRowsArrayContains data related to updated rows.
triggeredRowIndexNumberAn index property that indicates the row index of the table that has been triggered.
updatedRowIndicesArrayRefers to an array of indices corresponding to the rows that have been updated

Style properties

Style properties allow you to change the look and feel of the widget. All of these properties are present in the property pane of the widget.

PropertyData typeDescription
Default Row HeightStringSets the height of the row in the table - short, default, or tall.
Text SizeStringSets the size of the text.
EmphasisStringSets a font style for text, such as bold or italic.
Text AlignStringSets how text is aligned horizontally within the cells.
Vertical AlignmentStringSets where the cell contents are vertically positioned within the cells.
Cell Background ColorStringSets the background color of the table cells.
Text ColorStringSets the color for the text in the table.
Cell BordersStringSets the border configuration for the table's cells. Default (all borders), horizontal borders only, or no borders.
Border RadiusStringSets rounded-ness for the widget's corners.
Box ShadowStringSets a shadow around the widget's edges.
Border ColorStringSets the color of the widget's borders.
Border WidthNumberSets the thickness of the widget's borders.


When the event is triggered, these event handlers can run queries, JS code, or other supported actions.

onRowSelectedSets the action to run when the user selects a row.
onPageChangeSets the action to run when the table's page changes.
onPageSizeChangeSets the action to run when the table's height is changed. This event can only be triggered by developers working on the app, not by end users. For example, it can be used to set a Limit in your query dynamically.
onSearchTextChangeSets the action to run when the user enters a search text.
onSortSets the action to run when the user sorts the data.