How to create a collapsible side container in Retool for filters, extra data, charts and more!

In this tutorial, we run through a Bold Tech favorite hack: collapsible side containers. Perfect for making extra space for filters, extra data, charts, and more!

How to create a collapsible side container in Retool for filters, extra data, charts and more!
💡
UPDATE: Retool has now released a native sidebar 'frame' that can be used in the same way - you can head to our Sidebar layouts UI guide to learn some of the best ways to use it.

When building internal tools screen real estate is incredibly valuable, and so it’s important to position components as dynamically as possible to optimize for user experience. Creating collapsible elements in your layout, which hide away when out of use, is a great way to avoid creating apps that spill down the page, causing users to scroll unnecessarily, wasting time, and leaving margins for error. 

Retool is great for automatically adjusting components across vertical space, (i.e. components move up if something collapses above) however, there is not yet any in-built functionality for space adjustments horizontally, such as to collapse a side container. ‍

Luckily for you, we have a great hack to do this yourself in just a few steps, using a temp state and hidden components, to create a hideable sidebar such as this one: 

retool app with collapsible side container
An example of collapsible elements within an internal application

This space is super useful for things such as advanced filters, extra charts or data, or extra actions that aren’t always needed. 

It’s good, right? We think so too - this is a Bold Tech favorite hack. This tutorial should only take you 15 minutes or so, so let’s jump in and get started!

Setting up your collapsible sidebar

For this example, we are going to use a simple table with data, where we want to add some more complex filters in a collapsible sidebar, which we’re tucking away to the left of our table. If you don’t already have an app you’re using for this tutorial, pull in a table component with some dummy data, like so:

table in retool
A simple table with data

This trick works by using two different table components and a container, which are alternately hidden and shown through the click of a button, which changes the value of a temp state. So for this full-width table we’ve just pulled in, let’s make sure to call the component ‘mainTable’ in the right-hand component inspector for clarity.‍

Next, set the mainTable to be hidden by typing ‘true’ in the ‘Hidden’ value box. 

hidden set to true in retool
Setting the component to be hidden by typing 'true' in the 'Hidden' value box

In its place, pull in a container and a button to the side, and another table component next to them. The button should sit above the hidden ‘main table’ so that it remains in place when the container is hidden and the layout adjusts.

table and side container
A container and a button positioned to the left and above of the main table

Make sure to name the new table to be something clear, such as ‘filterTable’, as this will be the table component that shows when the side container is expanded. Connect the data in this table to the same query as your mainTable.‍

Next, create the temp state by clicking ‘Create new’ under ‘Temporary State’ in the left-hand inspector. Set the initial value to ‘true’. Note, if you decide to use more than one collapsible element, you'll need to use something other than a boolean to define the state, such as 'main', 'filters' and 'details'.

temp state set to true as default
A temp state is created in the left hand inspector

When the button is clicked, this temp state will switch between true and false to determine the width of table component that is shown. The state will be true when the mainTable is used (full-width) and the sidebar is collapsed, and false when the filters are expanded and the smaller filterTable used.

‍Let’s add an event handler to the button to reverse the value of the temp state on click:

event handler setting temp state retool
An event handler reverses the value of the temp state

Again, if you are using different values than true/false for your temp state, you’ll need to write out a ternary clause to switch the values. 

Let’s also change the button text to reflect these changes, for better UI:

ternary switching button text in retool
An example on how to change button text for better UI

Now, when you click the button, the text should change along with the value of the temp state. 

For the final steps, we’ll make sure the container and filterTable both hide when the filters temp state is set to true: 

hidden table
hidden container

And set the mainTable to hide when the filters temp state is set to false: 

hidden table when temp state false
An example on how to set mainTable to hide when the filters temp state is set to false

Matching data across your duplicate tables

Now, we’re almost there, but not quite done yet, since for good UI we need to ensure the smoothest transitions between the two: matching the table sort, as well as the index of the selected row, and the selected page. We need to make sure that these match across both tables so that when you switch between views, the data stays fixed. 

To explain with an example: if you are using this layout for expanding read-only views in a side panel, you want to make sure that when the user selects a row in the full-width table view, this same selection populates to the smaller-width table when it opens too. 

To do this, you’ll need to set up a series of simple event handlers. 

‍For the selected row, add an event handler to each table that fires on selectedRow change. Set this to change the selectedRow index of the other to match, as below:

event handler setting selected row index

Make sure to do this in both tables (main and filter) inversely:

event handler setting selected row index

Next, set up the sort to match across both, by setting an event on ‘sort change’ to match the column and the order:

event handler setting sort by

And again, do the opposite in the other table:

event handler setting sort by

Finally, set the page to change as well, be the table.selectedPageIndex:

event handler setting selected page index

And, once more inversely:

event handler setting selected page index

You may also need to perform these actions if you are using table filters frequently, or selecting cells specifically: these can all be done in the same way using the event handlers. 

This trick can be used beyond just a container/table layout, even with three tables and collapsing elements on each side, but do be sure not to overcomplicate things, as all of these duplicate elements need to perform exactly the same actions and pull from the same queries. So, the more complex this component is, the harder to debug two different, overlapping components at the same time. 

Since everything needs to work exactly the same in both tables, it’s best to add this UI feature towards the end of your development process, as you’ll need to perform each change to the table component twice from then on. 


💥
At Bold Tech, we specialize in building great internal tools, fast. We are obsessed with building apps that make your teams happier and more productive. In our blog, you can learn all about how to build better business software for more satisfied employees, or get in touch to chat to us about what you're looking to build.

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to Bold Tech Blog.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.