css to set table class to table-condensed (bootstrap)

2,266 views
Skip to first unread message

Vincent Nijs

unread,
Oct 21, 2013, 9:04:26 PM10/21/13
to shiny-...@googlegroups.com
Perhaps a bit off-topic but ...

I am using pander for conditional formatting of tables in a Shiny app. Pander creates the relevant markdown and then I use markdownToHTML to create the html the app will display (see command below).

html <- markdownToHTML(text = fancyTab, stylesheet="www/fancyTab.css")

mardownToHTML allows you to specify a css file to apply when creating the html. I like boostrap's 'table-condensed' class and would like to apply that. I assume there is a simple way to put that in a css file but I haven't been able to find it. I resorted to the following hack. Any better alternatives?

html <- gsub("<table>","<table class='table table-condensed'>", html)

Screenshot attached.


pander_formatting.png

Ramnath Vaidyanathan

unread,
Oct 22, 2013, 7:49:41 PM10/22/13
to shiny-...@googlegroups.com
Why don't you use jQuery to dynamically add the `table-condensed` class to the HTML. You might be able to add this using tag$script.

Stéphane Laurent

unread,
Oct 23, 2013, 6:18:45 PM10/23/13
to shiny-...@googlegroups.com
I'm very interested about this. It would be helpful if you share some details about the way you use. Where have you find the fancyTab.css file ? Do you use uiOutput() to render the table ? Do you generate your table with pandoc.table(..., style="rmarkdown")

Vincent Nijs

unread,
Oct 24, 2013, 3:04:49 AM10/24/13
to shiny-...@googlegroups.com
Ramnath: I don't know any jquery so sub (rather than gsub) will work for now I guess.

Stephane: I use this to bold the largest absolute value in each row of a factor loading matrix. The code is across a few files in my app (not good :) ) but this is pretty much how it works.

fancyTable <- function() {

res <- factorAnalysisReactive()

abs_res <- abs(res)
row_max <- apply(abs_res, 1, max)
ind_max <- which(abs_res == row_max , arr.ind = TRUE)
emphasize.strong.cells(ind_max)

html <- markdownToHTML(text = pander.return(res, style='rmarkdown'), stylesheet="www/fancyTab.css")
html <- sub("<table>","<table class='table table-condensed'>", html)
}

then use HTML(fancyTable())  in your tabPanel

There is actually nothing in my fancyTab.css file right now :) I am pretty happy with bootstrap's table-condense formatting.

I woudn't use this approach for big tables (i.e, > a few 100 rows) but for my purposes it works nicely.

in 

Screenshot attached.


Stéphane Laurent

unread,
Oct 24, 2013, 5:09:26 AM10/24/13
to shiny-...@googlegroups.com
Thank you. 

I do like this and that works very well, except for one point :

          output[[pandoctable]] <- renderUI({ # test data summary in each tab 
            ... create a table named bbb...
            out <- pandoc.table.return(bbb, style="rmarkdown", emphasize.strong.cols=1, emphasize.cols=2)
            html <- markdownToHTML(text = out)
            Encoding(html) <- "UTF-8"
            HTML(html)
          })

and uiOutput("pandoctable") in ui.R. But there is the following problem, the table is splitted whereas it is not too wide:

time:06
Batch
DRSVA005AResult7.57.6
temperature5°C ± 3°C
StatusPASSPASS
DRSVA009AResult7.67.7
temperature5°C ± 3°C
StatusPASSPASS

Table: Table continues below

9
7.7
5°C ± 3°C
PASS
7.7
5°C ± 3°C
PASS

Stéphane Laurent

unread,
Oct 24, 2013, 5:13:23 AM10/24/13
to shiny-...@googlegroups.com
Oops the solution is easy :  pandoc.table.return(bbb, style="rmarkdown", emphasize.strong.cols=1, emphasize.cols=2, split.tables=Inf)


