Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug when running rhandsontable in modal dialogue (reference issue # 24) #387

Open
lgirola opened this issue Jul 24, 2021 · 4 comments
Open

Comments

@lgirola
Copy link

lgirola commented Jul 24, 2021

Hi, rhandsontable is very useful for the types of models I work with. And in combination with modal dialogue, it makes the model input process very user friendly.

However, when an rhandsontable is rendered in a modal box, depending on the circumstance only a part of the table is rendered until the user clicks on the partially rendered table. Is this a bug, or am I using rhandsontable incorrectly? Please see super simple MWE code below. It renders the initial table just fine, but when the user makes a change to the table (for example inserting a row with data) and tries re-rendering it by clicking the "Show" action button, only part of the table is rendered until the user clicks on the table.

The first image shows the rendered table when first invoking the app - looks good. The second image shows the rendered table after having inserted a row/data and then clicking "Show" -- I only get a partial rendering of the table until clicking on it, and then the complete table pops up (as it should have done after the "Show" click). The third images shows the completely and correctly rendered table after inserting a 3rd row, after clicking "Show", and after clicking on the partially rendered table.

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)

Image1
Image2
Image3

@timelyportfolio
Copy link
Collaborator

@ismirsehregal Since the handsontable is rendered into a hidden element, handsontable will not know a size. My solution below makes two changes:

  1. Add some JavaScript to re-render the handsontable on the show.bs.modal event
  2. Change to height: auto; in rHandsontableOutput
library(shiny)
library(rhandsontable)

ui <- fluidPage(
  tags$head(tags$script(HTML(
"
$(document).on('show.bs.modal', function() {
  var w = HTMLWidgets.find('#hot');
  var hot = w && w.hot ? w.hot : null
  if(hot === null) {return null} // if handsontable not defined or rendered then exit
  
  hot.render();
})
"
  ))),
  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(
        {
          # messy way to change height to auto from 100%
          hot <- rHandsontableOutput("hot")
          hot[[1]]$attribs$style <- "height: auto; width: 100%;"
          hot
        }
      )
    )
  })

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

  output$hot <- renderRHandsontable(rhandsontable(dat1(), licenseKey = "non-commercial-and-evaluation"))

}

shinyApp(ui,server)

@DillonHammill
Copy link
Collaborator

Thanks a lot for looking into this @timelyportfolio! Perhaps @jrowen can offer advice on making a more permanent solution, but this works well in my testing.

@lgirola
Copy link
Author

lgirola commented Aug 23, 2021

The above post from timelyportfolio does clean up the re-rendering issue noted in the original #387 Issue posting dated Jul-24. However, the "Change" (or "Reset") button doesn't work -- clicking it should revert the output back to a 2 x 2 table of 4 random numbers obviating any manual changes that have been made to the table. Any ideas on how to fix this? As I've dealt with this issue and tried alternative solutions, resolving the re-rendering issue triggers the reset issue, and resolving the reset issue triggers the re-rendering issue. There needs to be a way out of this circle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants