I am trying to determine if it is possible for a shiny
DataTable
to have row selection disabled for certain rows.
Using the selection
parameter of DT::datatable
I can pre-select rows, determine whether the user selects rows or columns or both, and disable selection entirely, but it isn't clear to me if I can indicate specific rows to exclude. Is this possible?
Regards
With the Select
extension you can do:
library(DT)
library(shiny)
dat <- iris[1:17,]
rowCallback <- c(
"function(row, data, displayNum, displayIndex){",
" var indices = [0, 2, 4, 15];",
" if(indices.indexOf(displayIndex) > -1){",
" $(row).find('td').addClass('notselectable');",
" }",
"}"
)
shinyApp(
ui = fluidPage(
DTOutput("table")
),
server = function(input, output, session) {
output[["table"]] <- renderDT({
dat %>%
datatable(options = list(
rowCallback = JS(rowCallback),
select = list(style = "multi", selector = "td:not(.notselectable)")
),
extensions = "Select", selection = "none"
)
}, server = FALSE)
}
)
But if you need the indices of the selected rows in input$table_rows_selected
, you have to code in JavaScript for that:
callback <- c(
"var id = $(table.table().node()).closest('.datatables').attr('id');",
"table.on('click', 'tbody', function(){",
" setTimeout(function(){",
" var indexes = table.rows({selected:true}).indexes();",
" var indices = Array(indexes.length);",
" for(var i = 0; i < indices.length; ++i){",
" indices[i] = indexes[i];",
" }",
" Shiny.setInputValue(id + '_rows_selected', indices);",
" }, 0);",
"});"
)
shinyApp(
ui = fluidPage(
DTOutput("table")
),
server = function(input, output, session) {
output[["table"]] <- renderDT({
dat %>%
datatable(
callback = JS(callback),
options = list(
rowCallback = JS(rowCallback),
select = list(style = "multi", selector = "td:not(.notselectable)")
),
extensions = "Select", selection = "none"
)
}, server = FALSE)
observe({
print(input[["table_rows_selected"]])
})
}
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With