Shiny DT Table Helpers
Code Properties
- Language: R
- Packages:
shiny,DT,htmltools,purrr,glue,dplyr
Overview
Collection of helper functions for creating feature-rich DataTables in Shiny applications, including download buttons, inline action buttons, and reusable table modules.
Code
DT Download Buttons
#' DT Export Buttons Configuration
#'
#' @param data Data frame for export configuration
#' @param filename Base filename for exports
#' @param escape_cols Columns to exclude (HTML content)
#'
#' @return List of button configurations
#' @export
dt_buttons <- function(data, filename = "data", escape_cols = NULL) {
export_cols <- seq_len(ncol(data))
if (!is.null(escape_cols)) {
export_cols <- setdiff(export_cols, escape_cols)
}
fileout <- paste0(filename, "-", Sys.Date())
list(
list(
extend = "copy",
text = '<i class="fa fa-copy"></i>',
titleAttr = "Copy to Clipboard",
exportOptions = list(
columns = export_cols,
modifier = list(selected = NULL)
)
),
list(
extend = "print",
text = '<i class="fa fa-print"></i>',
titleAttr = "Print",
autoPrint = FALSE,
exportOptions = list(
columns = export_cols,
modifier = list(selected = NULL)
)
),
list(
extend = "excel",
text = '<i class="fa fa-file-excel"></i>',
titleAttr = "Export to Excel",
title = fileout,
exportOptions = list(
columns = export_cols,
modifier = list(selected = NULL)
)
),
list(
extend = "csv",
text = '<i class="fa fa-file-csv"></i>',
titleAttr = "Export to CSV",
title = fileout,
exportOptions = list(
columns = export_cols,
modifier = list(selected = NULL)
)
),
list(
extend = "pdf",
text = '<i class="fa fa-file-pdf"></i>',
titleAttr = "Export to PDF",
orientation = "landscape",
pageSize = "LEGAL",
download = "open",
title = fileout,
exportOptions = list(columns = ":visible"),
modifier = list(selected = NULL)
),
list(
extend = "colvis",
text = '<i class="fa fa-columns"></i>',
titleAttr = "Column Visibility"
),
list(
extend = "pageLength",
text = '<i class="fa fa-list"></i>',
titleAttr = "Page Length"
)
)
}Inline Action Buttons
#' Create Inline Action Buttons for DT Rows
#'
#' @param ids Vector of row IDs
#' @param edit Include edit button
#' @param delete Include delete button
#' @param view Include view button
#'
#' @return Character vector of HTML button groups
#' @export
dt_inline_buttons <- function(ids, edit = TRUE, delete = TRUE, view = FALSE) {
purrr::map_chr(ids, function(id) {
buttons <- c()
if (view) {
buttons <- c(buttons, glue::glue(
'<button class="btn btn-info btn-sm view_btn" ',
'data-toggle="tooltip" title="View" id="{id}">',
'<i class="fa fa-eye"></i></button>'
))
}
if (edit) {
buttons <- c(buttons, glue::glue(
'<button class="btn btn-primary btn-sm edit_btn" ',
'data-toggle="tooltip" title="Edit" id="{id}">',
'<i class="fa fa-pencil"></i></button>'
))
}
if (delete) {
buttons <- c(buttons, glue::glue(
'<button class="btn btn-danger btn-sm delete_btn" ',
'data-toggle="tooltip" title="Delete" id="{id}">',
'<i class="fa fa-trash"></i></button>'
))
}
glue::glue(
'<div class="btn-group" role="group">{paste(buttons, collapse = "")}</div>'
)
})
}DT Table Module
#' DT Table Module UI
#'
#' @param id Module namespace ID
#'
#' @return Shiny UI element
#' @export
mod_datatable_ui <- function(id) {
ns <- shiny::NS(id)
htmltools::tagList(
DT::DTOutput(ns("table"))
)
}
#' DT Table Module Server
#'
#' @param id Module namespace ID
#' @param data Reactive data frame
#' @param filename Export filename base
#' @param caption Table caption
#' @param selection Row selection mode
#' @param actions Include action buttons column
#'
#' @return Reactive selected rows
#' @export
mod_datatable_server <- function(
id,
data,
filename = "data",
caption = NULL,
selection = "none",
actions = FALSE
) {
shiny::moduleServer(id, function(input, output, session) {
ns <- session$ns
table_data <- shiny::reactive({
shiny::req(data())
dat <- data()
if (actions && nrow(dat) > 0) {
action_btns <- dt_inline_buttons(seq_len(nrow(dat)))
dat <- cbind(Actions = action_btns, dat)
}
dat
})
output$table <- DT::renderDT({
shiny::req(table_data())
dat <- table_data()
escape_col <- if (actions) 1 else NULL
DT::datatable(
dat,
rownames = FALSE,
caption = caption,
selection = selection,
class = "stripe row-border compact",
escape = if (actions) -1 else TRUE,
extensions = c("Buttons", "Scroller"),
filter = "top",
options = list(
autoWidth = TRUE,
scrollX = TRUE,
scrollY = 500,
dom = "Blfrtip",
lengthMenu = list(
c(25, 50, 100, -1),
c("25", "50", "100", "All")
),
buttons = dt_buttons(dat, filename, escape_col),
columnDefs = list(
list(className = "dt-center", targets = "_all")
)
)
)
})
# return selected rows
shiny::reactive({
input$table_rows_selected
})
})
}Usage
# in UI
mod_datatable_ui("my_table")
# in Server
selected <- mod_datatable_server(
"my_table",
data = reactive({ mtcars }),
filename = "mtcars-export",
caption = "Motor Trend Car Road Tests",
actions = TRUE
)
# observe button clicks
shiny::observeEvent(input$`my_table-table_cell_clicked`, {
info <- input$`my_table-table_cell_clicked`
if (!is.null(info$value) && grepl("edit_btn", info$value)) {
# handle edit action
}
})Appendix
Note created on 2024-06-23 and last modified on 2024-12-13.
See Also
Backlinks
(c) No Clocks, LLC | 2024