I have an rhandsontable and wish to trigger an event each time a cell is clicked, such that I can identify the cell which was clicked.
From what I've seen, this can only be done using JS.
I've tried using the basic .click()
event, but that uses an argument-free function and this
is the HTML itself, with no "selectedCell" property or what have you.
library(shiny)
library(shinyjs)
library(rhandsontable)
ui <- fluidPage(
useShinyjs(),
actionButton("redraw", "Redraw"),
rHandsontableOutput("test")
)
server <- function(input, output, session) {
output$test <- renderRHandsontable({
input$redraw # force re-rendering if desired
runjs("$('#test').click(function() {
console.log(this)
});")
rhandsontable(data.frame(a = 1:2, b = 3:4))
})
}
shinyApp(ui, server)
Looking at the handsontable documentation, I've found the afterOnCellMouseDown
event, which seems adequate for my use-case, taking a function with a coords
argument which informs me of the selected cell. I should be able to use this in conjunction with Shiny.onInputChange
to let my app identify the clicked cell.
However, I can't figure out the JS I need to run to bind to the afterOnCellMouseDown
event. As I mentioned, using $('#test')
gives me the HTML and I don't know how to access the hot
itself.
With the app below, the coordinates of the clicked cell are sent to input$clickedCell
, a list of the form list(row = i, col = j)
.
library(shiny)
library(rhandsontable)
library(htmlwidgets)
jsCode <- c(
"function(el, x) {",
" Handsontable.hooks.add('afterOnCellMouseDown', function(event, coords, TD){",
" Shiny.setInputValue('clickedCell', coords, {priority: 'event'});",
" });",
"}"
)
ui <- fluidPage(
rHandsontableOutput("test")
)
server <- function(input, output, session) {
output$test <- renderRHandsontable({
rhandsontable(data.frame(a = 1:2, b = 3:4)) %>% onRender(jsCode)
})
observe({print(input$clickedCell)})
}
shinyApp(ui, server)
This is applied to all handsontable
instances of the app. I don't know how to target a specific one (I think this is not possible).