You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使Shiny App UI根据URL参数或窗口宽度切换输入组件?

Shiny UI Switching: URL Parameters & Window Width

Great question! Let’s break down your two main concerns one by one, with practical code examples for each scenario.

1. Switching UI via URL Parameter (mini=TRUE)

You absolutely can use either conditionalPanel or renderUI for this—each has its own use case:

Option 1: renderUI (Server-Side Approach)

This is the more flexible option if you need to tie the URL parameter to other server-side logic. We’ll read the URL query string in the server, then dynamically render the right input component:

library(shiny)
library(shinyWidgets)

nazwy <- c('Warszawa', 'Krakow', 'Gdansk')

ui <- fluidPage(
  uiOutput("city_selector")
)

server <- function(input, output, session) {
  # Grab the `mini` parameter from the URL
  is_mini_mode <- reactive({
    query_params <- parseQueryString(session$clientData$url_search)
    # Convert to boolean, handle cases where parameter is missing or malformed
    isTRUE(as.logical(query_params$mini))
  })
  
  output$city_selector <- renderUI({
    if (is_mini_mode()) {
      pickerInput(inputId = "miasto", choices = nazwy, multiple = TRUE)
    } else {
      checkboxGroupInput('miasto', 'Wybierz miasto:', choices = nazwy)
    }
  })
}

shinyApp(ui, server)

Option 2: conditionalPanel (Client-Side Approach)

If you don’t need server-side logic for this switch, conditionalPanel lets you handle everything directly in the UI using JavaScript to read the URL. This keeps the server code cleaner:

library(shiny)
library(shinyWidgets)

nazwy <- c('Warszawa', 'Krakow', 'Gdansk')

ui <- fluidPage(
  # Show pickerInput when URL has `mini=TRUE`
  conditionalPanel(
    condition = "window.location.search.includes('mini=TRUE')",
    pickerInput(inputId = "miasto", choices = nazwy, multiple = TRUE)
  ),
  # Show checkboxGroupInput otherwise
  conditionalPanel(
    condition = "!window.location.search.includes('mini=TRUE')",
    checkboxGroupInput('miasto', 'Wybierz miasto:', choices = nazwy)
  )
)

server <- function(input, output, session) {
  # Add your app logic here
}

shinyApp(ui, server)

Pro tip: If you need to handle case variations (like Mini=true), adjust the JS condition to use toLowerCase(): window.location.search.toLowerCase().includes('mini=true')

2. Switching UI Based on Window Width

Yes, you can absolutely swap components based on window size! The key gotcha here is that resizing the window will trigger a re-render of conditionalPanel components, which can reset user selections. To fix this, we’ll store the selected value in a reactive variable and sync it across both input components.

Here’s the refined solution that preserves user choices:

library(shiny)
library(shinyWidgets)

nazwy <- c('Warszawa', 'Krakow', 'Gdansk')

ui <- fluidPage(
  # Show pickerInput for mobile (window < 768px, a common breakpoint)
  conditionalPanel(
    condition = "window.innerWidth < 768",
    pickerInput(inputId = "miasto_mobile", choices = nazwy, multiple = TRUE)
  ),
  # Show checkboxGroupInput for desktop (window >= 768px)
  conditionalPanel(
    condition = "window.innerWidth >= 768",
    checkboxGroupInput('miasto_desktop', 'Wybierz miasto:', choices = nazwy)
  )
)

server <- function(input, output, session) {
  # Reactive variable to store the user's selected cities (persists across switches)
  selected_cities <- reactiveVal(nazwy[1]) # Default to first city
  
  # Sync mobile input changes to the reactive variable and desktop input
  observeEvent(input$miasto_mobile, {
    selected_cities(input$miasto_mobile)
    updateCheckboxGroupInput(session, "miasto_desktop", selected = input$miasto_mobile)
  })
  
  # Sync desktop input changes to the reactive variable and mobile input
  observeEvent(input$miasto_desktop, {
    selected_cities(input$miasto_desktop)
    updatePickerInput(session, "miasto_mobile", selected = input$miasto_desktop)
  })
  
  # Initialize both inputs with the default value
  observe({
    updatePickerInput(session, "miasto_mobile", selected = selected_cities())
    updateCheckboxGroupInput(session, "miasto_desktop", selected = selected_cities())
  })
  
  # Example: Print selected cities to the console for testing
  observe({
    cat("Selected cities:", paste(selected_cities(), collapse = ", "), "\n")
  })
}

shinyApp(ui, server)

By using separate input IDs for mobile/desktop and syncing their values to selected_cities, we ensure users don’t lose their selections when resizing the window.

Quick Recap

  • URL parameter switch: Both renderUI (server-side) and conditionalPanel (client-side) work. Choose renderUI if you need server logic tied to the parameter, conditionalPanel for a lighter client-only approach.
  • Window width switch: Use conditionalPanel with a reactive variable to store selections—this prevents resets and keeps the user experience smooth.

内容的提问来源于stack exchange,提问作者MonikaP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:38:33