Reputation: 546
I’m trying to create a datatable with pagination in R with checkboxes that are preselected. Other examples (eg here) do not account for pagination.
In the following example, there checkbox status gets reset when you return to a page. In addition, the variable excludedrows does not count the rows checked on other pages.
library(shiny)
library(DT)
ui = fluidPage(
tags$script(HTML('$(document).on("click", "input", function () {
var checkboxes = document.getElementsByName("row_selected");
var checkboxesChecked = [];
for (var i=0; i<checkboxes.length; i++) {
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i].value);
}}
Shiny.onInputChange("checked_rows",checkboxesChecked);
})')),
verbatimTextOutput("excludedRows"),
DTOutput('myDT')
)
server = function(input, output) {
mymtcars_reactive <- reactive(mtcars)
output$myDT <- renderDataTable({
mymtcars <- mymtcars_reactive()
mymtcars[["Select"]] <- paste0('<input type="checkbox" name="row_selected" value=',1:nrow(mymtcars),' checked>')
datatable(mymtcars,selection = "multiple",
options = list(pageLength = 14,
lengthChange = FALSE,
stateSave = TRUE),
rownames= FALSE,
escape=F)
})
output$excludedRows <- renderPrint({
intersect(input$checked_rows,1:nrow(mymtcars_reactive()))
})
}
shinyApp(ui,server, options = list(launch.browser = TRUE)
Upvotes: 3
Views: 2265
Reputation: 84529
Here is a way:
library(shiny)
library(DT)
mymtcars <- mtcars
mymtcars[["Select"]] <- paste0('<input type="checkbox" name="row_selected" value=',1:nrow(mymtcars),' checked>')
mymtcars[["_id"]] <- paste0("row_", seq(nrow(mymtcars)))
callback <- c(
sprintf("table.on('click', 'td:nth-child(%d)', function(){",
which(names(mymtcars) == "Select")),
" var checkbox = $(this).children()[0];",
" var $row = $(this).closest('tr');",
" if(checkbox.checked){",
" $row.removeClass('excluded');",
" }else{",
" $row.addClass('excluded');",
" }",
" var excludedRows = [];",
" table.$('tr').each(function(i, row){",
" if($(this).hasClass('excluded')){",
" excludedRows.push(parseInt($(row).attr('id').split('_')[1]));",
" }",
" });",
" Shiny.setInputValue('excludedRows', excludedRows);",
"});"
)
ui = fluidPage(
verbatimTextOutput("excludedRows"),
DTOutput('myDT')
)
server = function(input, output) {
output$myDT <- renderDT({
datatable(
mymtcars, selection = "multiple",
options = list(pageLength = 5,
lengthChange = FALSE,
rowId = JS(sprintf("function(data){return data[%d];}",
ncol(mymtcars)-1)),
columnDefs = list( # hide the '_id' column
list(visible = FALSE, targets = ncol(mymtcars)-1)
)
),
rownames = FALSE,
escape = FALSE,
callback = JS(callback)
)
}, server = FALSE)
output$excludedRows <- renderPrint({
input[["excludedRows"]]
})
}
shinyApp(ui,server, options = list(launch.browser = TRUE))
Upvotes: 3