Skip to content

Instantly share code, notes, and snippets.

@nanxstats
Created April 9, 2022 07:08
Show Gist options
  • Save nanxstats/2f79e09060657e143b19d068bd6d79b8 to your computer and use it in GitHub Desktop.
Save nanxstats/2f79e09060657e143b19d068bd6d79b8 to your computer and use it in GitHub Desktop.
Paginated news list with DT/DataTables
# Generate mock data -----------------------------------------------------------
set.seed(42)
k <- 100
df <- data.frame(
title = unlist(purrr::map2(
.x = stringr::word(stringi::stri_rand_lipsum(k), start = 1, end = 10),
.y = rep("#", k),
.f = function(.x, .y) as.character(htmltools::tags$a(.x, href = .y))
)),
time = as.POSIXct(unlist(
charlatan::ch_date_time(n = k)
), origin = "1970-01-01 00:00.00 UTC"),
inst = sample(charlatan::ch_company(n = 20), size = k, replace = TRUE),
type = sample(
c("backgrounders", "media advisories", "news releases", "readouts", "speeches"),
size = k, replace = TRUE
),
desc = stringi::stri_rand_lipsum(k),
stringsAsFactors = FALSE
)
df$metadata <- paste(df$time, df$inst, df$type, sep = "&nbsp; | &nbsp;")
df <- df[, c("title", "time", "inst", "type", "metadata", "desc")]
df <- df[order(df$time, decreasing = TRUE), ]
# Create filter widgets using crosstalk ----------------------------------------
df_shared <- crosstalk::SharedData$new(df)
ui_filters <- list(
crosstalk::filter_select(
id = "selector-type",
label = "News type",
sharedData = df_shared,
group = ~type
),
crosstalk::filter_select(
id = "selector-inst",
label = "Institution",
sharedData = df_shared,
group = ~inst
)
)
# Create table widget using DT -------------------------------------------------
ui_dt <- DT::datatable(
df_shared,
options = list(
columnDefs = list(list(visible = FALSE, targets = c(1, 2, 3))),
dom = "<'top'fil>rt<'bottom'p><'clear'>",
language = list(search = "Filter items:"),
pageLength = 3,
headerCallback = DT::JS(
"function(thead, data, start, end, display){",
" $(thead).remove();",
"}"
)
),
class = c("table", "table-striped", "table-hover", "table-borderless"),
style = "bootstrap4",
rownames = FALSE,
escape = FALSE,
width = "850px",
selection = "none"
)
# Define custom CSS styles for table elements ----------------------------------
css_dt <- textConnection("
table td { display: block; }
table td:nth-child(1) { font-size: 1.375rem; }
table td:nth-child(2) { color: #555; }
div.dataTables_wrapper div.dataTables_filter { display: inline; text-align: left; }
div.dataTables_wrapper div.dataTables_filter label { font-weight: 700; }
div.dataTables_wrapper div.dataTables_info { display: inline; margin-left: 1ch; padding-top: 0; }
div.dataTables_wrapper div.dataTables_length { display: inline; margin-left: 1ch; padding-left: 1ch; border-left: 1px solid;}
div.dataTables_wrapper div.dataTables_length label { font-weight: 700; }
div.dataTables_wrapper div.dataTables_paginate ul.pagination { justify-content: center; }
")
# Compose widgets into an HTML page --------------------------------------------
card <- function(title, ...) {
htmltools::tags$div(
class = "card",
htmltools::tags$div(class = "card-header", title),
htmltools::tags$div(class = "card-body", ...)
)
}
html <- shiny::fluidPage(
title = "DT News List Example",
theme = bslib::bs_theme(version = 5, primary = "#295376"),
lang = "en",
shiny::includeCSS(css_dt),
shiny::fluidRow(
shiny::column(
width = 10, offset = 1,
shiny::fluidRow(
shiny::column(
width = 3,
card(
title = "Filter news",
htmltools::tags$p(
"Use filters to search for the most recent news articles."
),
ui_filters
)
),
shiny::column(
width = 9,
ui_dt
)
)
)
)
)
htmltools::browsable(html)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment