How to have Shiny App refresh on action button

I am trying to expand on an example to get started with Shiny. I would like it to only refresh when the submit button is clicked, and I am successful getting it to run only after it is clicked the first time. However, once it is clicked once, it refreshes with each keystroke. The goal is to only have it refresh on button click (allow typing before changing the plot).

Any help is appreciated. Code is below:

# Define UI for miles per gallon app ----
ui <- fluidPage(

  # App title ----
  titlePanel("Miles Per Gallon"),

  # Sidebar layout with input and output definitions ----
  sidebarLayout(

    # Sidebar panel for inputs ----
    sidebarPanel(

      # Input: Selector for variable to plot against mpg ----
      textInput('variable', label = 'MPG vs:', value = 'am', placeholder = 'am'),

      # Input: Checkbox for whether outliers should be included ----
      checkboxInput("outliers", "Show outliers", TRUE),
      
      #Wait until action button is clicked
      actionButton(
        inputId = "submit_loc",
        label = "Submit")

    ),

    # Main panel for displaying outputs ----
    mainPanel(

      # Output: Formatted text for caption ----
      h3(textOutput("caption")),

      # Output: Plot of the requested variable against mpg ----
      plotOutput("mpgPlot")

    )
  )
)


mpgData <- mtcars
mpgData$am <- factor(mpgData$am, labels = c("Automatic", "Manual"))

server <- function(input, output) {
  observeEvent(
      eventExpr = input$submit_loc,
      handlerExpr =  {
  # Compute the formula text ----
  # This is in a reactive expression since it is shared by the
  # output$caption and output$mpgPlot functions
  formulaText <- reactive({
    paste("mpg ~", input$variable)
  })

  # Return the formula text for printing as a caption ----
  output$caption <- renderText({
    formulaText()
  })

  # Generate a plot of the requested variable against mpg ----
  # and only exclude outliers if requested
  output$mpgPlot <- renderPlot({
    boxplot(as.formula(formulaText()),
            data = mpgData,
            outline = input$outliers,
            col = "#75AADB", pch = 19)
  })

      }
    )
  }


shinyApp(ui, server)

1 Like

You should try to avoid nesting observeEvent and reactive.

Here is a solution based on eventReactive.

# Define UI for miles per gallon app ----
ui <- fluidPage(
  
  # App title ----
  titlePanel("Miles Per Gallon"),
  
  # Sidebar layout with input and output definitions ----
  sidebarLayout(
    
    # Sidebar panel for inputs ----
    sidebarPanel(
      
      # Input: Selector for variable to plot against mpg ----
      textInput('variable', label = 'MPG vs:', value = 'am', placeholder = 'am'),
      
      # Input: Checkbox for whether outliers should be included ----
      checkboxInput("outliers", "Show outliers", TRUE),
      
      #Wait until action button is clicked
      actionButton(
        inputId = "submit_loc",
        label = "Submit")
      
    ),
    
    # Main panel for displaying outputs ----
    mainPanel(
      
      # Output: Formatted text for caption ----
      h3(textOutput("caption")),
      
      # Output: Plot of the requested variable against mpg ----
      plotOutput("mpgPlot")
      
    )
  )
)


mpgData <- mtcars
mpgData$am <- factor(mpgData$am, labels = c("Automatic", "Manual"))

server <- function(input, output) {

      # Compute the formula text ----
      # This is in a reactive expression since it is shared by the
      # output$caption and output$mpgPlot functions
      formulaText <- eventReactive(input$submit_loc, {
        paste("mpg ~", input$variable)
      })
      
      # Return the formula text for printing as a caption ----
      output$caption <- renderText({
        formulaText()
      })
      
      # Generate a plot of the requested variable against mpg ----
      # and only exclude outliers if requested
      output$mpgPlot <- renderPlot({
        boxplot(as.formula(formulaText()),
                data = mpgData,
                outline = input$outliers,
                col = "#75AADB", pch = 19)
      })
      
}


shinyApp(ui, server)

Btw. I'd use selectInput instead of textInput for a scenario like this.

That's it, thank you!

I was using text input because I have another project where I would like to enter text and run on command, so this is perfect to understand how to do that.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.