Retool

Documentation

Welcome to Retool! We're a fast way to build custom internal software.

You'll find the 5 minute demo, quickstart guide, and documentation for each of our connectors and components here. If you've got any questions -- chat with us on the bottom right!

Get Started    Guides

Text

Render Markdown text or HTML.

 
Property name
Description
Type

value

The value to render inside the text widget. By default, renders Markdown according to the CommonMark, but it can also render HTML.

string

html

Controls whether the value is rendered as Markdown or HTML.

boolean

Tip: Custom styles

You can also use it to render custom styles. Just enable HTML rendering, and paste in CSS in a <style> tag, as below. The .retool-canvas selector selects everything on the Retool canvas.

<style>
  .retool-canvas {
    font-family: Avenir;
  }
</style>

Table

Render tabular data.

 
Property name
Description
Type
Editable

data

The data for the array.

[{column1: value1}, ...] || { column1: [value1, ...], ... }

title

The title of the table.

string

selectedRow

The selected row.

object

selectedColumn

The selected column. Generally not used.

object

columnVisibility

Which columns are visible / hidden.

object

pageSize

The size of the page.

number

columnWidths

The width of the columns.

object

columnColors

The color of the columns.

object

Server side pagination

In many cases you only want to display one page of data at a time, but still require the ability to access the entire range of data. Tables supports server side pagination seamlessly. Here is an example of how to accomplish this.

Enable the 'Server side paginated?' checkbox and create two queries.

Enable the 'Server side paginated?' checkbox and create two queries.

The query.data is used to fetch the data, while the queryCount.data.count is a different query that retrieves the number of total results there are.

In this case, here is what the query for fetching the data might look like:

select * from customer where first_name ilike {{ '%' + textinput1.value + '%' }}
limit {{ table1.pageSize }}
offset {{ table1.paginationOffset }}

The important parts of this query is the last two lines - the limit and offset statement use values from the table in order to fetch the correct range of rows.

The query to count the total results would look like this:

select count(*) from customer where first_name ilike {{ '%' + textinput1.value + '%' }}

The key here being that the filter condition in both queries are identical so that the counted number of rows is accurate.

After setting it all up, your table will now automatically fetch the correct page of data whenever a user changes the selected page!

Server side pagination with dynamic column sorting.

In order to hook the Table's column sorting with server side paginated, you will need to utilize the sortedColumn and sortedDesc properties of the Table. Here is an example of how you could accomplish this.

select * from customer
order by

-- For each column you want to enable sorting by you must add the following two rows - including the ending comma.
case when {{ table1.sortedColumn == 'email' }} and {{ table1.sortedDesc }} then email end desc,
case when {{ table1.sortedColumn == 'email' }} and {{ !table1.sortedDesc }} then email end asc,

case when {{ table1.sortedColumn == 'first_name' }} and {{ table1.sortedDesc }} then email end desc,
case when {{ table1.sortedColumn == 'last_name' }} and {{ !table1.so }} then email end asc

limit {{ table1.pageSize}}
offset {{ table1.paginationOffset }}

While verbose, this is necessary because SQL queries are converted into parameterized queries safe from SQL injection.

Setting the data

Set the data in either row-based or column-based form.

Coloring columns

Select a column twice, and that'll expose the columnColor property for the selected column. You can write a JS function for the color - access the current cell's value with self:

{{ self === 'yes' ? 'green' : 'red'}}

Client-side sorting

Click on column to sort it. This works well enough for up to 10k rows, but after that, you want to be sorting in your query.

Action Buttons

To enable action buttons on every row in a table, check the "Add action button" checkbox. You will be able to customize the text on the button as well as which query is run when the button is pressed.

For now, queries that are run because of table actions will define a variable i, where row corresponding to the button clicked is the ith row.
For example, if the button in the 3rd row was clicked, the query run would have i = 3.

Container

Group components together.

 

Containers are the best way to organize your Retool page. Use them as top-level components, and nest other components (TextInputs, Buttons, etc.) inside of them. Aesthetically, containers improve layout; functionally, they let you move components together.

Property name
Description
Type

disabled

If a container is disabled, all the elements inside also become disabled. Useful for multi-step workflows: if you put each step in a container, you can disable the next step until the current step is completed.

boolean

TabbedContainer

A container with tabs that you can programmatically switch between.

 

TabbedContainers are like containers, except they have tabs, which can be programmatically selected. If you want to hide elements on a page if some_condition, the TabbedContainer is a great choice.

Property name
Description
Type

disabled

