From 79d8bdba1c5d14c7b00f51fdb76b171482d3628d Mon Sep 17 00:00:00 2001 From: pvictor Date: Sun, 16 Jun 2024 09:48:57 +0200 Subject: [PATCH] example filter grid --- DESCRIPTION | 2 +- R/gridstack.R | 4 +- examples/filter-grid.R | 113 +++++++++++++++++++++++++++++++++++++++++ man/gridstack.Rd | 3 ++ 4 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 examples/filter-grid.R diff --git a/DESCRIPTION b/DESCRIPTION index 472b20e..8849e98 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: gridstackr Title: Interactive grid layout with the JavaScript 'GridStack' Library -Version: 0.0.0.9100 +Version: 0.0.0.9200 Authors@R: c( person("Victor", "Perrier", email = "victor.perrier@dreamrs.fr", role = c("aut", "cre")), person("Fanny", "Meyer", role = "aut")) diff --git a/R/gridstack.R b/R/gridstack.R index baf2228..1971a21 100644 --- a/R/gridstack.R +++ b/R/gridstack.R @@ -28,6 +28,7 @@ #' @param class Additional class on top of '.grid-stack' to differentiate this instance. #' @param options List of options for the grid. #' @param bg Background color. +#' @param list_items A `list` of items created with [gs_item()] to be placed in the grid. An alternative to `...` to specify items. #' @inheritParams htmlwidgets::createWidget #' #' @@ -54,11 +55,12 @@ gridstack <- function(..., class = NULL, options = list(), bg = "#e5e7eb", + list_items = NULL, width = NULL, height = NULL, elementId = NULL) { - items <- list(...) + items <- c(list(...), list_items) rendered_items <- renderTags(x = items) x <- list( diff --git a/examples/filter-grid.R b/examples/filter-grid.R new file mode 100644 index 0000000..03d6ddd --- /dev/null +++ b/examples/filter-grid.R @@ -0,0 +1,113 @@ +library(data.table) +library(bslib) +library(gridstackr) +library(shiny) + + +my_pkgs <- c("shinyWidgets", "esquisse", "datamods", "shinylogs", "shinybusy", "fresh", "phosphoricons", "toastui", "apexcharter", "billboarder", "gfonts") + +pkgs <- tools::CRAN_package_db() +setDT(pkgs) + +pkgs <- pkgs[Package %in% my_pkgs] + + +card_pkg <- function(.list) { + card( + card_header(.list$Package, class = "bg-primary fw-bold"), + card_body( + tags$div(.list$Title), + tags$div(.list$Description) + ), + fill = FALSE, + height = "100%" + ) +} + +item_pkg <- function(pkg) { + gs_item(card_pkg(pkg), w = 3, id = pkg$Package) +} +item_pkg_all <- function(pkgs) { + lapply( + X = apply(pkgs, 1, as.list), + FUN = item_pkg + ) +} + +add_pkg <- function(pkg) { + gs_proxy_add("mygrid", card_pkg(pkg), options = list(w = 3, id = pkg$Package)) +} +add_pkg_all <- function(pkgs) { + lapply( + X = apply(pkgs, 1, as.list), + FUN = add_pkg + ) +} + + + +ui <- page_fluid( + tags$h2("Filter GridStack example"), + shinyWidgets::searchInput( + inputId = "search", + label = "Search grid:", + btnSearch = icon("magnifying-glass"), + btnReset = icon("xmark") + ), + gridstackOutput("mygrid"), + verbatimTextOutput("res") +) + +server <- function(input, output, session) { + + output$mygrid <- renderGridstack({ + gridstack( + minRow = 2, + cellHeight = "200px", + disableResize = TRUE, + disableDrag = TRUE, + list_items = item_pkg_all(pkgs) + ) + }) + + output$res <- renderPrint({ + data.table::rbindlist(input$mygrid_layout$children, fill = TRUE) + }) + + ### Method 1: Always remove items then put back items corresponding to search + # observeEvent(input$search, { + # gs_proxy_remove_all("mygrid") + # if (!isTruthy(input$search)) { + # add_pkg_all(pkgs) + # } else { + # pkgs_search <- pkgs[tolower(Description) %like% tolower(input$search)] + # add_pkg_all(pkgs_search) + # } + # }, ignoreNULL = FALSE, ignoreInit = TRUE) + + ### Method 2 : add or remove according to items in the frid + observeEvent(input$search, { + items_grid <- data.table::rbindlist(input$mygrid_layout$children, fill = TRUE) + pkgs_search <- pkgs[tolower(Description) %like% tolower(input$search)] + for (pkg in my_pkgs) { + if (pkg %in% pkgs_search$Package) { + if (pkg %in% items_grid$id) { + # already in grid + } else { + add_pkg(pkgs_search[Package == pkg]) + } + } else { + if (pkg %in% items_grid$id) { + gs_proxy_remove_item("mygrid", pkg) + } else { + # not in grid + } + } + } + + }, ignoreNULL = FALSE, ignoreInit = TRUE) + +} + +if (interactive()) + shinyApp(ui, server) diff --git a/man/gridstack.Rd b/man/gridstack.Rd index ca94a84..cea1e1a 100644 --- a/man/gridstack.Rd +++ b/man/gridstack.Rd @@ -22,6 +22,7 @@ gridstack( class = NULL, options = list(), bg = "#e5e7eb", + list_items = NULL, width = NULL, height = NULL, elementId = NULL @@ -75,6 +76,8 @@ It could also be a selector string, in this case widgets will be removed by drop \item{bg}{Background color.} +\item{list_items}{A \code{list} of items created with \code{\link[=gs_item]{gs_item()}} to be placed in the grid. An alternative to \code{...} to specify items.} + \item{width}{Fixed width for widget (in css units). The default is \code{NULL}, which results in intelligent automatic sizing based on the widget's container.}