简体   繁体   中英

Get renderUI to work mid way through an observeEvent

I have a renderUI that I need to update mid way through an observeEvent.

Basically, When I click on the load button in the below example, firstly input$Test1 needs to update with new values, then I need the renderUI to update, then I need to update the input values in this renderUI. (This usually comes from me loading a file, but this simplified version should suffice)

I have simplified this below. Basically, I need input$DynamicTwo to be filled in on the first pass - It currently only fills in once I've clicked on input$Load twice.

library(shiny)

ui <- navbarPage(
  title = "navbar", 
  id = "navbar",
  tabPanel(
    "panel1", 
    selectizeInput("Test1",label="Test1: UI on panel2 depends on this",choices=c("One","Two","Three"),multiple=T,selected="One"),
    actionButton("Load","Make Test1=Two and fill in DynamicTwo with B")
  ),
  tabPanel(
    "panel2",
    uiOutput("DynamicOnTest1")
  )
)


server <- function(input, output, session) {

  output$DynamicOnTest1<- renderUI({
    lapply(input$Test1,function(x) {
      selectizeInput(paste("Dynamic",x,sep=""),paste("Dynamic",x), choices=c("A","B","C"),multiple=TRUE)
    })
  })

  observeEvent(input$Load ,{
    updateSelectizeInput(session,"Test1",selected="Two")
    #somehow I need to get the renderUI to run in here, before...
    updateSelectizeInput(session,"DynamicTwo",selected="B")
  })

}

shinyApp(ui = ui, server = server)

I've hit a mental brick wall here so any help would be greatly appreciated.

There are two workarounds to it, but depending on what you really plan to do with your app, they might be not suitable. But maybe that can help you go through your mental brick wall.

First solution using observe

Create an observer for your dynamic input.

  observeEvent(input$Load ,{
    updateSelectizeInput(session,"Test1",selected="Two")
  })

  observe({
    input[["DynamicTwo"]]
    updateSelectizeInput(session,"DynamicTwo",selected="B")  
  })

Second solution using shinyjs::delay

Wait for DynamicOnTest1 to be rendered first, so we are sure that input[["DynamicTwo"]] exists.

ui <- navbarPage(
  title = "navbar", 
  id = "navbar",
  tabPanel(
    "panel1", 
    selectizeInput("Test1",label="Test1: UI on panel2 depends on this",choices=c("One","Two","Three"),multiple=T,selected="One"),
    actionButton("Load","Make Test1=Two and fill in DynamicTwo with B")
  ),
  tabPanel(
    "panel2",
    uiOutput("DynamicOnTest1")
  ),
  shinyjs::useShinyjs()
)


server <- function(input, output, session) {

  output$DynamicOnTest1<- renderUI({
    lapply(input$Test1,function(x) {
      selectizeInput(paste("Dynamic",x,sep=""),paste("Dynamic",x), choices=c("A","B","C"),multiple=TRUE)
    })
  })

  observeEvent(input$Load ,{
    updateSelectizeInput(session,"Test1",selected="Two")
    shinyjs::delay(1000, updateSelectizeInput(session,"DynamicTwo",selected="B"))  
  })
}

shinyApp(ui = ui, server = server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM