I wish to remove the all/none checkbox from a Reactable table used in a Shiny app. For a regular R script, an answer was suggested here.
However this solution fails with:
Warning in renderWidget(instance) : Ignoring prepended content; prependContent can't be used in a Shiny render call
The code below fails to remove the checkbox with the error mentioned above. So, how do I remove the all/none checkbox of a Reactable table in a Shiny app.
library(reactable)
library(htmlwidgets)
javascript <- JS('
document.querySelector(\'.rt-select-input[aria-label="Select all rows"]\').parentElement.parentElement.style.display="none";
')
ui <- fluidPage(reactableOutput("table")
)
server <- function(input, output, session) {
output$table <- renderReactable({
e <- reactable(iris,
onClick = "select",
selection = "multiple")
(p <- prependContent(e, onStaticRenderComplete(javascript)))
})
}
shinyApp(ui, server)
This can be achieved by a sneaky workaround using shiny's javascript events and the shinyjs
package.
js.code
defining the js function that'll add an event handler to the shiny:visualchange
event.useShinyjs()
use the shinyjs package.extendShinyjs
defining the js function in order to be used.js$hideSelectAll("table")
add the event handler to the table.delay(100, runjs('$( "#table" ).trigger( "shiny:visualchange" );'))
delay the call to the event handler in order to allow for the table to refresh.I tried the shiny:value
event but it didn't work it supposedly should've been executed whenever the output component is rendered but sadly it didn't.
library(reactable)
library(shiny)
library(shinyjs)
# you'll need to pass the id that you provided to reactableOutput(id)
js.code <- '
shinyjs.hideSelectAll = function(id){
$("#"+id).on("shiny:visualchange", function({currentTarget}) {
currentTarget = currentTarget.querySelector(".rt-select-input[aria-label=\'Select all rows\']")
if(currentTarget) currentTarget.parentElement.parentElement.style.display="none";
});
}
'
ui <- fluidPage(reactableOutput("table"),
useShinyjs(debug=TRUE),
extendShinyjs(text = js.code, functions = c("hideSelectAll"))
)
server <- function(input, output, session) {
output$table <- renderReactable({
reactable(iris,
onClick = "select",
selection = "multiple")
})
js$hideSelectAll("table")
delay(100, runjs('$( "#table" ).trigger( "shiny:visualchange" );'))
#runjs('$( "#table" ).trigger( "shiny:visualchange" );')
}
shinyApp(ui, server)
library(reactable)
library(shiny)
library(shinyjs)
js.code <- '
document.querySelector(\'.rt-select-input[aria-label="Select all rows"]\').parentElement.parentElement.style.display="none";
'
ui <- fluidPage(reactableOutput("table"),
useShinyjs(debug=TRUE)
)
server <- function(input, output, session) {
output$table <- renderReactable({
reactable(iris,
onClick = "select",
selection = "multiple")
})
delay(100, runjs(js.code))
}
shinyApp(ui, server)
Even refreshing the data doesn't show the select all button. it appears that my first code isn't optimal :( but I'm leaving it as a reference.
ui <- fluidPage(reactableOutput("table"),
actionButton("button", "refresh"),
tags$head(tags$script(HTML('
setTimeout(()=>{
document.querySelector(\'#table .rt-select-input[aria-label="Select all rows"]\').parentElement.parentElement.style.display="none";
}, 200)
')))
)
server <- function(input, output, session) {
output$table <- renderReactable({
reactable(iris,
onClick = "select",
selection = "multiple")
})
observeEvent(input$button, {
output$table <- renderReactable({
reactable(mtcars,
onClick = "select",
selection = "multiple")
})
})
}
shinyApp(ui, server)