Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expand/Collapse Shiny selectInput function

I would like to find a resource that would allow my Shiny selectInput function to expand/collapse based on the category headings that I have created. I have searched through some bootstrap resources, but am not yet successful. Please forgive my minimal working example, I acknowledge that there may be more efficient ways to provide a MWE. Thanks for any advice you can offer.

library(shiny)
library(tidyverse)
#create a quick dataset to plot
schools <-  as.data.frame(table(
    c('Adams', 'Van Buren', 'Clinton', 'Douglas', 'Edwards', 
              'Franklin', 'Grant', 'Harrison', 'Ignatius', 'Justice', 
              'Kellogg', 'Lincoln'), 
    dnn = list("school")))

enrollment <- as.data.frame(table(
    c(300, 305, 265, 400, 500, 450, 475, 900, 800, 850, 1200, 1500), 
    dnn = list("enrollment")))

schoolsDataframe <- schools %>% 
    bind_cols(enrollment) %>% 
    select(school, enrollment)

#define data elements for selectInput choices argument
elem <- c('Adams', 'Van Buren', 'Clinton', 'Douglas')
mid <- c('Edwards', 'Franklin', 'Grant')
high <- c('Harrison', 'Ignatius', 'Justice')
multi <- c('Kellogg', 'Lincoln')

# Define UI 
ui <- fluidPage(
    tags$style(".optgroup-header { color: #FFFFFF !important; background: #000000 !important; }"),
    # Application title
    titlePanel("Expandable selectInput"),

    # Sidebar with a select input
    sidebarLayout(
        sidebarPanel(
            selectInput(inputId = 'schoolsInput',
                        label = 'Select a school',
                        choices = list('Elementary' = elem, 
                                       'Middle' = mid, 
                                       'High' = high, 
                                       'Multi-level' = multi), 
                        selectize = TRUE)
        ),

        # Show a plot 
        mainPanel(
           plotOutput("myPlot")
        )
    )
)

# Define server logic required to draw a plot
server <- function(input, output) {

    output$myPlot <- renderPlot({
        #filter the data based on selectInput
schoolsDataframe <- schoolsDataframe %>% 
    filter(school == input$schoolsInput)
        # draw the plot
ggplot(data = schoolsDataframe, 
       mapping = aes(x = school, 
                     y = enrollment))+
    geom_col()
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

enter image description here

enter image description here

like image 695
Susan Switzer Avatar asked Aug 06 '26 06:08

Susan Switzer


2 Answers

library(shiny)

onInitialize <- '
function(){
  this.$dropdown_content.on("mousedown", function(e){
    e.preventDefault(); 
    return false;
  }); 
  $("body").on("click", ".optgroup-header", function(){
    $(this).siblings().toggle();
  });
}'

onDropdownOpen <- '
function(){
  setTimeout(function(){
    $(".optgroup .option").hide();
  }, 0);
}'

shinyApp(

  ui = fluidPage(
    selectizeInput("state", "Choose a state:",
                list(`East Coast` = list("NY", "NJ", "CT"),
                     `West Coast` = list("WA", "OR", "CA"),
                     `Midwest` = list("MN", "WI", "IA")),
                options = list(
                  onInitialize = I(onInitialize),
                  onDropdownOpen = I(onDropdownOpen)
                )
    ),
    textOutput("result")
  ),

  server = function(input, output) {
    output$result <- renderText({
      paste("You chose", input$state)
    })
  }

)

enter image description here

like image 80
Stéphane Laurent Avatar answered Aug 08 '26 19:08

Stéphane Laurent


The answer from Stéphane Laurent is fantastic, but it only works when there is one single dropdown on the page. If you have more than one dropdown, here is a slightly modified version of his answer that works with multiple inputs:

library(shiny)

onInitialize <- '
$(function() {
  $("body").on("mousedown", ".selectize-dropdown-content", function(e){
    e.preventDefault(); 
    return false;
  }); 
  $("body").on("click", ".optgroup-header", function(){
    $(this).siblings().toggle();
  });
});'

onDropdownOpen <- '
function(el){
  setTimeout(function(){
    $(el).find(".optgroup .option").hide();
  }, 0);
}'

shinyApp(
  
  ui = fluidPage(
    tags$script(HTML(onInitialize)),
    selectizeInput("state", "Choose a state:",
                   list(`East Coast` = list("NY", "NJ", "CT"),
                        `West Coast` = list("WA", "OR", "CA"),
                        `Midwest` = list("MN", "WI", "IA")),
                   options = list(
                     onDropdownOpen = I(onDropdownOpen)
                   )
    ),
    textOutput("result"),
    selectizeInput("state2", "Choose a state:",
                   list(`East Coast` = list("NY", "NJ", "CT"),
                        `West Coast` = list("WA", "OR", "CA"),
                        `Midwest` = list("MN", "WI", "IA")),
                   options = list(
                     onDropdownOpen = I(onDropdownOpen)
                   )
    ),
    textOutput("result2")
  ),
  
  server = function(input, output) {
    output$result <- renderText({
      paste("You chose", input$state)
    })
    output$result2 <- renderText({
      paste("You chose", input$state2)
    })
  }
  
)
like image 27
DeanAttali Avatar answered Aug 08 '26 20:08

DeanAttali



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!