Hello StackOverflow community,
I have developed a Shiny app that employs three modules. The main feature I'm implementing is the autosave and bookmarking feature of Shiny. Currently, the app saves a bookmark automatically every 5 minutes and users can also manually save a bookmark.
Here are the main steps:
- When a bookmark is created, it is saved to a local .txt file along with a user-provided name.
- The user can then select this bookmark from a dropdown menu to restore the app to this saved state.
- The app saves a new bookmark every 5 minutes (handled in the server function with a reactiveTimer).
The issue I'm facing is that, currently, every time a user changes an input, a pop-up dialog box appears,showing the bookmarked URL. While this is a built-in feature of Shiny's bookmarking system, I would like to avoid having this pop-up appear so frequently.
Is there a way to modify the bookmarking feature such that the dialog box only appears when the app is restarted, rather than every time an input changes?
I would greatly appreciate any suggestions on how to modify the current app behavior. Thank you very much!
Here is a fully reproducible version of my app.
# Required Libraries
library(shiny)
# Module Server Functions
module1 <- function(input, output, session) {
output$value <- renderText({ input$num^2 })
}
module2 <- function(input, output, session) {
output$value <- renderText({ input$num^2 })
}
module3 <- function(input, output, session) {
output$value <- renderText({ input$num^2 })
}
# Module UI Functions
module1UI <- function(id) {
ns <- NS(id)
tagList(numericInput(ns("num"), "Number", value = 0),
textOutput(ns("value")))
}
module2UI <- function(id) {
ns <- NS(id)
tagList(numericInput(ns("num"), "Number", value = 0),
textOutput(ns("value")))
}
module3UI <- function(id) {
ns <- NS(id)
tagList(numericInput(ns("num"), "Number", value = 0),
textOutput(ns("value")))
}
# UI
ui <- function(request) {
fluidPage(
module1UI("mod1"),
module2UI("mod2"),
module3UI("mod3"),
actionButton("saveBookmark", "Save Bookmark"),
selectInput("restoreBookmark", "Restore Bookmark", choices = NULL),
textOutput("txt")
)
}
# Server
server <- function(input, output, session) {
# Initialize Modules
callModule(module1, "mod1")
callModule(module2, "mod2")
callModule(module3, "mod3")
# Check if bookmarks.txt exists, if not, create it
if (!file.exists("bookmarks.txt")) {
write.table(data.frame(bookmarkName = character(), bookmarkURL = character(), stringsAsFactors = FALSE), "bookmarks.txt", row.names = FALSE)
}
# Load bookmarks from file
bookmarks <- read.table("bookmarks.txt", header = TRUE, stringsAsFactors = FALSE)
updateSelectInput(session, "restoreBookmark", choices = bookmarks$bookmarkName)
# Handle bookmark restoration
observeEvent(input$restoreBookmark, {
if (input$restoreBookmark != "") {
session$doBookmark()
}
})
# Handle bookmark creation
onBookmark(function(state) {
# Add to bookmarks database
bookmarks <<- rbind(bookmarks, data.frame(bookmarkName = state$id, bookmarkURL = state$url))
write.table(bookmarks, "bookmarks.txt", row.names = FALSE)
# Update the selectInput
updateSelectInput(session, "restoreBookmark", choices = bookmarks$bookmarkName)
})
# Handle restore event
onRestore(function(state) {
# Update the text output
output$txt <- renderText({
paste("Restored from bookmark:", state$id)
})
})
# Set up auto-saving every 5 minutes (300 seconds)
autoSave <- reactiveTimer(300000)
observe({
autoSave()
session$doBookmark()
})
}
shinyApp(ui, server, enableBookmarking = "server")