Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

insertUI and bookmark states #1461

Closed
KZARCA opened this issue Nov 7, 2016 · 1 comment
Closed

insertUI and bookmark states #1461

KZARCA opened this issue Nov 7, 2016 · 1 comment

Comments

@KZARCA
Copy link

@KZARCA KZARCA commented Nov 7, 2016

Hi,
insertUI is very useful, but is not efficient with bookmark states. The typical use case is when I have an actionButton that creates an input field. When I execute the following example, click n times, and then bookmark, when I restore, the text fields are of course not restored.

library(shiny)
ui = function(request) {
  fluidPage(
      title = "test",
      id = "main",
      uiOutput("testUI"),
      bookmarkButton() 
  )
}`

server <- shinyServer(function(session, input, output) {
  values <- reactiveValues(n = 0)
  onBookmark(function(state) {
    state$values$n <- values$n
  })
  onRestore(function(state) {
    values$n <- state$values$n
  })
  setBookmarkExclude(
    "clickButton"
  )
  output$testUI <- renderUI({
    actionButton("clickButton", "Click here")
  })
  observeEvent(input$clickButton,{
    values$n <- values$n + 1
    insertUI("#testUI", 
             ui = div(
               textInput(paste0("textExample", values$n), NULL, value = paste(values$n, "This is a test"))
             )
    )
  })
})

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

I found a workaround, which is using lapply:

  observeEvent(input$clickButton,{
    values$n <- values$n + 1
  })
  
  observe({
    lapply(seq_len(values$n), function(x){
      insertUI("#testUI", 
               ui = div(
                 textInput(paste0("textExample", x), NULL, value = paste(x, "This is a test"))
               )
      )
    })

But using a lapply is not straightforward: it will create 1 textInput at the first click, 2 more at the second, 3 more at the third, etc.
So we must use removeUI to remove the old copies:

  observeEvent(input$clickButton,{
    values$n <- values$n + 1
  })
  
  observe({
    lapply(seq_len(values$n), function(x){
      removeUI(paste0("#div", x))
      insertUI("#testUI", 
               ui = div(id = paste0("div", x),
                 textInput(paste0("textExample", x), NULL, value = paste(x, "This is a test"))
               )
      )
    })
    
  })

Therefore I have the feeling that insertUI could be optimised for bookmarking. What do you think?

@wch
Copy link
Collaborator

@wch wch commented Nov 7, 2016

There isn't a straightforward way to make bookmarking automatically work when you do things like insertUI. In your case you can use onRestored to insert the UI after the page has loaded.

library(shiny)
ui = function(request) {
  fluidPage(
    title = "test",
    id = "main",
    uiOutput("testUI"),
    bookmarkButton() 
  )
}

server <- shinyServer(function(session, input, output) {
  values <- reactiveValues(n = 0)
  onBookmark(function(state) {
    state$values$n <- values$n
  })
  onRestore(function(state) {
    values$n <- state$values$n
  })
  onRestored(function(state) {
    for (i in seq_len(values$n)) {
      insertTextInput(i)
    }
  })
  setBookmarkExclude(
    "clickButton"
  )
  output$testUI <- renderUI({
    actionButton("clickButton", "Click here")
  })
  observeEvent(input$clickButton,{
    values$n <- values$n + 1
    insertTextInput(values$n)
  })

  insertTextInput <- function(n) {
    insertUI("#testUI",
      ui = div(
        textInput(paste0("textExample", n), NULL,
          value = paste(n, "This is a test"))
      )
    )
  }
})

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

@wch wch closed this as completed Nov 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants