12

I need to add a CSS class to a series of textOutput in a shiny app.

When I try, e.g.:

textOutput('text', class = 'error')

I get:

Warning: Error in textOutput: unused argument (class = "error")

It is possible to alter the CSS of the id of that textOutput. However, my ids are generated dynamically, so that is not a good solution. A possible alternative would be to 'grab' all ids that begin with/contain "error" (e.g. "error1", "error2"), but I am not sure if this is possible within my CSS style sheet.

1

4 Answers 4

20

A simple was to do this is using the shiny tagAppendAttributes function. I normally find it easier to pipe the HTML output of shiny output objects into it like so:

library(shiny)
library(magrittr)

textOutput("foo") %>% 
  tagAppendAttributes(class = 'error')

Which produces the following output, which contains the error class.

<div class="shiny-text-output error" id="foo"></div>

You can also do the same thing with styles

textOutput("foo") %>% 
  tagAppendAttributes(style= 'color:green;')
<div id="foo" class="shiny-text-output" style="color:green;"></div>
Sign up to request clarification or add additional context in comments.

3 Comments

please do you know if we could also use the same technique "tagAppendAttributes" to add the style of a single specific table? I just tried the following but it doesn't do anything: tableOutput("retail_dashboard_ratios_table") %>% tagAppendAttributes(style = '{ border-collapse: collapse; font-size:20px; color:red;}')
Try it without the braces: tableOutput("retail_dashboard_ratios_table") %>% tagAppendAttributes(style = 'border-collapse: collapse; font-size:20px; color:red;')
Note that tagAppendAttributes() is not from the {shiny} package, it's re-exported by {shiny} from the {htmltools} package. So you'd require library(htmltools) if you're just looking for this function.
6

The various *Output functions return objects with attributes you can manipulate, class among them -- just inspect their structure with the str() function:

foo <- textOutput("foo")
print(foo)
# <div id="foo" class="shiny-text-output"></div>
str(foo)
# List of 3
#  $ name    : chr "div"
#  $ attribs :List of 2
#   ..$ id   : chr "foo"
#   ..$ class: chr "shiny-text-output"
#  $ children: list()
#  - attr(*, "class")= chr "shiny.tag"

This means that we can overwrite the class set by the textOutput function like so:

foo$attribs$class <- "foo bar"
print(foo)
# <div id="foo" class="foo bar"></div>

If you want to preserve existing classes while adding new ones, you can use the paste() function, and wrap it all in a custom add_classes() function for convenience:

add_classes <- function(el, classes) {
  el$attribs$class <- paste(el$attribs$class, classes)
  el
}

foo <- add_classes(foo, "baz qux")
print(foo)
# <div id="foo" class="foo bar baz qux"></div>

Comments

4

Maybe wrapping it in a div with the required class helps?:

library(shiny)

ui <- fluidPage(tags$div(id = 'wrap_div',
                         class = 'error',
                         textOutput('text')))

server <- function(input, output, session) {
  output$text <- renderText ({
    "My text"
  })
}

shinyApp(ui = ui, server = server)

Comments

-2

The answer is to use a CSS selector like:

[id^="error"] {
   ...
}

This is placed within your external css file within the app directory...usually named style.css.

1 Comment

Could you please expand this answer ? Where do you put this code ? The full code would be appreciated.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.