Search code examples
rshinyhandsontablerhandsontable

handsontable in Shiny modal does not render properly


Problem

In my code I want to show a rhandsontable in a modal. When I first show the modal, the table is nicely rendered. However, when I close the modal and reopen it (without changing the underlying data), I only see parts of the table. Only after I clicked on the table, it renders again properly. If the data changes before re-opening the modal, the table is rendered again nicely.

Questions

How can I avoid that? Is there a javascript routine I can call to force the handsontable to re-render as a workaround?

Reprex

library(shiny)
library(rhandsontable)

ui <- fluidPage(actionButton("show", "show"), 
                actionButton("change", "Change"))

server <- function(input, output, session) {
  dat <- reactiveVal(data.frame(x = runif(2), 
                                y = runif(2)))

  observeEvent(input$show, {
    showModal(modalDialog(rHandsontableOutput("hot")))
  })

  observeEvent(input$change, dat(data.frame(x = runif(2), 
                                            y = runif(2))))

  output$hot <- renderRHandsontable(rhandsontable(dat()))
}

How to reproduce the error

  1. Open the modal and close it
  2. Re-open the modal and you will see that it is nor rendered properly
  3. Close again and refresh the data
  4. Re-open the modal and see that it is rendered properly again

Screenshots

handsontable rendered properly handsontable not rendered properly

Environment

R version 3.5.0 (2018-04-23)
Platform: i386-w64-mingw32/i386 (32-bit)
Running under: Windows 7 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=German_Germany.1252  LC_CTYPE=German_Germany.1252   
[3] LC_MONETARY=German_Germany.1252 LC_NUMERIC=C                   
[5] LC_TIME=German_Germany.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shiny_1.1.0         rhandsontable_0.3.6

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.17    digest_0.6.15   later_0.7.2     mime_0.5       
 [5] R6_2.2.2        xtable_1.8-2    jsonlite_1.5    magrittr_1.5   
 [9] rlang_0.2.1     promises_1.0.1  tools_3.5.0     htmlwidgets_1.2
[13] httpuv_1.4.3    yaml_2.1.19     compiler_3.5.0  htmltools_0.3.6

Browser tested: Chrome Version 69.0.3497.100, IE 11


Solution

  • Not the most elegant solution, but this works:

    library(shiny)
    library(rhandsontable)
    
    ui <- fluidPage(actionButton("show", "show"), 
                    actionButton("change", "Change"))
    
    server <- function(input, output, session) {
      dat <- reactiveVal(data.frame(x = runif(2), 
                                    y = runif(2)))
    
      dat1 <- reactive({
        if(is.null(input$hot)){
          dat()
        } else {
          as.data.frame(hot_to_r(input$hot))
        }
      })
    
      observeEvent(input$show, {
        showModal(modalDialog(rHandsontableOutput("hot")))
      })
    
      observeEvent(input$change, 
                   dat(data.frame(x = runif(2), y = runif(2))))
    
      output$hot <- renderRHandsontable(rhandsontable(dat1()))
    
    }
    
    shinyApp(ui,server)