If a container is disabled, all the elements inside also become disabled. Useful for multi-step workflows: if you put each step in a container, you can disable the next step until the current step is completed.

boolean

numberOfTabs

The number of tabs.

integer

tabNames

The names of tabs.

[<string>]

selectedTab

Index of selected tab.

integer

selectTab()

Change the selected tab, programatically.

integer -> void

showTabBar

If false, then the user can't manually switch the tab. Good for hiding components!

boolean

Key Value Map

Render an object nicely.

 
Property name
Description
Type

data

An object to render the keys and values for.

object

keyTitle

Title of the key column.

string

valueTitle

Title of the value column.

string

Key value maps are often used to inspect the selectedRow of a table.

TextInput

Input text for use in Retool.

 
Property name
Description
Type

value

The value of the component.

string

placeholder

The placeholder when there's no value.

string

leftIconName

The left icon; choose from these.

string

TextInput is commonly used to modify the parameters of a query -- say the ILIKE in a SQL statement, or a URL parameter in a REST query.

ListView

Render a repeating list of views.

 

ListViews are good when you want something like a Table, but want to render specific components for each row. For example, ListViews can loop over all the users returned in a SQL statement, and each user can have a ban button - right in the ListView.

To get started, you set the number of instances in the ListView. Then just drag on some component (say, a Text) onto the ListView, and you'll see it repeat instances number of times. Inside each Text component, you can access the index with the variable i. So if you just set the value of the Text to be {{i.toString()}}, you'll get something like this:

Rendering a `ListView` of instance size `5`. A `Text` was dragged on to the `ListView`, so it repeats 5 times. The `value` of the `Text` is `<span ng-non-bindable>{{i.toString()}}</span>`.

Rendering a ListView of instance size 5. A Text was dragged on to the ListView, so it repeats 5 times. The value of the Text is {{i.toString()}}.

Property name
Description
Type

data

An array of objects, that represent the values of each component inside. So listview.data[2].text would be 2 in the example above.

[{componentName: value, ...}, ...]

instances

The "length" of the ListView.

integer

itemHeight

The height of each individual instance. A height of n has a pixel height of 35px * n.

number

Form

Group input components in to a form, so you can easily submit them together.

 
Property name
Description
Type

onSubmit

The query to run when the form is submitted.

query

submitButtonText

The text on the submit button.

string

submitButtonFullWidth

Whether or not the submit button should be full width.

boolean

disabled

Whether or not the form should be disabled.

boolean

loading

Whether or not the form should show a loading indicator.

boolean

Forms let you group inputs together, so you can submit them at once. To add inputs to a form, drag them on:

To update your database on form submission, change the onSubmit to be a query, and in the query, use the values of the inputs (e.g. {{textinput1.value}}):

Button

A button for running queries or exporting data.

 
Property name
Description
Type

value

The text to render on the Button.

string

color

The color of the Button, either as a string, hex, or rgba.

string

loading

Whether or not the button is loading. If loading, the Button has a spinner and is disabled.

boolean

buttonType

Either export or action. Export buttons export data; action buttons run queries.

string

exportQuery

If an export button, then the query to export (eg. users.data). The same as used by a Table.

[object] or object

exportFileType

If an export button, then the file type of the export. Currently just xlsx.

string

action

If an action button, then the name of the query to run (eg. onbutton1Click)

string

Buttons can be used in either to export data or run queries.

Export data

Currently, only Excel and CSV data exports are supported. To export data, change the "on click" to "export data", and the exportQuery to be the same object as the one fed in to the table (e.g. datasource1.data).

When clicked, the button will download the file. During development mode, you'll need to click the button twice: the first click selects the button, and the second click downloads the file.

Run queries

Buttons can also run arbitrary queries, such as API calls, or database insert statements. When creating the button, change the "on click" to "run a query", and create a new query if needed.

Queries can either be API queries, or database insert / update statements.

Open a Retool page

If you want to open another Retool page, you can pass in URL parameters:

Passing in URL parameters via a `Button`.

Passing in URL parameters via a Button.

Then, in the new page, you can use urlparams.company_id to access the company_id that was passed in.

Open a URL

You can also open a URL - and choose whether or not it opens in a new tab.

ButtonGroup

A group of buttons, for selecting between different options.

 
Property name
Description
Type

value

The selected value in the ButtonGroup. One of raw_values.

a

label

The label for the ButtonGroup.

string

values

The possible values for the ButtonGroup.

[a]

labels

The values to show to the end user.

[a]

defaultValue

