Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add vertical line in a DT datatable in a shiny app with custom container

Tags:

r

dt

shiny

I want to add a vertical line between groups of columns. Here is a desired outcome:

---------
g1  | g2
---------
a b | a b
---------
1 2 | 3 4
---------

and a shiny app to start with:

library(shiny)
library(DT)
library(htmltools)

runApp(shinyApp(
  ui <- basicPage(
    DT::dataTableOutput('table1')
  ),
  server = function(input, output) {
    output$table1 <- DT::renderDataTable({
      datatable(data.frame(a1 = 1, b1 = 2, a2 = 3, b2 = 4), rownames = FALSE,
                container = withTags(table(
                  class = 'display',
                  thead(
                    tr(
                      th(colspan = 2, 'g1'),
                      th(colspan = 2, 'g2')
                    ),
                    tr(
                      lapply(rep(c('a', 'b'), 2), th)
                    )
                  )
                ))
      )
    })
  }
))

Current output from shiny app above:

enter image description here

like image 830
danas.zuokas Avatar asked Apr 18 '16 11:04

danas.zuokas


1 Answers

You could add a css class that adds a border on the right of the cells and apply it to the relevant columns using the columnDefs options. For the header, you can set the class using the initComplete callback.

Here's an example:

library(shiny)
library(DT)
library(htmltools)

runApp(shinyApp(
  ui <- basicPage(
    tags$head(
      tags$style(HTML(".cell-border-right{border-right: 1px solid #000}"))),
    DT::dataTableOutput('table1')
  ),
  server = function(input, output) {
    output$table1 <- DT::renderDataTable({
      datatable(data.frame(a1 = 1, b1 = 2, a2 = 3, b2 = 4), rownames = FALSE,
                container = withTags(table(
                  class = 'display',
                  thead(
                    tr(
                      th(colspan = 2, 'g1'),
                      th(colspan = 2, 'g2')
                    ),
                    tr(
                      lapply(rep(c('a', 'b'), 2), th)
                    )
                  )
                )),options = list(initComplete = JS(
                  "function(settings, json) {",
                  "var headerBorder = [0,1];",
                  "var header = $(this.api().table().header()).find('tr:first > th').filter(function(index) {return $.inArray(index,headerBorder) > -1 ;}).addClass('cell-border-right');",
                  "}"),columnDefs=list(list(className="dt-right cell-border-right",targets=1))
      ))
    })
  }
))

The jquery selectors are used to select the first row of the header and the first th tag, so that the border is only added to the g1 cell.

like image 150
NicE Avatar answered Nov 13 '22 17:11

NicE