Chapter 13 Tips and Tricks

While previous chapters on working with Shiny made use of external libraries and built packages that brought new functionalities previously not available in Shiny, one does not have to go to this length to take advantage of the learnings contained in those pages. Moreover, there are a few exciting things that have not yet been explored.

13.1 Shiny Events

There is a wee bit of documentation tucked away on the shiny website that contains a useful list of events that Shiny fires to notify the developer of interesting things that happen in the application. This includes events that are fired when outputs are being recalculated, when Shiny connects, when an element become visible, and more. To demonstrate how to use those events and how handy they can be, we will create a notification which appears to indicate that the server is busy running computations. This could be as fancy as ever, but for simplicity’s sake, we limit the demonstration to showing and hiding a gif.

First, we create the directories and necessary files, and to indicate the server is busy. We’ll be using a gif that is rather well-known in the R community. Note that we will be using some CSS, hence the style.css file.

Then we create an application that draws and redraws a plot at the click of a button. Note that we give the gif an id as we will need to be able to retrieve this element JavaScript-side (to dynamically show and hide it), and an id makes for an ideal selector.

The gif should only be visible when the server is busy, unlike now. Whether it is visible will be controlled in JavaScript, so this should be initialised as hidden using CSS. The following code hides the gif with visibility: hidden, and repositions it, floating on top of the rest of the content in the top right of the page, the z-index ensures the gif appears on top of other elements.

We can then use the Shiny events to dynamically show and hide the gif when the server is busy. Below we observe the event shiny:busy on the entire page (document) when the event is triggered the gif is retrieved using its id and then made visible by changing its CSS visibility property to visible.

We then need to hide the gif when the server goes from busy to idle, using the shiny:idle event we can change the visibility of the gif back to hidden.

The application will then display the gif when the server is busy running computations as in Figure 13.1.

Shiny with a busy indicator

FIGURE 13.1: Shiny with a busy indicator

13.2 Table Buttons

For instance, using what was learned previously, one can place buttons inside a Shiny table and observe server-side, which is clicked. With a basic application that only includes a table to which we ultimately want to add a column containing a button on each row. Here we achieve this by having each button set a different value (e.g., an id) to an input using shiny.setInputValue, but one could very well create different input names for each button.

Note that in the above we pass some parameters to datatable not all are necessary at the exception of escape, which is set to FALSE as we will ultimately place HTML code the table which should appear rendered rather than show said code as a string.

We start by creating the on-click functions as R character strings for each row of the mtcars dataset. This is the function that will be triggered when buttons are clicked. This should look familiar we use Shiny.setInputValue to define an input named click, which is set to a different value for every row of the table.

Next, we create the buttons for each row and set the JavaScript functions previously created as the onClick attributes. The JavaScript code passed to the onClick attribute will be executed every time the button is clicked.

We can then observe the click input and, to demonstrate, render it’s value in the UI, see Figure 13.2 below.

DT with custom inputs

FIGURE 13.2: DT with custom inputs

13.3 jQuery

The Shiny framework itself makes use of and thus imports the jQuery JavaScript library, a library that provides a convenient API to make many things easier, including animations.

As an example, we could use jQuery’s show, hide, or toggle functions to show or hide an HTML element at the press of a button.

Because jQuery is already imported, there is no need to do so, on the contrary, importing it again will impact load time and might clash with the pre-existing version. Below we create a Shiny application containing a message handler to toggle (show or hide element depending on its state) at the click of a button.

Note that jQuery takes a selector so one could very well use a class to hide and show multiple elements (with said class) at once.

This is something where, again, R is leveraged in order to make it easier on the Shiny developer, but it must be said that it suffers from some inefficiency: the message travels from the browser (button click) to the R server, where it is sent back to the browser and triggers toggle. It could indeed very well be rewritten in JavaScript entirely. This is, however, outside the scope of this book.