3MW (Writing JavaScript without actually knowing it)

Guten Tag!

Many greetings from Ulm, Germany.

Today, we'll learn how to spice up our Shiny apps with a little bit of JavaScript (JS). Fear not! This will be beginner friendly. I do not really know JS but still I manage to use it for small tasks.

A sample app

Let's have a look at a really basic dashboard built with {bs4Dash}. It contains three rearrange-able boxes that we can fill with texts (the same boxes that we talked about last week).

If you look at the code of this app, then you will notice that the boxes contain text area inputs with labels box_1, box_2 and box_3. Really creative, I know.

The point of the button is to collect all the texts. Normally, this would mean that after clicking the box, the server function of the app has to access input$box_1, input$box_2 and input$box_3 in that order.

But what happens if the boxes were shuffled? The labels of the boxes do not change but the order in which they have to be read does. This is where we have to use JS magic.

How do we begin with that? First, we look behind the HTML curtain. In your web browser, right-click on the box and press "Inspect". This will show you the box' HTML code.

Find specific elements

As you can see, what we're looking for seems to use tags. A quick web-search yields that a specific HTML tag can be found with document.getElementsByTagName(""). But how do we use this code?

To enter JS code, you have to switch to your web browser's console (ctrl+shift+K in Firefox). There, you can just try out any code that you find online until you get the results you want. Here are the results for our tag search.

The output that you see is an HTMLCollection of length 3. And the great thing is that it's always in the order of the boxes that you can see in the app. That's exactly what we need.

You can save the result in a variable using `var name = ...`. Once the data is saved, you can access the collection with [] (like in R). This will return a textarea object whose value you can get with .value.

Iterate to get all values

Now, we just have to repeat the same for all three boxes. Just like in R, we can use a for-loop to fill an empty array (think vector) step by step. What you need to know is that you can append new elements to an array by using .push() on the vector you're working on.

Make array accessible to R

Now we have all the texts in an array. Time to make the conversion from JS to R. Another quick web search reveals that we can use Shiny.setInputValue('texts', texts); for that. Once that code ran through, we can access all the texts in R with input$texts in our server function.

Thus, our JS code is complete.

Now we need to figure out how to execute this code whenever the button is clicked. That's our story for next week.

That's a wrap! As always, I'm happy to hear your feedback about this week's issue. Feel free to write me on Twitter or reply to this mail.

Enjoy the rest of your day!Albert

Did you like this post and want to support more content like this? Whenever you feel like it, you can support me with a coffee or a membership.

Need help visualizing your data? Or need to build a Shiny app? I'm open to freelance work. You can book a free 30-minute Zoom meeting with me and we can find out if I'm a good match for your project.

Reply

or to participate.