3MW (Inserting JavaScript into {reactable})

Guten Tag!

Many greetings from Munich, Germany. Last week, we made our Quarto dashboards a little bit more interactive. This week, we want to continue on that path by making sure that our tables react to inputs from checkboxes.

This requires a little bit of JavaScript that we combine with the {reactable} package. A good primer on how that works can be found in my newest YT video where I show you how to add dropdown menus to {reactable} tables. You can check it out on YT:

And once you understand how that works, you’ll realize that making our checkbox thing happen is quite similar. So with that said, let’s dive into this week’s issue.

Like every week, the code that you see in the code chunks can be found on GitHub. For this week’s issue there’s also the Repo of the live version of this dashboard.

Where we´re headed

So last week I mentioned that we want to get a functionality that looks like this.

Basically, we want to add the checkbox functionality to our existing {reactable} code. If you recall, here’s how that looks.

Adding checkboxes

First, let us do the easy thing. Let’s create the checkboxes. You can do that with {htmltools}.

This code will generate the checkboxes but it doesn’t include any interactive features yet. As you can see in the YT video, we can use the onchange argument to make that happen. But this is what we can only do at the end of the two steps that come before that. And unfortunately some of these steps require small JavaScript snippets 😭 

Let me go over these three steps broadly so that you know the big picture and then we’ll implement this one step at a time. Don’t be alarmed if the steps don’t mean anything to you yet. You ready for the three steps? Okay, here they are:

  1. Define an ID for your table.

  2. Set the filter method of the Species column.

  3. Modify the onchange argument of the checkboxes so that they set the filter value of the Species column (so that our new filter method can take care of these values)

Set an ID

Okay this is the nice part. All you have to do is to give to give our table an ID so that we can reference to it in our filter method. Just set elementId = ‘tbl’ inside of your reactable() call.

Set a filter method

The next part is a little bit tricky. We will have to write a JavaScript function that can take an array of species names and check which values in the species column are included in that list.

Due to the way that {reactable} is set up, this requires a function that depends on the rows, columnId and filterValue. Have a look how that could look in our code and then I’ll explain.

Here this function first checks whether the filterValue has zero length. If so it will just return all rows as is. But if not, it will filter the rows. These rows get filtered via an unnamed function that returns TRUE/FALSE for each row in rows.

This function is defined via the `(row) => {}` syntax. In R, that would be equivalent to `\(row) {}` or `function(row) {}`. And inside this unnamed function, the code checks whether the array filterValue includes the values from a row’s column.

Set a filter value

So now that we have a function that can take an array as input for filterValue, we can make sure that the filterValue of the Species column gets set when the checkboxes change. More specifically, what needs to happen onchange is:

  1. Checkboxes are selected

  2. Values of the checked checkboxes are extracted and put into an array

  3. filterValue of our table is set to the newly created array

And the way this works in JavaScript is as follows:

  1. Use document.querySelectorAll() with CSS keywords to find the checkboxes on the page. Here’s where we use the fact that we used name=checkboxes in tags$input().

  2. Create an array from all those checkboxes, filter for those that are checked and then extract the values from those checkboxes.

  3. Use reactable.setFilter() to set the filterValue of the Species column in the table with ID tbl to that new array.

In our code that sets up the checkboxes, that looks as follows:

And then we get the desired output 🥳 

Nice with that we have concluded this week’s newsletter. I hope the JavaScript wasn’t too hard. I tried to break it down as much as possible.

Also, I’m actually thinking about making a “WebDev for R” series on YT. The goal is to make this into a good resource for the WebDev-adjacent things we have to to in R when we want to create dashboards or use some of our other cool tools. 

Let me know what you think about this idea. You can even ask for specific topics. And as always, if you want to reach out to me, just reply to this mail or find me on LinkedIn.

See you next week,
Albert 👋

Enjoyed this newsletter and found something helpful? Here are other ways I can help you:

Join the conversation

or to participate.