daattali / shinyalert

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

Get df value from rhandsontable inside shinyalert modal #50

Closed amanthapar closed 3 years ago

amanthapar commented 3 years ago

Hello, I am rendering a rhandsontable inside a tagList that has a dropdown. When a user changes the dropdown and clicks "Ok" I want to get access to that data frame. Normally with handsontable you can do that by hot_to_r("table Id"). Is there a way I could have access to that in a similar fashion inside the tagList? So it can be availabel in the CallbackR or somewhere else?

For example if: rhandsontable::rHandsontableOutput(ns("modalTbl")) output$modalTbl <- rhandsontable::renderRHandsontable({....}) df can be accessed via hot_to_r(output$modalTbl)

Currently, I am not able to detect any input changes to the dropdown when exiting the modal.

shinyalert::shinyalert(
                  title = "title",
                  text = tagList(
                    rhandsontable::renderRHandsontable({
                    rhandsontable::rhandsontable(df, height = 300, rowHeaders = TRUE, selectCallback = TRUE, search = TRUE) %>%
                    rhandsontable::hot_col("Col1", colWidths = 120 ) %>%
                    rhandsontable::hot_col("Col2", readOnly = TRUE, colWidths = 150) %>%
                    rhandsontable::hot_col("Col3", readOnly = TRUE, colWidths = 175 ) %>%
                    rhandsontable::hot_col("Col4", type = "dropdown", colWidths = 175, source = c('a', 'b', 'c') )
                    })
                  ),
                  size = "m", 
                  closeOnEsc = TRUE,
                  closeOnClickOutside = FALSE,
                  html = TRUE,
                  type = "",
                  showConfirmButton = TRUE,
                  showCancelButton = TRUE,
                  confirmButtonText = "Save",
                  confirmButtonCol = "#AEDEF4",
                  timer = 0,
                  imageUrl = "",
                  animation = FALSE,
                  callbackR = function(x){
                  output$DEBUG <- renderPrint(rhandsontable::hot_to_r(output$shinyalert))
                  }
                 )
daattali commented 3 years ago

This example is too complex and not reproducible, I cannot help with this code. But generally you shouldn't be placing render functions inside shinyalert's text argument - you should place an output function there because it expected to receive UI tags. And in the callback you shouldn't place a render function either. Render functions should go in the top-level server, and the callback should modify a variable.

Even though I can't fix your exact code, here is an example that shows that you can use a rhandsontable inside a shinyalert and you can retrieve its value:

library(shiny)

df <- head(cars)

ui <- fluidPage(
  tableOutput("table")
)

server <- function(input, output, session) {
  shinyalert::shinyalert(
    text = tagList(
      rhandsontable::rHandsontableOutput("rhotable", height = "200")
    ),
    html = TRUE
  )
  output$rhotable <-  rhandsontable::renderRHandsontable({
    rhandsontable::rhandsontable(df)
  })

  output$table <- renderTable({
    rhandsontable::hot_to_r(input$rhotable)
  })
}

shinyApp(ui, server)

And here's a more complex example where you can generate the shinyalert to edit a table multiple times, and it still works.

library(shiny)

ui <- fluidPage(
  actionButton("edit", "Edit"),
  tableOutput("table")
)

server <- function(input, output, session) {
  df <- reactiveVal(head(cars))

  observeEvent(input$edit, {
    shinyalert::shinyalert(
      text = tagList(
        rhandsontable::rHandsontableOutput("rhotable", height = "200")
      ),
      html = TRUE,
      callbackR = function(value) {
        if (isTRUE(value)) {
          df(rhandsontable::hot_to_r(input$rhotable))
        }
      }
    )
  })

  output$rhotable <-  rhandsontable::renderRHandsontable({
    rhandsontable::rhandsontable(df())
  })

  output$table <- renderTable({
    df()
  })
}

shinyApp(ui, server)

It seems like the issues in your code stem more from incorrect use of reactivity concepts rather than issues with shinyalert, so I'm closing this issue. I hope the two examples above are helpful!

amanthapar commented 3 years ago

Thank you