This article describes five patterns to use with Shiny’s action buttons and action links. Action buttons and action links are different from other Shiny widgets because they are intended to be used exclusively with
Create an action button with
actionButton() and an action link with
actionLink(). Each of these functions takes two arguments:
inputId- the ID of the button or link
label- the label to display in the button or link
actionButton("button", "An action button") actionLink("button", "An action link")
An action button appears as a button in your app.
An action link appears as a hyperlink, but behaves in the same way as an action button.
Like all widgets, action buttons have a value. The value is an integer that changes each time a user clicks the button. You can access this value from within your app as
<inputId> is the ID that you assigned to your action button.
Action buttons are different from other widgets because the value of an action button is almost never meaningful by itself. The value is designed to be observed by one of
eventReactive(). These functions monitor the value, and when it changes they run a block of code.
The patterns below explain this arrangement and illustrate the most popular ways to use an action button or an action link.
observeEvent() to trigger a command with an action button.
In the code above,
session$setCustomMessage() generates a popup message.
Action buttons do not automatically generate actions in Shiny. Like other widgets, action buttons maintain a state (a value). The state changes when a user clicks the button.
observeEvent() observes a reactive value, which is set in the first argument of
observeEvent(). Whenever the value changes,
observeEvent() will run its second argument, which should be a block of code surrounded in braces.
This pattern uses
observeEvent() to connect the change in an action button’s value to the code that the action button should trigger.
observeEvent() isolates the block of code in its second argument with
observeEvent() only notices changes in the value of the action button. It does not matter what the actual value of the button is. If your code depends on the value of the action button, it may be mis-written.
eventReactive() to delay reactions until a user clicks the action button.
eventReactive() creates a reactive expression that monitors a reactive value, which is set in the first argument of
eventReactive(). The expression will be invalidated whenever the value changes, but it will ignore changes in other reactive values.
Complete this pattern by using the reactive expression created by
eventReactive() in rendered output. Output that depends on the expression will not update until the expression is invalidated, i.e. until the action button is clicked.
eventReactive() isolates the block of code in its second argument with
NULL until the action button is clicked. As a result, the graph does not appear until the user asks for it by clicking “Go”.
To build several action buttons that control the same object, combine
observeEvent() calls with
reactiveValues() creates a reactive values object, a list of reactive values that you can update and call programmatically. These values are like the values stored in Shiny’s
input object with one difference: you can update the values of a reactive values object, but you cannot normally update the values of the
input object (those values are reserved for the user to update interactively).
To complete the pattern, monitor each button with its own
observeEvent() call. Arrange for the calls to update the object created by
reactiveValues(). Reactive values obey reference class semantics, which means that you can update them from within the scope of an
To create a reset button, use the above pattern to assign
NULL to a reactive values object.
You can apply the previous pattern to reset an element of a reactvie values object to its intial state (
NULL). To do this, arrange for a button to assign
NULL to the reactive values object with the help of
Observe the value of a
observeEvent() to rest the value of an object each time your user switches tabs.
This pattern extends the previous reset pattern. You use
observeEvent() to reset an element of a reactive values object. However, instead of observing the value of an action button, you observe the value of a tab function.
navbarPage() each combine multiple tabs (created with
tabPanel()) into a single ui object. These functions maintain a reactive value that contains the title of the current tab. When your user navigates to a new tab, this value changes.
observeEvent() resets the reactive value to
NULL when it does.
As with the patterns above, this pattern requires you to store and manipulate a value created with
tabsetPanel(), you can acheive the same effect with
Action buttons and action links are meant to be used with one of
eventReactive(). You can extend the effects of an action button with
observeEvent()to trigger a block of code with an action button.
eventReactive()to update derived/calculated output with an action button.
reactiveValues()to maintain an object for multiple action buttons to interact with.
Before action buttons existed in Shiny, there were only submit buttons. At this point, our general reccomendation is to avoid submit buttons and only use action buttons. Note that any code that uses a submit button can be converted to code that uses an action button instead (while the reverse is generally not true).
With an action button, input values are sent from the browser to the server as usual (when they’re changed) but you can control the reactive flow of the program by telling particular reactives to not compute until the action button is pressed. In contrast, if your app includes a submit button anywhere, none of the inputs will be sent from the client to the server until the button is pressed. However, submit buttons have unusual behavior in many ways, and we recommend that they not be used for anything but the simplest apps.
These issues include the following: A submit button has a global scope, so there is no way of specifying which inputs should be on hold and which shouldn’t. If an app has two submit buttons, both of them will control the entire app, which is probably not what you want. Also, dynamically created submit buttons (for example, with
insertUI()) will not work. For more info and an example, read the documention for
We love it when R users help each other, but RStudio does not monitor or answer the comments in this thread. If you'd like to get specific help, we recommend the Shiny Discussion Forum for in depth discussion of Shiny related questions and How to get help for a list of the best ways to get help with R code.comments powered by Disqus