4
votes

Example:

Following shiny example app.R file contains a selectizeInput UI. The selected elements can be removed by using options = list(plugins= list('remove_button')).

enter image description here

library(shiny)
library(dplyr)

ui= fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectizeInput(inputId= "cyl", label= "cyl", 
                     choices= sort(unique(mtcars$cyl)), 
                     selected= sort(unique(mtcars$cyl)),
                     multiple=T,
                     options = list(plugins= list('remove_button')))
    ),
    mainPanel(
      tableOutput("tab")
    )
  )
)

server= function(input, output) {
  df_filtered= reactive({
    mtcars %>%
    {if (is.null(input$cyl)) . else filter(., cyl %in% input$cyl)}
  })
  output$tab= renderTable(df_filtered())
}

shinyApp(ui, server)

Question:

Is there an selectize.js option accessible in shiny which adds a feature "remove all-at-once" instead of the "remove one-by-one" as shown in the example?

I studied the selectize.js docu but got stuck.

2
Do you want it integrated in the form or would a button below be sufficient?Tonio Liebrand
@BigDataScientist best-case integrated in the form.user2030503
If nobody comes up with an integrated way I could help out with the non-fancy way ;)Tonio Liebrand
You can hold down the delete button :). Seriously, I think you are out of luck. Let BDS write you a button. I looked at the code and that remove_button feature is relatively new, and there are not very many plug-ins at all yet. If someone was ambitious they could write a new plug in to do it of course, but it feels like it would be messy code.Mike Wise
@MikeWise thx for looking into. Appreciate your judgement.user2030503

2 Answers

4
votes

I think the walk around solution is to use reset_button, however the selected= option should be changed to minium (one option?) cause it is the reset value

library(shiny)
library(shinyjs)
library(dplyr)

ui= fluidPage(
  sidebarLayout(
    sidebarPanel(
      useShinyjs(),
      div(id = "form",
          selectizeInput(inputId = "cyl", 
                         label = "cyl",
                         choices = sort(unique(mtcars$cyl)), 
                         selected=sort(unique(mtcars$cyl))[1], multiple=TRUE)),
          actionButton("reset_input", "Reset")
    ),
    mainPanel(
      tableOutput("tab")
    )
  )
)

server= function(input, output) {

  observeEvent(input$reset_input, {
    shinyjs::reset("form")
  })

  df_filtered= reactive({
    mtcars %>%
    {if (is.null(input$cyl)) . else filter(., cyl %in% input$cyl)}
  })
  output$tab= renderTable(df_filtered())
}

shinyApp(ui, server)

After pressing the Reset button, all selected values are cleared at once and the primary value of selectizeInput is returned.

0
votes

I stumbled across this answer while looking for something else, and it was an issue I had to recently solve. Here is my solution, which does not require an additional button.

library(shiny)
library(shinyjs)
library(dplyr)

ui= fluidPage(
  sidebarLayout(
    sidebarPanel(
          selectizeInput(inputId = "cyl", 
                         label = "cyl",
                         choices = c("All", sort(unique(mtcars$cyl))),
                         multiple = TRUE,
                         options = list(placeholder = "All"))
          ),
    mainPanel(
      tableOutput("tab")
    )
  )
)


server= function(input, output) {

  # This bit will revert the multi select back to the placeholder.
  # You might want to change the filtering logic further down stream though (depending on what actually want to display).
  observe({
    if("All" %in% input$cyl) {
      updateSelectizeInput(session = getDefaultReactiveDomain(),
                           "cyl",
                           choices = c("All", sort(unique(mtcars$cyl))),
                           options = list(placeholder = "All"))
    }
  })

  df_filtered= reactive({
    mtcars %>%
    {if (is.null(input$cyl)) . else filter(., cyl %in% input$cyl)}
  })
  output$tab= renderTable(df_filtered())
}

shinyApp(ui, server)

You can add in the plugins= list('remove_button') to the options too, but it needs to be added to the ui part and the updateSelectizeInput() function.