Call this once, near the top of your server function. After that,
rewind records the session inputs as the user works. It also records
the reactive values that you register with rewind_track(). The user can
then move backwards and forwards through that history.
Usage
rewind_enable(
session = shiny::getDefaultReactiveDomain(),
inputs = NULL,
exclude = NULL,
depth = 50L,
coalesce_ms = 400L,
shortcuts = TRUE,
verbose = FALSE
)Arguments
- session
The Shiny session. The default is the current session.
- inputs
Character vector of the input IDs to capture. Use
NULL(the default) to capture all permitted inputs.- exclude
Character vector of input IDs to skip.
rewindapplies this afterinputs.- depth
The maximum number of history entries to keep.
rewindremoves the oldest entries first.- coalesce_ms
The quiet period in milliseconds before
rewindwrites a change to the history. Increase it to group more changes.- shortcuts
Set to
TRUEto bind the keyboard shortcuts in the browser. There are three:Ctrl+Z(Cmd+Zon macOS) does an undo;Ctrl+Shift+Z(Cmd+Shift+Zon macOS) does a redo;Ctrl+Yalso does a redo. This is the usual redo shortcut on Windows.
The shortcuts do nothing while the user types in a text field. The text undo of the browser thus continues to work.
- verbose
Set to
TRUEto show messages about whatrewindcaptures and restores. This is useful during development.
What gets captured
By default rewind captures every input in the session. There are four
exclusions. It is never useful to restore these:
action buttons and links. Their value is a click counter.
shiny::fileInput(). Its value points to a temporary file on the server. Shiny deletes that file at the next upload. An old snapshot would thus point to a file that does not exist.inputs with names that start with
rewind_. These belong to this package.inputs with names that start with
.. These are internal to Shiny.
Use inputs to give a list of the inputs to capture. This is usually
better in a large application. Undo must move the controls that the user
thinks of as filters. It must not move every other input on the page.
Grouping
Changes that occur within coalesce_ms of each other become one history
entry. One drag of a slider is thus one undo step, not forty. Use
rewind_step() to group changes yourself.
Modules
You can call this function inside a moduleServer(). rewind captures
the inputs with their module-local names. These are the same names that
input$ uses inside the module. rewind adds the namespace with
session$ns() when it restores them.
All modules share session$userData. A second call to rewind_enable()
thus uses the same history as the first call. It does not make a second
history. Call the function once, at the position in the module tree that
is best for your application.
Examples
if (interactive()) {
library(shiny)
ui <- fluidPage(
rewind_buttons(),
selectInput("species", "Species", c("setosa", "versicolor", "virginica")),
sliderInput("n", "Rows", 1, 50, 10),
tableOutput("tbl")
)
server <- function(input, output, session) {
rewind_enable()
output$tbl <- renderTable({
head(iris[iris$Species == input$species, ], input$n)
})
}
shinyApp(ui, server)
}