Switch between layouts reactively with shiny

后端 未结 1 1210
误落风尘
误落风尘 2020-12-20 03:26

How can I switch between page layouts in Shiny in response to user input? For example, I would like to switch between a sidebar layout to a wellpanel layout in order to hav

相关标签:
1条回答
  • 2020-12-20 03:48

    Hi you can't call an output twice (or more) in the ui, that's why this isn't working, instead you can do all the work in the server like this :

    library(shiny)
    
    shinyApp(
      shinyUI(
        fluidPage(
          radioButtons('layout', 'Layout:', choices=c('Sidebar', 'WellPanel'), inline=TRUE),
          uiOutput('general_ui')
        )
      ),
      shinyServer(function(input, output) {
        output$general_ui <- renderUI({
          if (input$layout == "Sidebar") {
            sidebarLayout(
              sidebarPanel(
                uiOutput('ui')
              ),
              mainPanel(
                plotOutput('plot')
              )
            )
          } else if (input$layout == "WellPanel") {
            fluidRow(
              column(12, plotOutput('plot')),
              column(12, wellPanel(uiOutput('ui')))
            )
          }
        })
    
        output$ui <- renderUI({
          list(
            checkboxInput('inp1', 'Some stuff'),
            sliderInput('inp2', 'Some more stuff', 0, 10, 5)
          )
        })
    
        output$plot <- renderPlot({ plot(1) })
      })
    )
    

    But there's a catch, when you switch between layout, the input widgets are reinitialized...

    But you can fix it with something like this :

    output$ui <- renderUI({
      list(
        checkboxInput('inp1', 'Some stuff'),
        if (is.null(input$inp2)) {
          sliderInput('inp2', 'Some more stuff', 0, 10, 5)
        } else {
          sliderInput('inp2', 'Some more stuff', 0, 10, input$inp2)
        }
      )
    })
    

    Before creating your widget, you'll have to check if the value already exists, in a more compact way than above you can do that :

    output$ui <- renderUI({
          list(
            checkboxInput(inputId = "inp1", label = 'Some stuff', value = input$inp1 %||% FALSE),
            sliderInput(inputId = "inp2", label = 'Some more stuff', min = 0, max = 10, value = input$inp2 %||% 5)
          )
        })
    

    With %||% function defined like this :

    `%||%` <- function(a, b) {
      if (!is.null(a)) a else b
    }
    
    0 讨论(0)
提交回复
热议问题