Home > Software engineering >  ID for rhandsontable inside modal in R Shiny
ID for rhandsontable inside modal in R Shiny

Time:04-06

My goal is to display an (conditional) editable rhandsontable inside a modal by clicking an actionbutton. Creating and displaying the table worked fine, however I'm struggling on how to properly assign an ID in the ui for the table in order to recognize user changes.

Any help is appreciated, thank you :)

library(shiny)

ui <- fluidPage(
  actionButton('openModal', "Open Modal")
  # rHandsontableOutput("DataEditor") # doesn't work
)

server <- function(input, output, session) {
  
  observeEvent(input$openModal, {
    irrelevant_condition <- FALSE # include that rhandsontable doesn't have to appear always
    if (irrelevant_condition == TRUE) {
      return(showModal(modalDialog("Choose some variables to display first")))
    } else {
      # display rhandsontable if user made a valid choice
      showModal(modalDialog(  
        updDataEditor()
      ))
    }
  })
  
  updDataEditor <- function() {
    output$DataEditor <- renderRHandsontable({
      # in real app some conditional calculations leading to a DF called 'current.DF'
      # why function?: in real app with variation, depending on some inputs the user chose
      current.DF <- data.frame(Name = c("Name1", "Name2"), value1 = c(0,0), value2=c(0,0)) # example df
      rhandsontable(current.DF) 
    })
  }
    
  observeEvent(input$DataEditor, {
    # Here's the problem
    # won't get called when DataEditor is modified by the user
    browser() 
    return()
  })
  
}
shinyApp(ui,server)

CodePudding user response:

This works like this:

library(shiny)
library(rhandsontable)

ui <- fluidPage(
  actionButton('openModal', "Open Modal")
)

server <- function(input, output, session) {
  
  current.DF <- reactive(
    data.frame(Name = c("Name1", "Name2"), value1 = c(0,0), value2=c(0,0))
  )
  
  observeEvent(input$openModal, {
    irrelevant_condition <- FALSE # include that rhandsontable doesn't have to appear always
    if (irrelevant_condition == TRUE) {
      return(showModal(modalDialog("Choose some variables to display first")))
    } else {
      # display rhandsontable if user made a valid choice
      showModal(modalDialog(  
        rHandsontableOutput("DataEditor")
      ))
    }
  })
  
  output$DataEditor <- renderRHandsontable({
    rhandsontable(current.DF()) 
  })
  
  observeEvent(input$DataEditor, {
    print(input$DataEditor$changes)
  })
  
}
shinyApp(ui,server)

Is it what you want? For the dataframe which can change I would use a reactive value. If only some cells are changed you can use the set_data function, better.


EDIT Solving the problem raised in the comments:

  output$DataEditor <- renderRHandsontable({
    rhandsontable(current.DF()) %>% htmlwidgets::onRender(
      "function(el){var hot = this.hot; setTimeout(function(){hot.render();}, 1000)}"
    )
  })
  • Related