Search code examples
rshinydatatablesdt

Hide a datatable row on click on R/Shiny


I would like to make a row of an R datatable disappear when the user clicks on it on Shiny.

Minimum, reproducible example:

ui <- fluidPage(DT::dataTableOutput("DTOut"))

server <- function(input, output) {
  
  output$DTOut <- DT::renderDataTable({datatable(iris)})
  
}

shinyApp(ui = ui, server = server)

Thank you!

EDIT : Following up on Stéphane's answer, his solution works but I can't integrate it into a Shiny app

ui <- fluidPage(DT::dataTableOutput("DTOut"))

server <- function(input, output) {
    output$DTOut <- DT::renderDataTable(datatable(iris),
        callback = JS("table.on('click', 'tbody tr', function() {", " table.row(this).remove().draw();", "})"))}

shinyApp(ui = ui, server = server)

Solution

  • library(DT)
    
    js <- c(
      "table.on('click', 'tbody tr', function() {",
      "  table.row(this).remove().draw();",
      "});"
    )
    
    datatable(iris, callback = JS(js))
    

    Edit

    The above works in Shiny if you set server=FALSE in renderDT. If you want to use server=TRUE (the default), you can proceed as follows:

    library(shiny)
    library(DT)
    
    
    callback <- c(
      "table.on('click', 'tbody tr', function() {",
      "  Shiny.setInputValue('clickedRow', $(this).index(), {priority: 'event'});",
      "});"
    )
    
    ui <- fluidPage(
      br(),
      DTOutput("dtable")
    )
    
    server <- function(input, output, session) {
      
      dat <- iris
      
      output$dtable <- renderDT({
        datatable(
          dat,
          selection = "none",
          callback = JS(callback)
        )
      })
      
      proxy <- dataTableProxy("dtable")
      
      observeEvent(input$clickedRow, {
        dat <<- dat[-(input$clickedRow + 1), ]
        # below, set rownames=FALSE if you set rownames=FALSE in datatable()
        replaceData(proxy, dat, rownames = TRUE, resetPaging = FALSE)
      })
      
    }
    
    shinyApp(ui, server)