The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Multi-Select Filter with glasstabs

Overview

glassMultiSelect() is an animated multi-select dropdown for Shiny. It can be used inside a glassTabsUI() layout or completely on its own in any Shiny page.

The widget behaves like a standard Shiny input: input$<inputId> stores the selected values, and input$<inputId>_style stores the active indicator style.

It also supports server-side updates with updateGlassMultiSelect().

Basic usage

library(shiny)
library(glasstabs)

fruits <- c(Apple = "apple", 
            Banana = "banana", 
            Cherry = "cherry",
            Mango  = "mango", 
            Peach  = "peach")

ui <- fluidPage(
  useGlassTabs(),
  glassMultiSelect("pick", fruits),
  verbatimTextOutput("out")
)

server <- function(input, output, session) {
  output$out <- renderPrint(input$pick)
}

shinyApp(ui, server)

Shiny inputs produced

Input Type Value
input$<inputId> character vector Currently selected values
input$<inputId>_style character Active checkbox style

Initial selection

# All selected (default)
glassMultiSelect("f", fruits)

# Subset pre-selected
glassMultiSelect("f", fruits, selected = c("apple", "cherry"))

# Nothing pre-selected
glassMultiSelect("f", fruits, selected = character(0))

Checkbox styles

Three indicator styles are available via check_style:

# Bordered box + animated tick (default)
glassMultiSelect("f", fruits, check_style = "checkbox")

# Tick only — minimal, no box border
glassMultiSelect("f", fruits, check_style = "check-only")

# Solid coloured box — each option gets its own hue
glassMultiSelect("f", fruits, check_style = "filled")

By default, a style switcher row is shown inside the dropdown so the user can change the style at runtime. Hide it with show_style_switcher = FALSE:

glassMultiSelect("f", fruits,
  check_style         = "check-only",
  show_style_switcher = FALSE          # lock the style silently
)

Custom hues for the filled style

When check_style = "filled", hues are auto-assigned evenly around the colour wheel. Override them with a named integer vector of HSL hue angles (0–360):

glassMultiSelect("f", fruits,
  check_style = "filled",
  hues = c(apple = 0, banana = 50, cherry = 340, mango = 30, peach = 20)
)

Show / hide UI chrome

All three interactive chrome elements can be toggled independently. Defaults are all TRUE:

glassMultiSelect("f", fruits,
  show_style_switcher = FALSE,   # hide the Check / Box / Fill row
  show_select_all     = FALSE,   # hide the "Select all" row
  show_clear_all      = FALSE    # hide the "Clear all" footer link
)

Filter tag pills with glassFilterTags()

Place a glassFilterTags() container anywhere on the page to show the active selections as removable tag pills. The JS engine keeps them in sync automatically — clicking × on a tag deselects that option.

ui <- fluidPage(
  useGlassTabs(),
  glassMultiSelect("cat", fruits, show_style_switcher = FALSE),
  glassFilterTags("cat")    # can be placed anywhere, even in a different tab pane
)

You can place multiple glassFilterTags("cat") containers for the same filter — all will stay in sync.

Server-side access

Read the selection directly from input$<inputId> and the style from input$<inputId>_style:

server <- function(input, output, session) {

  # Direct access
  observe({
    message("Selected: ", paste(input$pick, collapse = ", "))
    message("Style: ",    input$pick_style)
  })
}

Reactive helper

If you want a small convenience wrapper, use glassMultiSelectValue():

server <- function(input, output, session) {
  ms <- glassMultiSelectValue(input, "pick")

  observe({
    message("Selected: ", paste(ms$selected(), collapse = ", "))
    message("Style: ", ms$style())
  })
}

Updating choices and selection from the server

updateGlassMultiSelect() can update: - available choices - current selection - active style

It follows Shiny-style update semantics:

ui <- fluidPage(
  useGlassTabs(),
  actionButton("subset", "Keep first 3 fruits"),
  actionButton("pick2", "Select 2 fruits"),
  actionButton("clear", "Clear"),
  actionButton("fill", "Switch to filled style"),
  glassMultiSelect("pick", fruits),
  verbatimTextOutput("out")
)

server <- function(input, output, session) {
  output$out <- renderPrint(input$pick)

  observeEvent(input$subset, {
    updateGlassMultiSelect(
      session,
      "pick",
      choices = fruits[1:3]
    )
  })

  observeEvent(input$pick2, {
    updateGlassMultiSelect(
      session,
      "pick",
      selected = c("apple", "cherry")
    )
  })

  observeEvent(input$clear, {
    updateGlassMultiSelect(
      session,
      "pick",
      selected = character(0)
    )
  })

  observeEvent(input$fill, {
    updateGlassMultiSelect(
      session,
      "pick",
      check_style = "filled"
    )
  })
}

shinyApp(ui, server)

When choices is updated without selected, the widget keeps the intersection of the current selection and the new choice set.

Theming

Built-in presets

glassMultiSelect("f", fruits, theme = "dark")   # default
glassMultiSelect("f", fruits, theme = "light")  # white panel, dark text

Custom theme with glass_select_theme()

Supply only the colors you want to change:

# One field — accent colour only
glassMultiSelect("f", fruits,
  theme = glass_select_theme(accent_color = "#f59e0b")
)

# Two fields
glassMultiSelect("f", fruits,
  theme = glass_select_theme(
    text_color   = "#1e293b",
    accent_color = "#2563eb"
  )
)

# All four fields
glassMultiSelect("f", fruits,
  theme = glass_select_theme(
    bg_color     = "#1a0a2e",
    border_color = "#a855f7",
    text_color   = "#ede9fe",
    accent_color = "#a855f7"
  )
)
Argument What it controls
bg_color Dropdown panel and trigger button background
border_color Border colour
text_color Main text and label colour
accent_color Tick marks, badge, checked highlights, Clear all link

Standalone usage — no tabs required

glassMultiSelect() is fully independent of the tab widget. You only need useGlassTabs() for the CSS and JS:

library(shiny)
library(glasstabs)

sales <- data.frame(
  region  = c("North","North","South","South","East","West"),
  product = c("Alpha","Beta","Alpha","Gamma","Beta","Alpha"),
  revenue = c(42000, 31000, 27000, 55000, 38000, 61000)
)

ui <- fluidPage(
  useGlassTabs(),
  glassMultiSelect("region",  c(North="North", South="South",
                                East="East",   West="West"),
                   show_style_switcher = FALSE),
  glassMultiSelect("product", c(Alpha="Alpha", Beta="Beta", Gamma="Gamma"),
                   show_style_switcher = FALSE,
                   check_style = "check-only"),
  glassFilterTags("region"),
  glassFilterTags("product"),
  tableOutput("tbl")
)

server <- function(input, output, session) {
  filtered <- reactive({
    sales[sales$region  %in% (input$region  %||% unique(sales$region)) &
          sales$product %in% (input$product %||% unique(sales$product)), ]
  })
  output$tbl <- renderTable(filtered())
}

shinyApp(ui, server)

Multiple dropdowns on one page

Each glassMultiSelect() is scoped to its own inputId and works independently. When one dropdown is open it automatically floats above all others:

ui <- fluidPage(
  useGlassTabs(),
  glassMultiSelect("a", c(X = "x", Y = "y", Z = "z")),
  glassMultiSelect("b", c(P = "p", Q = "q", R = "r"),
                   check_style = "filled",
                   show_style_switcher = FALSE)
)

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.