% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/bookmark-state.R
\name{enableBookmarking}
\alias{enableBookmarking}
\title{Enable bookmarking for a Shiny application}
\usage{
enableBookmarking(store = c("url", "server", "disable"))
}
\arguments{
\item{store}{Either \code{"url"}, which encodes all of the relevant values in
a URL, \code{"server"}, which saves to disk on the server, or
\code{"disable"}, which disables any previously-enabled bookmarking.}
}
\description{
There are two types of bookmarking: saving an application's state to disk on
the server, and encoding the application's state in a URL. For state that has
been saved to disk, the state can be restored with the corresponding state
ID. For URL-encoded state, the state of the application is encoded in the
URL, and no server-side storage is needed.

URL-encoded bookmarking is appropriate for applications where there not many
input values that need to be recorded. Some browsers have a length limit for
URLs of about 2000 characters, and if there are many inputs, the length of
the URL can exceed that limit.

Saved-on-server bookmarking is appropriate when there are many inputs, or
when the bookmarked state requires storing files.
}
\details{
For restoring state to work properly, the UI must be a function that takes
one argument, \code{request}. In most Shiny applications, the UI is not a
function; it might have the form \code{fluidPage(....)}. Converting it to a
function is as simple as wrapping it in a function, as in
\code{function(request) \{ fluidPage(....) \}}.

By default, all input values will be bookmarked, except for the values of
passwordInputs. fileInputs will be saved if the state is saved on a server,
but not if the state is encoded in a URL.

When bookmarking state, arbitrary values can be stored, by passing a function
as the \code{onBookmark} argument. That function will be passed a
\code{ShinySaveState} object. The \code{values} field of the object is a list
which can be manipulated to save extra information. Additionally, if the
state is being saved on the server, and the \code{dir} field of that object
can be used to save extra information to files in that directory.

For saved-to-server state, this is how the state directory is chosen:
\itemize{
\item If running in a hosting environment such as Shiny Server or
Connect, the hosting environment will choose the directory.
\item If running an app in a directory with \code{\link[=runApp]{runApp()}}, the
saved states will be saved in a subdirectory of the app called
shiny_bookmarks.
\item If running a Shiny app object that is generated from code (not run
from a directory), the saved states will be saved in a subdirectory of
the current working directory called shiny_bookmarks.
}

When used with \code{\link[=shinyApp]{shinyApp()}}, this function must be called before
\code{shinyApp()}, or in the \code{shinyApp()}'s \code{onStart} function. An
alternative to calling the \code{enableBookmarking()} function is to use the
\code{enableBookmarking} \emph{argument} for \code{shinyApp()}. See examples
below.
}
\examples{
## Only run these examples in interactive R sessions
if (interactive()) {

# Basic example with state encoded in URL
ui <- function(request) {
  fluidPage(
    textInput("txt", "Text"),
    checkboxInput("chk", "Checkbox"),
    bookmarkButton()
  )
}
server <- function(input, output, session) { }
enableBookmarking("url")
shinyApp(ui, server)


# An alternative to calling enableBookmarking(): use shinyApp's
# enableBookmarking argument
shinyApp(ui, server, enableBookmarking = "url")


# Same basic example with state saved to disk
enableBookmarking("server")
shinyApp(ui, server)


# Save/restore arbitrary values
ui <- function(req) {
  fluidPage(
    textInput("txt", "Text"),
    checkboxInput("chk", "Checkbox"),
    bookmarkButton(),
    br(),
    textOutput("lastSaved")
  )
}
server <- function(input, output, session) {
  vals <- reactiveValues(savedTime = NULL)
  output$lastSaved <- renderText({
    if (!is.null(vals$savedTime))
      paste("Last saved at", vals$savedTime)
    else
      ""
  })

  onBookmark(function(state) {
    vals$savedTime <- Sys.time()
    # state is a mutable reference object, and we can add arbitrary values
    # to it.
    state$values$time <- vals$savedTime
  })
  onRestore(function(state) {
    vals$savedTime <- state$values$time
  })
}
enableBookmarking(store = "url")
shinyApp(ui, server)


# Usable with dynamic UI (set the slider, then change the text input,
# click the bookmark button)
ui <- function(request) {
  fluidPage(
    sliderInput("slider", "Slider", 1, 100, 50),
    uiOutput("ui"),
    bookmarkButton()
  )
}
server <- function(input, output, session) {
  output$ui <- renderUI({
    textInput("txt", "Text", input$slider)
  })
}
enableBookmarking("url")
shinyApp(ui, server)


# Exclude specific inputs (The only input that will be saved in this
# example is chk)
ui <- function(request) {
  fluidPage(
    passwordInput("pw", "Password"), # Passwords are never saved
    sliderInput("slider", "Slider", 1, 100, 50), # Manually excluded below
    checkboxInput("chk", "Checkbox"),
    bookmarkButton()
  )
}
server <- function(input, output, session) {
  setBookmarkExclude("slider")
}
enableBookmarking("url")
shinyApp(ui, server)


# Update the browser's location bar every time an input changes. This should
# not be used with enableBookmarking("server"), because that would create a
# new saved state on disk every time the user changes an input.
ui <- function(req) {
  fluidPage(
    textInput("txt", "Text"),
    checkboxInput("chk", "Checkbox")
  )
}
server <- function(input, output, session) {
  observe({
    # Trigger this observer every time an input changes
    reactiveValuesToList(input)
    session$doBookmark()
  })
  onBookmarked(function(url) {
    updateQueryString(url)
  })
}
enableBookmarking("url")
shinyApp(ui, server)


# Save/restore uploaded files
ui <- function(request) {
  fluidPage(
    sidebarLayout(
      sidebarPanel(
        fileInput("file1", "Choose CSV File", multiple = TRUE,
          accept = c(
            "text/csv",
            "text/comma-separated-values,text/plain",
            ".csv"
          )
        ),
        tags$hr(),
        checkboxInput("header", "Header", TRUE),
        bookmarkButton()
      ),
      mainPanel(
        tableOutput("contents")
      )
    )
  )
}
server <- function(input, output) {
  output$contents <- renderTable({
    inFile <- input$file1
    if (is.null(inFile))
      return(NULL)

    if (nrow(inFile) == 1) {
      read.csv(inFile$datapath, header = input$header)
    } else {
      data.frame(x = "multiple files")
    }
  })
}
enableBookmarking("server")
shinyApp(ui, server)

}
}
\seealso{
\code{\link[=onBookmark]{onBookmark()}}, \code{\link[=onBookmarked]{onBookmarked()}},
\code{\link[=onRestore]{onRestore()}}, and \code{\link[=onRestored]{onRestored()}} for registering
callback functions that are invoked when the state is bookmarked or
restored.

Also see \code{\link[=updateQueryString]{updateQueryString()}}.
}
