JavaScript Events in Shiny

A number of JavaScript events are supported in Shiny as of version 0.13.0. These events can be used to keep track of the app’s progress, or even manipulate the values of inputs/outputs.
Author

Yihui Xie

Published

September 4, 2015

A number of JavaScript events are supported in Shiny as of version 0.13.0. These events can be used to keep track of the app’s progress, or even manipulate the values of inputs/outputs. All event names have the prefix shiny:, e.g., shiny:connected. We can listen to these events using jQuery’s .on() method, e.g.,

$(document).on('shiny:connected', function(event) {
  alert('Connected to the server');
});

When an event is triggered in Shiny, the event object may have some additional properties that can be used to query or modify the information in Shiny, as we will see later in this document. Some events can cancel the process in Shiny, e.g., stop the propagation of an input or output change to the server. Such events include shiny:inputchanged, shiny:message, shiny:value, shiny:error, shiny:updateinput. To cancel the Shiny process, you can use event.preventDefault(), e.g.,

// no outputs will be updated since we canceled the output changes
$(document).on('shiny:value', function(event) {
  event.preventDefault();
});

All events currently supported in Shiny are listed below. Here’s a live example (source).

Initial Connection, Session Initialization and Disconnection

The events shiny:connected and shiny:disconnected are triggered when an initial connection to server is established, and when a session is ended or the connection is lost for some reason, respectively.

You can think of the shiny:connected event as firing the moment that you connect to Shiny. However, if you want to listen for an event that signals when you want to interact with the session object, you should use shiny:sessioninitialized. This event is only fired after the session object (the optional third argument in the Shiny server function) is fully initialized and queryable. These two events should happen almost immediately one after the other.

As of Shiny 1.9.0, instead of using the shiny:sessioninitialized event, we recommend using the Shiny JS object’s initializedPromise property. This is a Promise-like object that can be awaited or chained with .then().

The Shiny.initializedPromise object is resolved when the shiny:sessioninitialized event is triggered. In most cases the Promise is easier to use than shiny:sessioninitialized because with shiny:sessioninitialized, you may need one path if your code is called before the session has been initialized (and the shiny:sessioninitialized is yet to be triggered), and another path if your code is called after the session has been initialized (and the shiny:sessioninitialized will not be triggered again).

With Shiny.initializedPromise, it can be used both before and after the events have occurred; there is no need for a separate code path if the code called before vs. after the shiny:sessioninitialized event. Example usage:

{% highlight javascript %} Shiny.initializedPromise.then(() => { // Code to run }); {% endhighlight %}

For shiny:connected and shiny:disconnected, the event object has a socket property, which is used to store the web socket that is used to communicate between R and JavaScript. For example, you may query the state of the web socket via event.socket.readyState. The shiny:sessioninitialized event doesn’t have any special Shiny properties.

Server Status: Busy/Idle

The event shiny:busy is triggered when something is happening on the server (e.g. an observer is running), and the event shiny:idle indicates when the server is idle. The event object does not carry any special properties related to Shiny.

By the first time that shiny:idle is triggered, both shiny:connected and shiny:sessioninitialized have already fired (by that order).

Messages

The shiny:message is triggered when any messages are received from the server. The event has a property message, which is the message object (a JavaScript object).

Conditional Panels

When conditional panels (see ?shiny::conditionalPanel) are updated, the event shiny:conditional is triggered on the document.

Binding/Unbinding Inputs/Outputs

All the events above are triggered on the whole document. There are a few events triggered on specific HTML elements, including the events in the following sections on input and output elements.

When an input or output is bound to Shiny, the event shiny:bound is triggered. Similarly, there is a shiny:unbound event after an input/output is unbound. In these events, the event object has properties binding (the input/output binding object) and bindingType (may be 'input' or 'output' depending on whether the binding is for an input or an output).

Output Events

The shiny:value event is triggered when an output receives a value from the server. The event object has three properties: name (output id), value (output value), and binding (output binding).

The shiny:outputinvalidated event is triggered when an output’s value is invalidated on the server. The event object has two properties: name (output id), and binding (output binding).

The shiny:error event is triggered when an error is propagated to an output. The event also has three properties like the shiny:value event: name, error (the error message), and binding.

The shiny:recalculating and shiny:recalculated events are triggered before and after an output value is recalculated, respectively. Please note shiny:recalculated is triggered after the output value has been recalculated in R, but that does not imply the output value has been displayed on the page. Use shiny:value instead if you want to do something when the output value is rendered.

To recap, suppose you have an output x which takes a reactive dependency on y (this could be an input or another reactive object). When y changes, the first thing that happens is that x is invalidated (and the shiny:outputinvalidated event for x is fired). The shiny:recalculating event is the next one to be fired for x. This may happen either immediately after the previous event, or it can take a while, depending on whether or not there are other previously invalidated objects also waiting to be recalculated. Once the value of x has finished recalculating, its shiny:recalculated event is fired. The last event to be fired for x is shiny:value (or shiny:error if the recalculation resulted in an error).

The shiny:visualchange event is triggered when an output is resized, hidden, or shown. The event object has properties visible (true or false) and binding (the output binding).

Since these events are triggered specifically on an output element, you may add the listener on the output element instead of on the document, although the latter also works, e.g.

$('#foo').on('shiny:value', function(event) {
  // append a character string to the output value
  event.value += ' Oh that is nice!';
});

// use event.target to obtain the output element
$(document).on('shiny:value', function(event) {
  // cancel the output of the element with id 'foo'
  if (event.target.id === 'foo') {
    event.preventDefault();
  }
});

Input Events

The event shiny:inputchanged is triggered when an input possibly has a new value, e.g., when you click an action button, or type in a text input. The event object has properties name (the id of the input), value (the value of the input), inputType (the type of the input, e.g. shiny.action), binding (the input binding object), and el (the DOM element for the input). The reason that it can be triggered when the input possibly has a new value is because, in some cases, keyboard or mouse events can trigger shiny:inputchanged even when the value has not actually changed.

For example, suppose you have a numeric input with id foo, you may double its value through this event:

$(document).on('shiny:inputchanged', function(event) {
  if (event.name === 'foo') {
    event.value *= 2;
  }
});

The shiny:updateinput event is triggered when an input is updated from the server, e.g., when you call updateTextInput() in R to update the label or value of a text input. The event object has properties message (the update message sent from the server) and binding (the input binding).

Summary

Here is a summary of the events. The ones that are cancelable can also be modified by users, e.g., you can change event.value in the shiny:inputchanged event, and the new event.value will be used as the input value (to be passed to R).

Name Event Properties Cancelable Target
shiny:connected socket No document
shiny:disconnected socket No document
shiny:sessioninitialized No document
shiny:busy No document
shiny:idle No document
shiny:inputchanged name, value, inputType, binding, el Yes input element
shiny:message message Yes document
shiny:conditional No document
shiny:bound binding, bindingType No input/output element
shiny:unbound binding, bindingType No input/output element
shiny:value name, value, binding Yes output element
shiny:error name, error, binding Yes output element
shiny:outputinvalidated name, binding No output element
shiny:recalculating No output element
shiny:recalculated No output element
shiny:visualchange visible, binding No output element
shiny:updateinput message, binding Yes input element
shiny:filedownload name, href No download button/link