time:03612182436
Batch
DNHPAFA001Result0.970.900.880.880.990.960.93
temperature-20°C-20°C-70°C-70°C-70°C-70°C
StatusPASSPASSPASSPASSPASSPASSPASS
DNHPAFA002Result0.930.821.000.800.910.971.00
temperature-20°C-20°C-70°C-70°C-70°C-70°C
StatusPASSPASSPASSPASSPASSPASSPASS
DNHPAFA003Result0.980.810.970.881.060.980.93
temperature-20°C-20°C-70°C-70°C-70°C-70°C
StatusPASSPASSPASSPASSPASSPASSPASS
DNHPAFA004Result0.890.900.951.010.850.880.93
temperature-20°C-20°C-20°C-20°C-20°C-20°C
StatusPASSPASSPASSPASSPASSPASSPASS


Stéphane Laurent

unread,
Oct 24, 2013, 5:22:01 AM10/24/13
to shiny-...@googlegroups.com

Using your method:

time:069
Batch
DRSVA005AResult7.57.67.7
temperature5°C ± 3°C
5°C ± 3°C
StatusPASSPASSPASS
DRSVA009AResult7.67.77.7
temperature5°C ± 3°C
5°C ± 3°C
StatusPASSPASSPASS

Thank you very much !

Stéphane Laurent

unread,
Oct 24, 2013, 5:41:20 AM10/24/13
to shiny-...@googlegroups.com
Please do you know an easy way to draw a rectangle border around the table ?

Stéphane Laurent

unread,
Oct 25, 2013, 2:14:40 PM10/25/13
to shiny-...@googlegroups.com
Great: http://html.orange-idea.com/valera/tables_forms.html 

@Vincent: Is there any particular reason to prefer a css ? One could use such a function instead (in global.R):

pandoc.table.html <- function(t, ...){
  out <- pandoc.table.return(t, style="rmarkdown", ...)
  html <- markdownToHTML(text = out)
  Encoding(html) <- "UTF-8"
  gsub("<table>","<table class='table table-condensed table-bordered'>", html)
}

Vincent Nijs

unread,
Oct 25, 2013, 2:40:52 PM10/25/13
to shiny-...@googlegroups.com
I am using the table-condensed layout in a couple of places in my app now. For larger tables that do not require conditional formatting I am using xtable. It just seemed 'cleaner' to put the table formatting option in css.

By the way ... I found out you can use sub instead of gsub. 

Stéphane Laurent

unread,
Oct 27, 2013, 11:23:53 AM10/27/13
to shiny-...@googlegroups.com

