Reputation: 1563
I want to modify UI using uiOutput()
and plotOutput()
when the button is clicked. Everything works fine if it doesn't wait for the event and changes the content immediately. What should i change to make output$body.on.button
having the same output as output$body.immediately
when the button is clicked?
server.R:
shinyServer(function(input, output, session) {
output$plot <- renderPlot({plot(1:5)})
output$body.ui <- renderUI({tags$p('This works only within renderUI')})
output$body.on.button <- eventReactive(input$goButton, {
switch(
input$select,
"text" = 'This works within both functions',
"ui" = uiOutput("body.ui"), # This doesn't work
"plot" = plotOutput("plot") # This doesn't work
)
})
output$body.immediately <- renderUI({
switch(
input$select,
"text" = 'This works within both functions',
"ui" = uiOutput("body.ui"), # This works
"plot" = plotOutput("plot") # This works
)
})
})
ui.R:
library(markdown)
shinyUI(
navbarPage(
"Title",
tabPanel(
"First element",
fluidRow(
column(
4,
wellPanel(
selectInput("select", "Select", c('text', 'ui', 'plot')),
actionButton("goButton", "Go!")
) # end of wellPanel
), # end of column
column(
4,
uiOutput("body.immediately")
), # end of column
column(
4,
uiOutput("body.on.button")
) # end of column
) # end of fluidROw
) # end of tabPanel
) # end of navbarPage
) # end of shinyUI
I have also tried function observeEvent()
but it didn't help.
Upvotes: 2
Views: 1770
Reputation: 5471
It doesn't work because you can't have two outputs with the same ID. In your example "Text" works because it is just a text - not an output with an ID.
In the example below I've added three new outputs with unique IDs. uiOutput body.on.button
also dynamically receives a specific output after clicking on a button.
You can try to remove this three lines
output$text2 <- renderText({ 'This works within both functions' })
output$body.ui2 <- renderUI({tags$p('This works only within renderUI')})
output$plot2 <- renderPlot({plot(1:10)})
and then change IDs
within eventReactive from "text2" to "text" (similarly with the other two) to see that the outputs after clicking on a button are not going to be shown.
If you want to have, for example, two same plots, then you should create two plotOutputs
with unique IDs and then use twice renderPlot
functions which produce the same plots.
I hope this helps.
Full example:
server <- shinyServer(function(input, output, session) {
# Create outputs with unique ID
output$text <- renderText({ 'This works within both functions' })
output$body.ui <- renderUI({tags$p('This works only within renderUI')})
output$plot <- renderPlot({plot(1:5)})
output$text2 <- renderText({ 'This works within both functions' })
output$body.ui2 <- renderUI({tags$p('This works only within renderUI')})
output$plot2 <- renderPlot({plot(1:10)})
# Save the selected type of the output and then pass it to renderUI via react()
react <- eventReactive(input$goButton, {
switch(
input$select,
"text" = textOutput("text2"),
"ui" = uiOutput("body.ui2"),
"plot" = plotOutput("plot2")
)
})
output$body.on.button <- renderUI({
react()
})
output$body.immediately <- renderUI({
switch(
input$select,
"text" = textOutput("text"),
"ui" = uiOutput("body.ui"), # This works
"plot" = plotOutput("plot") # This works
)
})
})
library(markdown)
ui <-shinyUI(
navbarPage(
"Title",
tabPanel(
"First element",
fluidRow(
column(
4,
wellPanel(
selectInput("select", "Select", c('text', 'ui', 'plot')),
actionButton("goButton", "Go!")
) # end of wellPanel
), # end of column
column(
4,
uiOutput("body.immediately")
), # end of column
column(
4,
uiOutput("body.on.button")
) # end of column
) # end of fluidROw
) # end of tabPanel
) # end of navbarPage
) # end of shinyUI
shinyApp(ui, server)
Upvotes: 3