根据URL参数制作闪亮的应用UI

时间:2018-01-31 15:24:50

标签: r shiny shiny-server

我想根据网址参数为我的应用创建替代用户界面。具体来说,我想使用shinyWidgets中的下拉选择器输入而不是checkboxGroupInput,但仅当参数mini = TRUE通过URL传递时

library(shinyWidgets)

nazwy=c('Warszawa', 'Krakow', 'Gdansk')

ui<-fluidPage(
 if (mini) {
    pickerInput(inputId = "miasto", choices = nazwy,multiple = TRUE)
 } else {
  checkboxGroupInput('miasto', nazwy)
 })

我能以某种方式使用conditionalPanel来做,或者我是唯一的选择吗?

或者,我可以根据窗口宽度显示pickerInput或checkboxGroupInput吗?

更新

下面给出的选项1是我最初问题的工作答案,使得UI依赖于URL。对于这种特殊情况,选项2是更好的解决方案 - 使UI适应窗口大小。但是,为了使选项2正常工作,需要另一个变量来存储选择,这样每次调整窗口大小时,select / pickerInput都不会返回默认选择。我相应地编辑了代码。

1 个答案:

答案 0 :(得分:1)

以下四个选项:

  1. 取决于URL,renderUI
  2. 取决于窗口宽度,renderUI
  3. 取决于窗口宽度,conditionalPanel(无法正常工作)
  4. 取决于窗口宽度,shinyjs
  5. 选项1:取决于URL,renderUI

    可以使其依赖于URL,例如参见here。以下是一个示例实现:

    library(shinyWidgets)
    library(shiny)
    
    nazwy=c('Warszawa', 'Krakow', 'Gdansk')
    
    ui<-fluidPage(
      uiOutput('myUI')
    )
    
    
    server <- function(input,output,session) {
    
      output$myUI <- renderUI({
        query <- parseQueryString(session$clientData$url_search)
        if (!is.null(query$mini)) {
          if(query$mini==TRUE)
          {
            pickerInput(inputId = "miasto", choices = nazwy,multiple = TRUE)
          }
          else
          {
            checkboxGroupInput('miasto', 'choose: ',nazwy)
          }
        } 
        else 
        {
          checkboxGroupInput('miasto', 'choose: ',nazwy)
        }
      }) 
    }
    
    shinyApp(ui,server,options=list(port=7777))
    

    同时尝试http://127.0.0.1:7777/http://127.0.0.1:7777/?mini=TRUE

    选项2:取决于窗口宽度,renderUI

    如果你想让它取决于窗口宽度,这里有一个可能的解决方案:

    library(shinyWidgets)
    library(shiny)
    
    nazwy=c('Warszawa', 'Krakow', 'Gdansk')
    
    ui<-fluidPage(
      tags$head(tags$script('
                                    var dimension = [0, 0];
                            $(document).on("shiny:connected", function(e) {
                            dimension[0] = window.innerWidth;
                            dimension[1] = window.innerHeight;
                            Shiny.onInputChange("dimension", dimension);
                            });
                            $(window).resize(function(e) {
                            dimension[0] = window.innerWidth;
                            dimension[1] = window.innerHeight;
                            Shiny.onInputChange("dimension", dimension);
                            });
                            ')),
      uiOutput('myUI')
    )
    
    
    server <- function(input,output) {
       output$myUI <- renderUI({
         req(input$dimension)
         if (input$dimension[1]<800) {
            pickerInput(inputId = "miasto", choices = nazwy, 
                         selected=isolate(selected_cities()),multiple = TRUE)
         } else {
            checkboxGroupInput('miasto', 'choose: ',
                         choices=nazwy, selected=isolate(selected_cities()))
         }
       })
    
       #store selected value to pass on resizing
       selected_cities<-reactive(input$miasto) 
    
    }
    
    shinyApp(ui,server)
    

    选项3:窗口宽度+ conditionalPanel。 注意:不能按预期工作。

       library(shinyWidgets)
        library(shiny)
    
        nazwy=c('Warszawa', 'Krakow', 'Gdansk')
    
        ui<-fluidPage(
          tags$head(tags$script('var dimension = [0, 0];
                                $(document).on("shiny:connected", function(e) {
                                dimension[0] = window.innerWidth;
                                dimension[1] = window.innerHeight;
                                Shiny.onInputChange("dimension", dimension);
                                });
                                $(window).resize(function(e) {
                                dimension[0] = window.innerWidth;
                                dimension[1] = window.innerHeight;
                                Shiny.onInputChange("dimension", dimension);
                                });
                                ')),
          conditionalPanel(condition = 'input.dimension[0]>1000',
                           pickerInput(inputId = "miasto", choices = nazwy,multiple = TRUE)
          ),
          conditionalPanel(condition = 'input.dimension[0]<=1000',
                           checkboxGroupInput('miasto', 'choose: ',nazwy))
        )
    
    
        server <- function(input,output) {
    
        }
    
        shinyApp(ui,server)
    

    选项4:窗口宽度+ shinyjs

    library(shinyWidgets)
    library(shiny)
    library(shinyjs)
    
    nazwy=c('Warszawa', 'Krakow', 'Gdansk')
    
    ui<-fluidPage(
      tags$head(tags$script('var dimension = [0, 0];
                            $(document).on("shiny:connected", function(e) {
                            dimension[0] = window.innerWidth;
                            dimension[1] = window.innerHeight;
                            Shiny.onInputChange("dimension", dimension);
                            });
                            $(window).resize(function(e) {
                            dimension[0] = window.innerWidth;
                            dimension[1] = window.innerHeight;
                            Shiny.onInputChange("dimension", dimension);
                            });
                            ')),
      div(id='div1',pickerInput(inputId = "miasto", choices = nazwy,multiple = TRUE)),
      shinyjs::hidden(div(id='div2',checkboxGroupInput('miasto', 'choose: ',nazwy))),
      useShinyjs()
    )
    
    
    server <- function(input,output) {
      observeEvent(input$dimension,ignoreNULL=T,{
        if (input$dimension[1]>1000) {
          shinyjs::show('div1')
          shinyjs::hide('div2')    
        } else {
          shinyjs::show('div2')
          shinyjs::hide('div1')   
        }
      }) 
    }
    
    shinyApp(ui,server)