【问题标题】:Expand/Collapse Shiny selectInput function展开/折叠闪亮的 selectInput 功能
【发布时间】:2023-04-06 05:10:01
【问题描述】:

我想找到一个资源,允许我的 Shiny selectInput 函数根据我创建的类别标题展开/折叠。我已经搜索了一些引导资源,但还没有成功。请原谅我的最小工作示例,我承认可能有更有效的方法来提供 MWE。感谢您提供的任何建议。

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)

【问题讨论】:

标签: javascript r shiny shinybs selectinput


【解决方案1】:
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)
    })
  }

)

【讨论】:

    【解决方案2】:

    Stéphane Laurent 的回答非常棒,但它仅在页面上有一个下拉菜单时才有效。如果您有多个下拉列表,这里是他的答案的略微修改版本,适用于多个输入:

    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)
        })
      }
      
    )
    

    【讨论】:

      【解决方案3】:

      这是你的一个开始,虽然它可能不是你想要的。我认为您需要一个基于学校类型(小学、中学...)的动态选择列表。这是一种您可以使用 2 个选择列表执行此操作的方法,其中较低的选择列表是动态的,响应上部选择列表中的选择。

      我还尝试简化您的数据设置。您可以复制/粘贴代码来运行它。

      library(shiny)
      library(tidyverse)
      
      #define data elements 
      schools <- data.frame (schoolName=  c('Adams', 'Van Buren', 'Clinton', 'Douglas', 'Edwards','Franklin', 'Grant', 'Harrison', 'Ignatius', 'Justice', 'Kellogg', 'Lincoln'),
                            schoolType = c('Elementary','Elementary','Elementary','Elementary','Middle','Middle','Middle','High','High','High','Multi-level','Multi-level'),
                            schoolEnrollment = c(300, 305, 265, 400, 500, 450, 475, 900, 800, 850, 1200, 1500))
      
      # 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 = 'schoolType',
                        label = 'Select a School Type',
                        choices = list('Elementary',
                                       'Middle', 
                                       'High', 
                                       'Multi-level'), 
                        ),
            selectInput("schoolName", "Select School:","Elementary"),
          ),
      
          # Show a plot 
          mainPanel(
            plotOutput("myPlot")
          )
        )
      )
      
      # Define server logic required to draw a plot
      server <- function(input, output, session) {
      
        # Set up the selection for counties
        observe ({
          selectionSchoolNames <- sort(unique(unlist(subset(schools$schoolName,schools$schoolType==input$schoolType))))
          updateSelectInput(session, "schoolName", choices = selectionSchoolNames)
        })
      
        output$myPlot <- renderPlot({
          #filter the data based on selectInput
          schoolsDataframe <- schools %>% 
            filter(schoolType == input$schoolType)
          # draw the plot
          ggplot(data = schoolsDataframe, 
                 mapping = aes(x = schoolName, 
                               y = schoolEnrollment))+
            geom_col()
        })
      }
      
      # Run the application 
      shinyApp(ui = ui, server = server)
      

      【讨论】:

      • 感谢您提供这个想法。
      猜你喜欢
      • 1970-01-01
      • 2012-08-31
      • 2018-03-05
      • 2020-08-24
      • 2020-05-10
      • 1970-01-01
      • 2023-03-10
      • 2019-11-06
      • 1970-01-01
      相关资源
      最近更新 更多