The default value (should be one of the raw_values). This property can't be read from -- it's just the default value of value.

a

Button groups are similar to the Dropdown, or RadioGroup -- they let you choose between different options. The display_values are the values that are actually displayed in the button groups; the raw_values are the actual values outputted by the ButtonGroup (ie. buttonGroup1.value).

Warning: `raw_values` and `display_values` must be valid JSON.

If they're not valid JSON, our parser will crash. We'll add dirty JSON parsing in a later version of Retool.

(eg. ['a', 'b', 'c'] is invalid because JSON can't have unescaped single quotes)

RadioGroup

A group of radio buttons, for selecting one option out of many different options.

 
Property name
Description
Type

value

The selected value in the RadioGroup. One of raw_values.

a

label

The label for the RadioGroup.

string

values

The possible values for the RadioGroup.

[a]

labels

The values to show to the end user.

[a]

Similar to a ButtonGroup and Dropdown, but the options are rendered as radio buttons.

The display_values are the values that are actually displayed in the button groups; the raw_values are the actual values outputted by the RadioGroup (ie. radiogroup1.value).

Warning: `raw_values` and `display_values` must be valid JSON.

If they're not valid JSON, our parser will crash. We'll add dirty JSON parsing in a later version of Retool.

(eg. ['a', 'b', 'c'] is invalid because JSON can't have unescaped single quotes)

Checkbox

A single checkbox.

 
Property name
Description
Type

value

The value of the Checkbox.

boolean

label

The label for the Checkbox

string

CheckboxGroup

A group of checkboxes, for selecting arbitrary numbers of options.

 
Property name
Description
Type

value

The selected values in the CheckboxGroup. A subset of raw_values.

[a]

values

The possible values for the CheckboxGroup.

[a]

labels

The values to show to the end user.

[a]

Similar to a ButtonGroup, Dropdown, or RadioGroup but the options are rendered as checkboxes, and you can check arbitrary numbers of them.

The display_values are the values that are actually displayed in the button groups; the raw_values are the actual values outputted by the Dropdown (ie. dropdown1.value).

Warning: `raw_values` and `display_values` must be valid JSON.

If they're not valid JSON, our parser will crash. We'll add dirty JSON parsing in a later version of Retool.

(eg. ['a', 'b', 'c'] is invalid because JSON can't have unescaped single quotes)

BarChart

 

Render a repeating list of views.

Property name
Description
Type

value

The value of the component.

string

onChange

Fire a query when the value changes.

function

TODO

LineChart

 

Render a repeating list of views.

Property name
Description
Type

value

The value of the component.

string

onChange

Fire a query when the value changes.

function

TODO

PieChart

 

Render a repeating list of views.

Property name
Description
Type

value

The value of the component.

string

onChange

Fire a query when the value changes.

function

TODO

Tableau

 

Render a repeating list of views.

Property name
Description
Type

value

The value of the component.

string

onChange

Fire a query when the value changes.

function

TODO

Statistic

A pre-built HTML view. Good for displaying a single statistic.

 
Property name
Description
Type

value

The value of the component.

string

Card

A pre-built HTML view. Good for organizing a header and a small paragraph.

 
Property name
Description
Type

value

The HTML value of the component.

string

Divider

A pre-built HTML view. Good for separating components.

 
Property name
Description
Type

value

The HTML value of the component.

string

S3Upload

Upload files to S3.

 
Property name
Description
Type

s3AccessKeyId

The S3 access key id.

string

s3SecretAccessKey

The S3 access key secret.

string

s3Region

The region of the S3 bucket. For example, us-west-1.

string

s3BucketName

The name of the S3 bucket. For example, test-bucket

string

s3ACL

The ACLs for the uploaded file. For example, private; see AWS docs for other canned ACLs.

string

To upload to S3, you need to make a S3 IAM user for Retool, as well as whitelist our domain in the S3 CORS settings.

Making a new S3 IAM user

Head over to IAM, make a new user, and call it retool-s3-uploader. Only enable "programmatic access".

Creating an IAM user and setting the access type.

Creating an IAM user and setting the access type.

Hit "next" to grant the account permissions. The easiest is granting it full S3 permissions, but if you want, you can further restrict the permissions. You'll need to create a new policy, then attach the policy to the new user.

Here's an example JSON IAM policy that works. You'll need to change the YOUR_STATEMENT_ID variable, as well as the YOUR_BUCKET_NAME_HERE variable. Keep both the YOUR_BUCKET_NAME_HERE/* and YOUR_BUCKET_NAME_HERE - they're both necessary!

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketAcl",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation",
                "s3:GetBucketLogging",
                "s3:GetBucketNotification",
                "s3:GetBucketPolicy",
                "s3:GetBucketWebsite",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:GetObjectVersion",
                "s3:GetObjectVersionAcl",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionAcl",
                "s3:PutObjectVersionTagging"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET_NAME",
                "arn:aws:s3:::BUCKET_NAME/*"
            ]
        }
    ]
}

Configuring CORS

Since we upload directly from your browser, you'll need to configure CORS. Open up the S3 bucket, click the Permissions tab, and then click CORS configuration, and paste in the following XML, which lets Retool upload directly in to your S3 bucket from the browser.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://*.tryretool.com</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
  <AllowedOrigin>*</AllowedOrigin>
  <AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>

That's it! you should be good to go.

Configuring CORS so you can upload from Retool.

Configuring CORS so you can upload from Retool.

EditableText

Edit text that already exists in your database.

 
Property name
Description
Type

value

The value of the component.

string

onChange

Fire a query when the value changes.

function

Different from the TextInput. EditableText is used to edit existing text, so the onChange fires a query whenever the value changes.

MultiSelect

A dropdown, for selecting one option out of many different options.

 
Property name
Description
Type

value

The selected values in the Dropdown. One of raw_values.

[a]

values

The possible values for the Dropdown.

[a]

labels

The values to show to the end user.

[a]

Similar to a CheckboxGroup, but you the options are rendered in a dropdown.

The display_values are the values that are actually displayed in the button groups; the raw_values are the actual values outputted by the MultiSelect (ie. multiselect1.value).

Warning: `raw_values` and `display_values` must be valid JSON.

If they're not valid JSON, our parser will crash. We'll add dirty JSON parsing in a later version of Retool.

(eg. ['a', 'b', 'c'] is invalid because JSON can't have unescaped single quotes)

Map

Visualize points on a map.

 
Property name
Description
Type

latitude

The latitude of the center of the Map.

string | float

longitude

The longitude of the center of the Map.

string | float

points

The points to plot on the Map.

[
 {
    longColumnName: <string|float>,
    latColumnName: <string| float>,
    ...,
  },
  ...
]

latitudeColumnName

The name of the column for latitudes, in points. In the example above, it's longColumnName.

string

longitudeColumnName

The name of the column for latitudes, in points. In the example above, it's lastColumnName.

string

visiblePoints

The points that are currently visible in the Map. Useful if you pan around on the map and use it to filter points.

[points]

pointValue

The text to show as the marker in the map. Try setting it to an emoji... perhaps that of a motorcycle? 🏍️

string

selectedPoint

The currently selected point on the Map. The value of this will be the same as the object passed in the points parameter.

point

Rendering points with a 🏍️ emoji.

Rendering points with a 🏍️ emoji.

FilePicker

Let the user pick files from their system.

 
Property name
Description
Type

label

The text to render on the Button.

string

onFilePick

The query to run after the user chooses a file to upload.

queryName

disabled

Disables this button dynamically based on other values on the page.

boolean

file

The file that was chosen by the user.

object

parsedValue

If the uploaded file ends with a .json or .csv filetype, Retool will attempt to automatically parse the value and provide it here.

object

This component is used for allowing the user to pick files from their filesystem. The two use cases are uploading a file to an API endpoint and parsing values from a file.

Once the file is picked, you can either upload the file to an API endpoint, or parse the file (as JSON or CSV).

Attaching the file to an API request

https://docs.tryretool.com/v2.1/docs/apis#section-uploading-files

Reading data from a file.

Retool will automatically attempt to parse files ending in .json or .csv. You will then be able to access the value using the syntax {{ filepicker1.parsedValue }} as you would any other property in Retool.

SQL (read)

A SQL query that reads data from a database.

 
Property name
Description
Type

query

The actual query being run, after the templating is run.

string

data

The result of the query, in column-based form.

{
  "columnName1": [column1Type],
   ...
}

isFetching

Whether the query is running, or not.`

boolean

Local Storage

 

Refer to it in Retool by using the global variable localStorage

Property Name
Description
Type

values

A key-value store with the data with all the

{}

setValue

A method that can be called in a Javascript Query to store values in local storage

(key: string, value: any)

Libraries

 

Anything between {{ }} is Javascript. We give you the following libraries:

Name
Docs
Version

lodash

4.17.4

uuid

Both v1 and v4; use uuid.v1() or uuid.v4()