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)}"
)
})