Build tables

Learn how to display and interact with data using the Table component.

Tables are a common way to view and interact with your data. You can sort, filter, paginate, and download rows of information. Tables also support row selection and insertion, server-side pagination, and custom columns.

Demo

Try out the app to see tables in action (edits are disabled).

Load data in a table

When you drag a Table component to the Canvas, it automatically displays data from one of your queries. If you don't have any queries, Retool initially populates the table with test data in JSON format. You can change the data displayed in a table by editing the Data property. From the dropdown, you can select a query, use JavaScript (e.g., queryName.data), or input an array.

Selecting a query as the data source for a table

Change column types

When you add tables to the Canvas, Retool tries to infer the column types. You can also set column types manually by clicking the column in the Inspect tab, and selecting the type from the Format dropdown.

Set a primary key

Retool recommends setting a primary key column to uniquely identify each row of data. If your data already has an an ID column, Retool automatically uses it for the primary key. You can also manually set it to any column that is guaranteed to be unique.

If you don't want to show the primary key column in your table, select the column and set its Hidden property to true.
Changing a column's type

Set source keys

You can set an optional source key on each column to pull data from your data source. For example, you could set the source ID to populate the table column with data from the data source's ID column.

Editable table columns

After populating a table with data, you can make columns editable and change cell values. To make a column editable, select the table to open Inspect tab in the right panel. Select ••• next to the column, then Make editable, or select the column and click the Editable checkbox.

Making a column editable

Double-click a cell to edit its value. When you edit cells, changes are saved in the table's changesetArray property. This tracks the changes but it doesn't update the underlying data source that your query connects to. To save edits back to your data source, you must write a query to update your data. For example, saving changes to a PostgreSQL database can be done using a bulk update query.

After creating the bulk update query, you need to connect it to the table. Open the Inspect tab again for the table and scroll to the Add-ons section. Add a Save actions add-on. Select the add-on, and then add an event handler that runs the bulk update query.

Adding a save action to run a query

Add new data to tables

You can add rows to tables and save the changes as new data. To do this, drag in a Form component and click Generate from. This opens a modal where you can select the table you previously dragged onto the Canvas:

Generating a form for adding new rows to a table

Have the form trigger an update query to add a new record.

Dynamic values in new rows

You can use dynamic values if you have columns you don't want users to edit, or if you want to automate some of the values added in a new row. These values are generated when the row is added, and don't require manual input from the user. For example, if your table has a timestamp column, you can use {{ moment() }} to generate the timestamp when the query runs.

Any {{ }} values can be used while creating new rows in a table

Automatically reload table data

If you want to automatically reload table data when changes are saved, add an event handler to the query that updates your data source. Configure the event handler so that when the query succeeds, it runs the query that populates your table.

Adding an event handler to refresh table data

Custom columns

You can add custom columns to tables using the + button in the Inspect tab above the list of columns. Custom columns are often used to calculate data based on other values in your Retool app. For example, if you have a monthlyIncome column and you want to calculate a yearlyIncome column, you could use {{ currentSourceRow.monthlyIncome * 12 }}.

Adding a custom column

Custom columns have the same properties as regular table columns.

Configure actions

You can add actions that are displayed as buttons when hovering over a row in a Table. For example, to open a Modal upon clicking an action button, drag a Modal component to the Canvas. Select the Table component and in the Inspect tab, click the + in the Actions section. Then configure the an event handler for the action to open the modal.

Configuring an action to open the modal component

Now when the button is clicked in the table, the modal opens.

Sort, filter, and customize data presentation

Tables come with prebuilt functionality for sorting and filtering data. You can click on a column to sort it, and you can combine a table with a Text Input component to create a search field that serves as another way of filtering data.

Show and hide columns

When you click a column in the Inspect tab, there's a Hidden property that you can set to true or conditionally control with JavaScript.

Row selection

Single row selection is enabled by default, but tables also support multiple row selection, or you can disable it completely. Selecting multiple rows is often useful when your app needs to make bulk actions. Navigate to the Interaction > Row selection section of the Inspect tab to change these settings.

Pagination

In the Inspect tab, you can choose between Pagination and Scroll options for handling overflow items.

You can also enable server-side pagination. You write queries that include parameters to define a subset of data to retrieve, server-side. Retool recommends this when working with large datasets to reduce the amount of data your table uses, which can help your app's performance.

Sorting of tables using server-side pagination must be done on the server. You can write queries that use the table's sort or sortObject properties to achieve this.

Table search

To enable search for a table, drag a Text Input component to the Canvas. Next, click on the Table component and navigate to the Interaction section in the Inspect tab. Set the Search term property to {{ textInput1.value }} (the name of the Text Input component might be different in your app) to connect the Text Input component to the table. This enables search across all the table's columns, and Retool provides options for fuzzy, exact, and case insensitive searches.

Row selection persistence

Some applications need to track the table's selected rows even while the user is filtering, sorting, or paginating through data. You can enable this in the Interaction section by selecting the Persist row selection checkbox.

Common table variables

currentSourceRow, item, and i are commonly used with tables. item and i work with other components, but they have unique meanings when used with table column settings. With tables, i is the index of the current row in the original dataset, and item is the value of the current cell.

Variables like currentRow and item are useful in situations where you want to access values in a table and then calculate a new value. For example, {{ item * 10 }} takes the current cell and multiplies it by ten. You can also do something like {{self + ' ' + '(Last sale: + currentSourceRow.last_sale)'}} to combine two values and map them to a column.

i is often used to iterate over a set of values and perform some kind of action. For example, you can iterate over each row in a table and update values, make API requests, send emails, etc. For example, this JavaScript transformer iterates over all rows in table1, and returns each sales person with over 200 sales.

var salesPerson = {{ table1.data }};
var highSales = salesPerson.filter(i => i.sales > 200);
return highSales;

See the Table component reference documentation for more information on properties, events, and JavaScript methods that you can use with tables.