daattali / shinyalert

🗯️ Easily create pretty popup messages (modals) in Shiny
https://daattali.com/shiny/shinyalert-demo/
Other
242 stars 26 forks source link

input$shinyalert can trigger even before pressing OK #22

Closed stephLH closed 5 years ago

stephLH commented 5 years ago

Hi Dean,

I have an issue when I use more than one time a shinyAlert during a session.

The second time I use a shinyalert widget, the observeEvent based on input$shinyalert triggers when modal is opening. It does not wait for confirmation or cancellation.

Is there a way to set back to NULL input$shinyalert when at some point when an operation is done ?

It's hard to give a reprex but here is a code. The first browser() call is normal after I confirmed the first shinyAlert. But I would expect that on second button press, I should arrive in browser() only if I confirm the modal, not just after modal opening.

if (interactive()) {
  library(shiny)
  library(shinyalert)

  shinyApp(
    ui = fluidPage(
      useShinyalert(),  # Set up shinyalert
      actionButton("btn", "Trigger modal"),
      verbatimTextOutput("input_shinyalert"),
      verbatimTextOutput("test_value")
    ),
    server = function(input, output) {

      observeEvent(input$btn, {

        shinyalert(
          title = "Do you confirm?", type = "info", showCancelButton = TRUE, closeOnEsc = FALSE
        )

        observeEvent(input$shinyalert, {

          if (input$shinyalert) {

            browser()

            output$test_value <- renderText({

              "test_value"

            })

          }

          output$input_shinyalert <- renderText({

            input$shinyalert

          })

        })

      })

    }
  )
}
daattali commented 5 years ago

This is not bug in shinyalert. The problem here is that you're note using reactivity correctly. You should not be placing renders inside observers and observers inside other observers, that can always result in unexpected strange behaviour.

The correct version of your app is as follows, and it works.

library(shiny)
library(shinyalert)

shinyApp(
  ui = fluidPage(
    useShinyalert(),  # Set up shinyalert
    actionButton("btn", "Trigger modal"),
    verbatimTextOutput("input_shinyalert"),
    verbatimTextOutput("test_value")
  ),
  server = function(input, output) {

    observeEvent(input$btn, {
      shinyalert(
        title = "Do you confirm?", type = "info", showCancelButton = TRUE, closeOnEsc = FALSE
      )
    })

    output$input_shinyalert <- renderText({
      input$shinyalert
    })

    output$test_value <- renderText({
      "test_value"
    })

    observeEvent(input$shinyalert, {
      if (input$shinyalert) {
        browser()
      }
    })

  }
)
stephLH commented 5 years ago

Thank you Dean. Sorry, I still do obvious mistakes using shiny...

I have one last question with your correct code. When I click tow times on the button and confirm "OK", the observeEvent based on input$shinyalert is not triggered the second time because the value TRUE has not changed for input$shinyalert. Is this an expected behaviour ?

daattali commented 5 years ago

This is indeed how shiny used to work prior to version 1.1 - a value that was identical did not trigger reactivity.

If you update your shiny to a newer version, it will trigger.

stephLH commented 5 years ago

It's now solved, my problem was I did not updated to devel version of shinyalert. Thanks again!