Reputation: 747
I am working on an RShiny application that will allow a user selection after they click a button in the UI. This selection will be used later in the code, so I would like the app to wait for the user to make their selection before proceeding. In the example here, after the user clicks on the button, they are presented with 3 checkbox options. They can take as long as they want to make their selection, and the options they choose are printed to the R console. The code is run once and then stops, exactly how I would like it to behave. However, when the user clicks the button a 2nd time, the dialog immediately disappears and prints out their previous selection and the code runs once. On a third click, the dialog box waits for input again, but after a selection the code runs 3 times! (you can verify this by the R console output or the UI notifications). How can I restructure my code so that the popup dialog waits for user input every time and only runs the code once?
Here is the example app.R file:
library(shiny)
ui <- shinyUI(fluidPage(
actionButton(inputId="myButton", label="Run code by clicking button")
))
server <- shinyServer(function(input, output, session) {
# Define the modal dialog
buttonModal <- function(failed = FALSE) {
modalDialog(
checkboxGroupInput(inputId = "options", label = "Make a selection", choices = c("Option 1", "Option 2", "Option 3")),
if (failed)
div(tags$b("something went wrong")),
footer = tagList(
modalButton("Cancel"),
actionButton(inputId = "ok", label = "OK")
)
)
}
observeEvent(input$myButton, {
print("clicked button")
#display the dialog after user clicks button
showModal(buttonModal())
# Wait to run rest of code until user clicks OK
observeEvent(input$ok, {
print(input$options)
removeModal()
showNotification("Running code... Please wait.")
print("Finished running.")
print("-------------------------------------------------------")
showNotification("Finished running.")
})
})
})
shinyApp(ui, server)
Upvotes: 0
Views: 615
Reputation: 1513
Avoid nesting observeEvent
, i.e. don't put observeEvent(input$ok,
inside observeEvent(input$myButton,
. Nesting them can cause weird behaviour.
Here is your code with that change made:
library(shiny)
ui <- shinyUI(fluidPage(
actionButton(inputId="myButton", label="Run code by clicking button")
))
server <- shinyServer(function(input, output, session) {
# Define the modal dialog
buttonModal <- function(failed = FALSE) {
modalDialog(
checkboxGroupInput(inputId = "options", label = "Make a selection", choices = c("Option 1", "Option 2", "Option 3")),
if (failed)
div(tags$b("something went wrong")),
footer = tagList(
modalButton("Cancel"),
actionButton(inputId = "ok", label = "OK")
)
)
}
observeEvent(input$myButton, {
print("clicked button")
#display the dialog after user clicks button
showModal(buttonModal())
})
observeEvent(input$ok, {
print(input$options)
removeModal()
showNotification("Running code... Please wait.")
print("Finished running.")
print("-------------------------------------------------------")
showNotification("Finished running.")
})
})
shinyApp(ui, server)
Upvotes: 2