Аргумент dt
функции действия кнопки (function(e,dt,node,config)
) - это API экземпляра DataTables для хоста DataTable: https://datatables.net/reference/option/buttons.buttons.action
В функции initComplete
function(settings)
этот объект является settings.oInstance.api()
, который называется table
в коде JS (var table = settings.oInstance.api();
).
Замените function(e,dt,node,config)
на function(e,table,node,config)
и переместите код JS в тело функции действия кнопки:
action = DT::JS(
c(
"function ( e, table, node, config ) {",
" var cross = '<span style=\"color:red; font-size:18px\"><i class=\"glyphicon glyphicon-remove\"></i></span>'",
" table.$('tr.selected').addClass('x');",
" table.$('tr.selected')",
" .each(function(){$(this).find('td').eq(1).html(cross);});",
"}"
)
)
EDIT
Вот полный код обновленного решения:
library(shiny)
library(DT)
removal <- c(
"function(e, table, node, config) {",
" table.$('tr.selected').addClass('x').each(function(){",
" var td = $(this).find('td').eq(1)[0];",
" var cell = table.cell(td);",
" cell.data('remove');",
" });",
" table.rows().deselect();",
" var excludedRows = [];",
" table.$('tr').each(function(i, row){",
" if($(this).hasClass('x')){excludedRows.push(parseInt($(row).attr('id')));}",
" });",
" Shiny.setInputValue('excludedRows', excludedRows);",
"}"
)
restore <- c(
"function(e, table, node, config) {",
" table.$('tr').removeClass('x').each(function(){",
" var td = $(this).find('td').eq(1)[0];",
" var cell = table.cell(td);",
" cell.data('ok');",
" });",
" Shiny.setInputValue('excludedRows', null);",
"}"
)
render <- c(
'function(data, type, row, meta){',
' if(type === "display"){',
' return "<span style=\\\"color:red; font-size:18px\\\"><i class=\\\"glyphicon glyphicon-" + data + "\\\"></i></span>";',
' } else {',
' return data;',
' }',
'}'
)
ui <- fluidPage(
tags$head(
tags$style(HTML(
".x { color: rgb(211,211,211); font-style: italic; }"
))
),
fluidRow(
column(
6,
tags$label("Excluded rows"),
verbatimTextOutput("excludedRows")
),
column(
6,
tags$label("Included rows"),
verbatimTextOutput("includedRows")
)
),
br(),
DTOutput('mytable')
)
server <- function(input, output,session) {
dat <- cbind(Selected = "ok", mtcars[1:6,], id = 1:6)
output[["mytable"]] <- renderDT({
datatable(dat,
extensions = c("Select", "Buttons"),
options = list(
rowId = JS(sprintf("function(data){return data[%d];}", ncol(dat))),
columnDefs = list(
list(visible = FALSE, targets = ncol(dat)),
list(className = "dt-center", targets = "_all"),
list(targets = 1, render = JS(render))
),
dom = "B",
buttons = list("copy", "csv",
list(
extend = "collection",
text = 'Deselect',
action = JS(removal)
),
list(
extend = "collection",
text = 'Restore',
action = JS(restore)
)
)
)
)
}, server = FALSE)
output$excludedRows <- renderPrint({
input[["excludedRows"]]
})
output$includedRows <- renderPrint({
setdiff(1:nrow(dat), input[["excludedRows"]])
})
}
shinyApp(ui, server)
«Отменить выделение» с сервера блестящий: пример
library(shiny)
library(DT)
library(shinyjs)
js <- paste(
"var table = $('#mytable').find('table').DataTable();",
"var rowsindices = [%s];",
"for(var i=0; i<rowsindices.length; ++i){",
" var idx = rowsindices[i];",
" table.cell(idx, 1).data('remove');",
" table.row(idx).select();",
"}",
"$('.dt-button.buttons-collection').eq(0).click();",
sep = "\n"
)
removal <- c(
"function(e, table, node, config) {",
" table.$('tr.selected').addClass('x').each(function(){",
" var td = $(this).find('td').eq(1)[0];",
" var cell = table.cell(td);",
" cell.data('remove');",
" });",
" table.rows().deselect();",
" var excludedRows = [];",
" table.$('tr').each(function(i, row){",
" if($(this).hasClass('x')){excludedRows.push(parseInt($(row).attr('id')));}",
" });",
" Shiny.setInputValue('excludedRows', excludedRows);",
"}"
)
restore <- c(
"function(e, table, node, config) {",
" table.$('tr').removeClass('x').each(function(){",
" var td = $(this).find('td').eq(1)[0];",
" var cell = table.cell(td);",
" cell.data('ok');",
" });",
" Shiny.setInputValue('excludedRows', null);",
"}"
)
render <- c(
'function(data, type, row, meta){',
' if(type === "display"){',
' return "<span style=\\\"color:red; font-size:18px\\\"><i class=\\\"glyphicon glyphicon-" + data + "\\\"></i></span>";',
' } else {',
' return data;',
' }',
'}'
)
ui <- fluidPage(
useShinyjs(),
tags$head(
tags$style(HTML(
".x { color: rgb(211,211,211); font-style: italic; }"
))
),
fluidRow(
column(
6,
tags$label("Excluded rows"),
verbatimTextOutput("excludedRows")
),
column(
6,
tags$label("Included rows"),
verbatimTextOutput("includedRows")
)
),
br(),
actionButton("go", "Deselect rows 1, 2, 3"),
br(),
DTOutput('mytable')
)
server <- function(input, output,session) {
dat <- cbind(Selected = "ok", mtcars[1:6,], id = 1:6)
output[["mytable"]] <- renderDT({
datatable(dat,
extensions = c("Select", "Buttons"),
options = list(
rowId = JS(sprintf("function(data){return data[%d];}", ncol(dat))),
columnDefs = list(
list(visible = FALSE, targets = ncol(dat)),
list(className = "dt-center", targets = "_all"),
list(targets = 1, render = JS(render))
),
dom = "B",
buttons = list("copy", "csv",
list(
extend = "collection",
text = 'Deselect',
action = JS(removal)
),
list(
extend = "collection",
text = 'Restore',
action = JS(restore)
)
)
)
)
}, server = FALSE)
output$excludedRows <- renderPrint({
input[["excludedRows"]]
})
output$includedRows <- renderPrint({
setdiff(1:nrow(dat), input[["excludedRows"]])
})
observeEvent(input[["go"]], {
rows <- c(1,2,3) - 1
runjs(sprintf(js, paste0(rows, collapse=",")))
})
}
shinyApp(ui, server)