Search code examples
javascriptrshinyreactable

Independent click events with reactable (selection, click and doubleclick)


My shiny app has one table (I'm using reactable).

It must allow for multiple selection (to download selected rows), a click event which triggers a modal window (independent on whether the clicked row is selected or not, and a doubleclick event on the last column.

My working example does the following:

  1. Allows multiple selection and download,
  2. Modal when row clicked (except column '.select') but (3) the doubleclick event does not work.

Below is another example with the doubleclick event working on its own.

How can I have make the doubleclick event work in the first example?

(first working example)

library(shiny)
library(tidyverse)
library(reactable)

ui <- fluidPage(
  downloadButton("dload", "Download (*.csv)"),
  fluidRow(
    column(12, align = 'center',reactableOutput("tbl"))
  )
)
server <- function(input, output, session) {
  
  data = reactive({mtcars %>% tibble::rownames_to_column('car')})
  
  output$tbl = renderReactable(
    reactable(
      data(),
      columns = list(
        carb = colDef(
          sticky = "right",
          sortable = FALSE,
          cell = function(value, index, name){
            icon("globe",
                 ondblclick = sprintf("window.alert('double clicked cell %s in column %s')", index, name)
            )
          })
      ),
      selection = "multiple",
      compact = T,
      highlight = T,
      onClick = JS("function(rowInfo, colInfo, column) {
        Shiny.setInputValue('qwert', {id:rowInfo.id, nonce:Math.random()})
        if (column.id !== 'carb') {
          return
        }
                    }"),
      rowStyle = list(cursor = "pointer")
    )
  )
  
  observeEvent(input$qwert, {
    print(input$qwert)
    id <- input$qwert$id
    row_nr <- as.numeric(id)+1
    showModal(
      modalDialog(
        size = 'l',
        easyClose = T,
        title = data()$car[row_nr],
        "some text"
      )
    )
  })
  
  sel = reactive({getReactableState("tbl","selected")})

  output$dload <- downloadHandler(
    filename = function() {
      paste("d"," ", Sys.time(), ".csv", sep = "")
    },
    content = function(file) {
     write.csv(data()[sel(),],file)# write.csv(dd(), file, row.names = FALSE)
    }
  )
}
shinyApp(ui = ui, server = server)

(my second working example - doubleclick event)

library(shiny)
library(reactable)

ui <- fillPage(
reactableOutput("t")
)

server <- function(input, output) {

data <- cbind(
  MASS::Cars93[1:5, c("Manufacturer", "Model", "Type", "Price")],
  d = NA
)

output$t <- renderReactable({
reactable(
  data,
  selection = "multiple",
  columns = list(
    d = colDef(
      sortable = FALSE,
      cell = function(value, index, name){
        icon("globe", class = "cor", style = "font-size: 14px;",
            ondblclick = sprintf("window.alert('double clicked cell %s in column %s')", index, name)
    )
  })
)
)})

}
shinyApp(ui,server)

Solution

  • You can replace the JS in the first example with

    function(rowInfo, colInfo, column) {
        if (colInfo.id !== 'carb') {
            Shiny.setInputValue('qwert', {id:rowInfo.id, nonce:Math.random()});
        }
    }
    

    Then the double-click event will work on the last column.

    enter image description here