Is it possible to restore accordion panels with shiny bookmarking?

40 views Asked by At

I have this app where bookmarking shiny works great, except it only restores the last accordion panel after a page refresh. If I regenerate the same panel, then I can see that the text input is restored. But it requires the user to regenerate the panels. Is it possible to restore the accordion panels with bookmarking?

Example app

library(shiny)
library(bslib)

ui <- function(request) {
  fluidPage(
    theme = bs_theme(version = 5),
    titlePanel("Dynamic Tabs with Bookmarking"),
    sidebarLayout(
      sidebarPanel(
        textInput("tab_name", "Tab Name"),
        actionButton("add_tab", "Add Tab")
      ),
      mainPanel(
        accordion(
          id = "tabs"
        )
      )
    )
  )
}

server <- function(input, output, session) {
  # Reactive value to store tab names
  tabs <- reactiveVal(character(0))

  # Function to add a new tab
  observeEvent(input$add_tab, {
    new_tab_name <- isolate(input$tab_name)
    if (!is.null(new_tab_name) && new_tab_name != "") {
      accordion_panel_insert(id = "tabs",
                panel = accordion_panel(title = new_tab_name, value = new_tab_name,
                                        textInput(paste0(new_tab_name, "_my"), label="Enter:"))
      )
      # Update reactive value with new tab name
      tabs(c(tabs(), new_tab_name))
    }
  })


  # Update bookmark state
  observe({

    session$doBookmark()
  })

  # Update URL
  onBookmarked(updateQueryString)
}

shinyApp(ui, server, enableBookmarking = "url")
1

There are 1 answers

0
Stéphane Laurent On BEST ANSWER

Using onBookmark and onRestore:

library(shiny)
library(bslib)

ui <- function(request) {
  fluidPage(
    theme = bs_theme(version = 5),
    titlePanel("Dynamic Tabs with Bookmarking"),
    sidebarLayout(
      sidebarPanel(
        textInput("tab_name", "Tab Name"),
        actionButton("add_tab", "Add Tab")
      ),
      mainPanel(
        accordion(
          id = "tabs"
        )
      )
    )
  )
}

server <- function(input, output, session) {
  # Reactive value to store tab names
  tabs <- reactiveVal(character(0))
  
  # Function to add a new tab
  observeEvent(input$add_tab, {
    new_tab_name <- isolate(input$tab_name)
    if (!is.null(new_tab_name) && new_tab_name != "") {
      accordion_panel_insert(id = "tabs",
                             panel = accordion_panel(title = new_tab_name, value = new_tab_name,
                                                     textInput(paste0(new_tab_name, "_my"), label="Enter:"))
      )
      # Update reactive value with new tab name
      tabs(c(tabs(), new_tab_name))
    }
  })
  
  
  # Update bookmark state
  observe({
    session$doBookmark()
  })
  
  onBookmark(function(state) {
    state$values$Tabs <- tabs()
  })
  
  onRestore(function(state) {
    for(tab_name in head(state$values$Tabs, -1)) {
      accordion_panel_insert(
        id = "tabs",
        panel = accordion_panel(
          title = tab_name, value = tab_name,
          textInput(paste0(tab_name, "_my"), label="Enter:")
        )
      )
    }
  })
  
  # Update URL
  onBookmarked(updateQueryString)
}

shinyApp(ui, server, enableBookmarking = "url")