I think @Ramnath's proposal is something like that (see  http://api.jquery.com/addClass/ ) :

          output[[pandoctable]] <- renderUI({ # test data summary in each tab 
            ... create a table named bbb...
            out <- pandoc.table.return(bbb, style="rmarkdown", emphasize.strong.cols=1, emphasize.cols=2)
            html <- markdownToHTML(text = out)
            Encoding(html) <- "UTF-8"
            list(tags$script(HTML(' 
                  $( "table" ).addClass( "table table-condensed" );
                ')),
            HTML(html)
           )
          })


It works but this is not more clean if we have to write this script at each html table output.

Vincent Nijs

unread,
Oct 28, 2013, 2:32:25 AM10/28/13
to shiny-...@googlegroups.com
You could pass bbb to a regular R function and have it pass back the formatted table. Nice to see the jquery example. Thanks Stéphane.

Stéphane Laurent

unread,
Oct 28, 2013, 3:44:20 AM10/28/13
to shiny-...@googlegroups.com
Hello Vincent,
 I don't understand what you mean. Pass the table to a regular function, what does it mean ? Do you simply mean a function returning the list with the tags$script ?

Vincent Nijs

unread,
Oct 28, 2013, 4:08:18 PM10/28/13
to shiny-...@googlegroups.com
Just something like the fancyTable function I mentioned earlier in this thread but then it takes bbb as input (i.e., the function is not a reactive).

Stéphane Laurent

unread,
Feb 20, 2014, 8:05:46 AM2/20/14
to shiny-...@googlegroups.com
Do you know why jQuery does not work on table elements generated by renderTable() ? This is what I conclude from my unsucessful attemps to answer to this question.

John Harrison

unread,
Feb 20, 2014, 10:00:48 AM2/20/14
to shiny-...@googlegroups.com
It is probably easier to set the css on the element you require (without defining a www/styles.css):

      tags$head(tags$style("#dummy table {background-color: red; }", media="screen", type="text/css"))

jquery as follows

$("#dummy table").css("background-color","red");

would work in the console but the DOM gets overwritten by shiny and you would need to tie the jquery into what shiny is doing.

Stéphane Laurent

unread,
Feb 20, 2014, 11:18:19 AM2/20/14
to shiny-...@googlegroups.com
Unsuccessful too :-(

John Harrison

unread,
Feb 20, 2014, 11:27:32 AM2/20/14
to shiny-...@googlegroups.com
Works for me:


runApp(
  list(ui = bootstrapPage(pageWithSidebar(
    headerPanel("Rummy"),
    sidebarPanel( tags$hr() ),
    
    mainPanel(
      
      # This is what I use to change the background color
      list(tags$head(tags$style("body {background-color: #ADD8E6; }"))),
      tableOutput("dummy"),

      tags$head(tags$style("#dummy table {background-color: red; }", media="screen", type="text/css"))
    )
    
  )
  )
 
  ,
  server = function(input, output) {
    output$dummy <- renderTable({ data.frame(A=1:4,B=2:5,C=rep("aaa",4)) })
  }
 
  )
)

Stéphane Laurent

unread,
Feb 20, 2014, 11:31:17 AM2/20/14
to shiny-...@googlegroups.com
Ah ok, you put tags$head after the table. Thank you !

John Harrison

unread,
Feb 20, 2014, 11:32:28 AM2/20/14
to shiny-...@googlegroups.com
Your welcome :)

Stéphane Laurent

unread,
Feb 20, 2014, 5:49:45 PM2/20/14
to shiny-...@googlegroups.com
Do you have an account on stacko ? Otherwise I can post your solution.

John Harrison

unread,
Feb 20, 2014, 7:50:51 PM2/20/14
to shiny-...@googlegroups.com
Stephane if you could post the solution that would be great.

sris Sri

unread,
Jul 15, 2014, 3:50:14 AM7/15/14
to shiny-...@googlegroups.com
I'm trying to do something similar, but I want to color the background depending on the value that is in a certain cell. I tried to battle with "      tags$head(tags$style("#dummy table {background-color: red; }", media="screen", type="text/css"))" in if-statements, but mostly nothing happens. Any help?

Stéphane Laurent

unread,
Jul 15, 2014, 4:04:32 AM7/15/14
to shiny-...@googlegroups.com

sris Sri

unread,
Jul 15, 2014, 5:12:11 AM7/15/14
to shiny-...@googlegroups.com
I've already seen and tried this out, but I encountered problems while downloading it. I was not able to use it.

I get this error:
Downloading master.zip from https://github.com/trestletech/shinyTable/archive/master.zip
Error in function (type, msg, asError = TRUE)  : couldn't connect to host

Stéphane Laurent

unread,
Jul 15, 2014, 5:18:17 AM7/15/14
to shiny-...@googlegroups.com
Sorry, I meant my code at the beginning of the discussion, not the shinyTable package.

Herman Sontrop

unread,
Jul 15, 2014, 6:19:17 AM7/15/14
to shiny-...@googlegroups.com
Hi,

if you want to conditionally color (or more generally format) cells in tables you may want to check out the reporters package. The FlexTables do what you want. As the name suggests, they are quite flexible.

Although the package is intended for generating Microsoft Word and PPT files via R, the underlying HTML can be extracted quite easily.

A while back I made a small Shiny toy example demo that shows the basic principle, see here.

hope this helps, best Herman

Op dinsdag 15 juli 2014 11:12:11 UTC+2 schreef sris Sri:
Reply all
Reply to author
Forward
0 new messages