Jack Tanner Jack Tanner - 3 months ago 17
R Question

Columns within uiOutput in Shiny

In Shiny, I create a UI dynamically in the server element using

renderUI
and
tagList
, and then display it using
uiOutput
. It works, but I'd like to break up the contents of
uiOutput
into columns. How do I do that?

Here's the (slightly abbreviated) Dynamic UI example from the Shiny gallery. Note how
output$ui
contains a
tagList
that ends up displaying as one column, but I want it to display as two.

Note that I can't call
column
inside
renderUI
.

library(shiny)

server <- shinyServer(function(input, output) {
output$ui <- renderUI({
if (is.null(input$input_type)) {return()}
tagList(list(div("Want this to be left column"),
switch(input$input_type,
"slider" = sliderInput("dynamic", "Want this to be right column",
min = 1, max = 20, value = 10),
"text" = textInput("dynamic", "Want this to be right column",
value = "starting value"),
"numeric" = numericInput("dynamic", "Want this to be right column",
value = 12),
"checkbox" = checkboxInput("dynamic", "Want this to be right column",
value = TRUE))))
})
output$input_type_text <- renderText({input$input_type})
output$dynamic_value <- renderPrint({str(input$dynamic)})
})

ui <- shinyUI(fluidPage(
titlePanel("Dynamically generated user interface components"),
wellPanel(selectInput("input_type", "Input type",
c("slider", "text", "numeric", "checkbox")
)),
wellPanel(uiOutput("ui")),
wellPanel(
tags$p("Input type:"),
verbatimTextOutput("input_type_text"),
tags$p("Dynamic input value:"),
verbatimTextOutput("dynamic_value")
)
))

shinyApp(ui = ui, server = server)

Answer

Instead of wrapping div and a selected widget into list and then into tagList (you don't need them both - one of them suffice)

tagList(list(div("Want this to be left column"), switch(...) ...)

create fluidRow and add two columns - one with the div and the another with switch:

fluidRow(column(6, div("Want this to be left column")),
         column(6, switch(input$input_type,
                        "slider" = sliderInput("dynamic", "Want this to be right column",
                                               min = 1, max = 20, value = 10),
                        "text" = textInput("dynamic", "Want this to be right column",
                                           value = "starting value"),
                        "numeric" =  numericInput("dynamic", "Want this to be right column",
                                                  value = 12),
                        "checkbox" = checkboxInput("dynamic", "Want this to be right column",
                                                   value = TRUE)
                  )
          )
        )

Full example:

library(shiny)

server <- shinyServer(function(input, output) {
  output$ui <- renderUI({
    if (is.null(input$input_type)) {return()}
    fluidRow(column(6, div("Want this to be left column")),
             column(6, switch(input$input_type,
                              "slider" = sliderInput("dynamic", "Want this to be right column",
                                                     min = 1, max = 20, value = 10),
                              "text" = textInput("dynamic", "Want this to be right column",
                                                 value = "starting value"),
                              "numeric" =  numericInput("dynamic", "Want this to be right column",
                                                        value = 12),
                              "checkbox" = checkboxInput("dynamic", "Want this to be right column",
                                                         value = TRUE)
             )
             )
    )
  })
  output$input_type_text <- renderText({input$input_type})
  output$dynamic_value <- renderPrint({str(input$dynamic)})
})

ui <- shinyUI(fluidPage(
  titlePanel("Dynamically generated user interface components"),
  wellPanel(selectInput("input_type", "Input type",
                        c("slider", "text", "numeric", "checkbox")
  )),
  wellPanel(uiOutput("ui")),
  wellPanel(
    tags$p("Input type:"),
    verbatimTextOutput("input_type_text"),
    tags$p("Dynamic input value:"),
    verbatimTextOutput("dynamic_value")
  )
))

shinyApp(ui = ui, server = server)