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