How do I render html content for boxes inside a loop in Shiny?

Viewed 131

I'm trying to build a Shiny dashboard that responds to user inputs by displaying a series of boxes with nicely formatted html content. Because the user's selections determine how many boxes will be displayed, I'm using lapply() to render the boxes on the server side and then pushing the results of that process to uiOutput() on the ui side.

It's working with one crucial exception: the html content isn't appearing in the boxes. I don't get any error messages or warnings; I just don't get any content inside the boxes, other than the reactive titles.

What follows is a simple, reproducible example. What do I need to do differently to get contents to appear inside the boxes in the body of the ui?

library(shiny)
library(shinydashboard)
library(shinyWidgets)

dat <- data.frame(food = c("hamburger", "hot dog", "pizza", "kale salad"),
                  price = c("$2.50", "$1.50", "$2.00", "$3.50"),
                  peanut_gallery = c("beefy!", "dachsund!", "pie time!", "healthy!"),
                  stringsAsFactors = FALSE)

### UI ###

header <- dashboardHeader(title = "My Food App", titleWidth = 400)

sidebar <- dashboardSidebar(width = 400,

  fluidRow(column(width = 12,

    checkboxGroupButtons(
      inputId = "my_food",
      label = "Pick a food",
      choices = c("hamburger", "hot dog", "pizza", "kale salad"),
      selected = NULL
    )

  ))

)

body <- dashboardBody(

  fluidRow(

    uiOutput("little_boxes")

  )

)

ui <- dashboardPage(header, sidebar, body, skin = "black")

### SERVER ###

server <- function(input, output) {

  output$little_boxes <- renderUI({

    req(input$my_food)

    lapply(input$my_food, function(x) {

      df <- dat[dat$food == x,]

      contents <- div(h4(df$peanut_gallery),
                      h5(df$price),
                      p(sprintf("Isn't %s great? I love to eat it.", df$food)))

      box(title = df$food,
          width = 6,
          background = "red",
          collapsible = TRUE, collapsed = TRUE,
          uiOutput(contents) )

    })

  })

}

## RUN ##

shinyApp(ui, server)

1 Answers

Try :

htmltools::tagList(contents) 

instead of

uiOutput(contents)

enter image description here

Related