Event Handlers

Event handlers allow you to trigger queries, control components, and more in response to user interactions. Anything you can do with Retool’s JS API (e.g. query1.trigger(), modal.open(), utils.showNotification(...)) you can do with event handlers.

Think of a Retool event handler just like addEventListener in native JS or onChange in React. Any component that can respond to a user action or input will have an Events section in the Inspector. For example, Button has a click event, Text Input has change, focus and blur events, and Form has submit and invalid events.

You can add multiple event handlers in response to an event. For example, when a user clicks a Button, you can (1) trigger a query to run and (2) reset the state of multiple Dropdowns and Text Inputs–all without writing custom JS.

Trigger queries

You can run any Resource or JavaScript query in response to an event. Create additional event handlers to run multiple queries.

📘

Event handlers are always run in parallel. To chain queries, use the Success or Failure triggers in the query editor (bottom panel).

Control components

Before event handlers, the only way to control components was to write a JavaScript query. Now, you can control components via event handlers.

Every component API is exposed in event handlers. Select the Control component action, select a component, and choose an API method. For example, you can quickly create a Button that sets multiple inputs to their defaults via the .setValue(...) API.

Navigate

With the Go to app action and automatic client-side routing, you can easily connect a multi-page app. You can also navigate to any URL with the Go to URL action.

For example, here we open a “Support” app with a user pre-selected from a separate “Users” app all via a Button’s click handler.

Set temporary state

Temporary state allows you to store any data, just like a global variable in native JS. Create and update temporary state directly from event handlers with the Set temporary state action.

You can also view and create temporary state from the model browser (left-hand side panel)You can also view and create temporary state from the model browser (left-hand side panel)

You can also view and create temporary state from the model browser (left-hand side panel)

Export data

You can export data from your queries or other sources to CSV, JSON, TSV, or Excel via the Export data action. You can also copy any text to the clipboard via the Copy to clipboard action.

For example, you can create a Button that exports a row in a table to a CSV file and copies it to your clipboard.

Fire confetti

Perhaps most important of all, when a user action is cause for celebration, the Confetti action is right at your fingertips 🎉.

Conditional runs

Only run when

Configure your event handlers to only run when a given condition evaluates to true. Use Retool’s {{ ... }} to evaluate any JavaScript condition, including references to other components and queries ( e.g. {{ checkbox1.value }} , {{ toggle1.value && query1.data.length > 0 }}).

For example, you can build a Form that either (1) edits an existing user if one is selected or (2) creates a new user–all via event handlers. First, create 2 event handlers to run on Submit. The first will be a Trigger query action that runs editUser only when you have an existing user ID {{ !!id }}. The second will be a Trigger query action that runs createNewUser only when there is no row selected, and therefore ID is falsey {{ !id}}.

Debounce and throttle

Debounce delays the action until the specified milliseconds have elapsed since the event was last triggered. Let's say you want to run a query when the user changes their search text in a search bar (e.g. a TextInput). If the underlying query is expensive, you don't want to fire it on every keystroke. Instead, you should run the query only when the user stops typing–that's a great candidate for debounce.

Throttle will only call the action once per the specified milliseconds. Let’s say the refreshUserData query is an expensive one, so we throttle it to run at most every 2 seconds, even if the user clicks the Button much more frequently.


Did this page help you?