Create a div using htmltools::withtags

I am trying to convert this html card using bootstrap to be used in a R shiny app using htmltools. Below is the actual html code and followed by the htmltools which I am using to convert it to be used inside an shiny app. I am able to create it with tables but not with divs.Where am I wrong here.

HTML CODE

<div class="card border-success mb-3" style="max-width: 18rem;">
  <div class="card-header bg-transparent border-success">Header</div>
  <div class="card-body text-success">
  <h5 class="card-title">Success card title</h5>
  <p class="card-text">Some quick example text to build on the card title and make up the bulk of the cards content.</p>
</div>
<div class="card-footer bg-transparent border-success">Footer</div>
</div>

R HTMLWIDGETS

cards = htmltools::withTags(
  div(class = "card border-success mb-3",
      div(class="card-header bg-transparent border-success"),
      div(class="card-body text-success" ,
      h3(class="card-title","header"),
      p(class="card-text","text")
   ),
      div(class= "card-footer bg-transparent border-success")
  ))

print(cards)
 
)

First know that you can use existing html code as-is in a shiny app UI using HTML(). See https://shiny.rstudio.com/articles/html-tags.html#raw-html

For you example, it seems like your htmltools code gives the right html code.
What is the issue exaclty ? I am not sure to correctly understand... :thinking:

@snt: Your code is not a best practice, while implementing custom UI. See below an example where you can pass custom arguments to edit your card:

my_card <- function(...) {
  htmltools::withTags(
    div(
      class = "card border-success mb-3",
      div(class = "card-header bg-transparent border-success"),
      div(
        class = "card-body text-success",
        h3(class = "card-title", "title"),
        p(class = "card-text", ...)
      ),
      div(class = "card-footer bg-transparent border-success", "footer")
    )
  )
}

my_card("blablabla. PouetPouet Pouet.")

You could also replace the title by an argument, same thing for the footer...

But the main problem is here: since your card is a bootstrap 4 element, shiny does not have the default dependencies (only for bootstrap 3). therefore, you need to provide them yourself:

library(shiny)
ui <- fluidPage(
  title = "Hello Shiny!",
  includeCSS(path = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"),
  fluidRow(
    column(
      width = 6,
      align = "center",
      br(),
      my_card("blablabla. PouetPouet Pouet.")
    )
  )
)

shinyApp(ui, server = function(input, output) { })

Your card should display, even though it would need serious improvement :slight_smile:

Alternatively, you could use a cleaner way by creating an htmlDependency with hmtltools, related to your card and attach it with attachDependencies ... see below:


# handle dependency
card_css <- "bootstrap.min.css"
bs4_card_dep <- function() {
  htmltools::htmlDependency(
    name = "bs4_card",
    version = "1.0",
    src = c(href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/"),
    stylesheet = card_css
  )
}


# create the card
my_card <- function(...) {
  cardTag <- htmltools::withTags(
    div(
      class = "card border-success mb-3",
      div(class = "card-header bg-transparent border-success"),
      div(
        class = "card-body text-success",
        h3(class = "card-title", "title"),
        p(class = "card-text", ...)
      ),
      div(class = "card-footer bg-transparent border-success", "footer")
    )
  )
  
  # attach dependencies
  htmltools::attachDependencies(cardTag, bs4_card_dep())
  
}


# run shiny app 
ui <- fluidPage(
  title = "Hello Shiny!",
  fluidRow(
    column(
      width = 6,
      align = "center",
      br(),
      my_card("blablabla. PouetPouet Pouet.")
    )
  )
)

shinyApp(ui, server = function(input, output) { })

Hope it helps

David

2 Likes

Thanks @DGranjon. This was helpful

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.