My DT output table seems to get a random table ID when it is rendered. I can see the ID when I inspect the webpage:
In this case, the id is DataTables_Table_0
. Is there a way to explicitly set the ID?
I've added a couple of buttons to my table to select all visible rows when the table has been filtered, and the operation requires using the table ID in the renderDT()
function like this:
library(shiny)
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(),
mainPanel(
DTOutput('dt_output')
)
)
)
server <- function(input, output, session) {
output$dt_output <- renderDT({
datatable(mtcars,
extensions = c('Select', 'Buttons'),
selection = "none",
options = list(
select = list(style = "multi", items = "row"),
dom = "Blfrtip",
deferRender = TRUE,
buttons = list(
list(extend = 'selectAll',
text = "Select All",
action = DT::JS(
"function () {
var table = $('#DataTables_Table_0').DataTable();
table.rows({ search: 'applied'}).deselect();
table.rows({ search: 'applied'}).select();}"
)),
list(extend = 'selectNone',
text = "Clear All",
action = DT::JS(
"function () {
var table = $('#DataTables_Table_0').DataTable();
table.rows({ search: 'applied'}).select();
table.rows({ search: 'applied'}).deselect();}"
))
)
)
)
}, server = FALSE)
}
shinyApp(ui = ui, server = server)
Since the ID is random and I don't know it before the table is rendered, it's a problem if I'm trying to do this on multiple tables in the same application. Perhaps there is another way to achieve the behavior I want? For example, I want to search for "merc" then select all the filtered rows with one click:
Is there another way to achieve this which doesn't require knowing the IDs, or is there a way to specify the IDs?
Actually you don't need the id
but any form of CSS selector which addresses your table unambiguously. Thus, you can use your self selected id
for the output element and from there select the inner table.
Looking at the source code you see that <table>
is a grandchild of <div id='dt_output'>
so you can use #dt_output table
which selects any <table>
element nested inside (at any level) the unique div
with id dt_output
(or being even more explicit by selecting only a grandchild of <div id='dt_output'>
by #dt_output > div > table
).
Thus, replace your JS piece by the following selector and everything works out smoothly:
let table = $('#dt_output table').DataTable()