| Hao Zhu | 501fb45 | 2017-07-05 14:37:13 -0400 | [diff] [blame] | 1 | #' Put a HTML table into a scrollable box | 
|  | 2 | #' | 
|  | 3 | #' @description This function will put a HTML kable object in a fixed-height, | 
|  | 4 | #' fixed-width or both box and make it scrollable. | 
|  | 5 | #' | 
|  | 6 | #' @param kable_input A HTML kable object | 
|  | 7 | #' @param height A character string indicating the height of the box, e.g. "50px" | 
|  | 8 | #' @param width A character string indicating the width of the box, e.g. "100px" | 
| Hao Zhu | 4b0c51e | 2017-08-01 15:21:07 -0400 | [diff] [blame] | 9 | #' @param box_css CSS text for the box | 
|  | 10 | #' @param extra_css Extra CSS styles | 
| Hao Zhu | 72917f9 | 2019-03-15 18:41:42 -0400 | [diff] [blame] | 11 | #' @param fixed_thead HTML table option so table header row is fixed at top. | 
|  | 12 | #' Values can be either T/F or `list(enabled = T/F, background = "anycolor")`. | 
| Hao Zhu | 501fb45 | 2017-07-05 14:37:13 -0400 | [diff] [blame] | 13 | #' | 
|  | 14 | #' @export | 
| Irene | 319a546 | 2018-04-17 15:37:39 -0700 | [diff] [blame] | 15 | #' | 
|  | 16 | #' @examples | 
|  | 17 | #' \dontrun{ | 
|  | 18 | #' # Specify table size by pixels | 
|  | 19 | #' kable(cbind(mtcars, mtcars), "html") %>% | 
|  | 20 | #'     kable_styling() %>% | 
|  | 21 | #'     scroll_box(width = "500px", height = "200px") | 
|  | 22 | #' | 
|  | 23 | #' # Specify by percent | 
|  | 24 | #' kable(cbind(mtcars, mtcars), "html") %>% | 
|  | 25 | #'     kable_styling() %>% | 
|  | 26 | #'     scroll_box(width = "100%", height = "200px") | 
|  | 27 | #' } | 
| Hao Zhu | 4b0c51e | 2017-08-01 15:21:07 -0400 | [diff] [blame] | 28 | scroll_box <- function(kable_input, height = NULL, width = NULL, | 
|  | 29 | box_css = "border: 1px solid #ddd; padding: 5px; ", | 
| Hao Zhu | 72917f9 | 2019-03-15 18:41:42 -0400 | [diff] [blame] | 30 | extra_css = NULL, | 
|  | 31 | fixed_thead = TRUE | 
|  | 32 | ) { | 
| Jrmie | aa30498 | 2018-12-08 00:14:16 +0100 | [diff] [blame] | 33 |  | 
| Hao Zhu | 501fb45 | 2017-07-05 14:37:13 -0400 | [diff] [blame] | 34 | kable_attrs <- attributes(kable_input) | 
| Hao Zhu | 72917f9 | 2019-03-15 18:41:42 -0400 | [diff] [blame] | 35 | fixed_thead <- get_fixed_thead(fixed_thead) | 
|  | 36 | if (is.null(height)) fixed_thead$enabled <- FALSE | 
| Jrmie | aa30498 | 2018-12-08 00:14:16 +0100 | [diff] [blame] | 37 |  | 
|  | 38 | if (fixed_thead$enabled) { | 
|  | 39 | box_css = "border: 1px solid #ddd; padding: 0px; " | 
|  | 40 | kable_xml <- read_kable_as_xml(kable_input) | 
| Hao Zhu | 72917f9 | 2019-03-15 18:41:42 -0400 | [diff] [blame] | 41 | all_header_cells <- xml2::xml_find_all(kable_xml, "//thead//th") | 
|  | 42 | if (is.null(fixed_thead$background))  fixed_thead$background <- "#FFFFFF" | 
|  | 43 | for (i in seq(length(all_header_cells))) { | 
|  | 44 | xml_attr(all_header_cells[i], "style") <- paste0( | 
|  | 45 | xml_attr(all_header_cells[i], "style"), | 
|  | 46 | "position: sticky; top:0; background-color: ", | 
|  | 47 | fixed_thead$background, ";" | 
|  | 48 | ) | 
| Jrmie | aa30498 | 2018-12-08 00:14:16 +0100 | [diff] [blame] | 49 | } | 
|  | 50 | out <- as.character(as_kable_xml(kable_xml)) | 
|  | 51 | } else { | 
|  | 52 | out <- as.character(kable_input) | 
|  | 53 | } | 
|  | 54 |  | 
| Hao Zhu | 4b0c51e | 2017-08-01 15:21:07 -0400 | [diff] [blame] | 55 | box_styles <- c(box_css, extra_css) | 
| Jrmie | aa30498 | 2018-12-08 00:14:16 +0100 | [diff] [blame] | 56 |  | 
| Hao Zhu | 501fb45 | 2017-07-05 14:37:13 -0400 | [diff] [blame] | 57 | if (!is.null(height)) { | 
|  | 58 | box_styles <- c(box_styles, | 
|  | 59 | paste0("overflow-y: scroll; height:", height, "; ")) | 
|  | 60 | } | 
| Jrmie | aa30498 | 2018-12-08 00:14:16 +0100 | [diff] [blame] | 61 |  | 
| Hao Zhu | 501fb45 | 2017-07-05 14:37:13 -0400 | [diff] [blame] | 62 | if (!is.null(width)) { | 
|  | 63 | box_styles <- c(box_styles, | 
|  | 64 | paste0("overflow-x: scroll; width:", width, "; ")) | 
|  | 65 | } | 
| Jrmie | aa30498 | 2018-12-08 00:14:16 +0100 | [diff] [blame] | 66 |  | 
| Hao Zhu | 501fb45 | 2017-07-05 14:37:13 -0400 | [diff] [blame] | 67 | out <- paste0('<div style="', paste(box_styles, collapse = ""), '">', | 
|  | 68 | out, '</div>') | 
|  | 69 | out <- structure(out, format = "html", | 
|  | 70 | class = "knitr_kable") | 
|  | 71 | attributes(out) <- kable_attrs | 
| Jrmie | aa30498 | 2018-12-08 00:14:16 +0100 | [diff] [blame] | 72 |  | 
| Hao Zhu | f210083 | 2018-01-11 16:20:29 -0500 | [diff] [blame] | 73 | if (!"kableExtra" %in% class(out)) class(out) <- c("kableExtra", class(out)) | 
| Jrmie | aa30498 | 2018-12-08 00:14:16 +0100 | [diff] [blame] | 74 |  | 
| Hao Zhu | 501fb45 | 2017-07-05 14:37:13 -0400 | [diff] [blame] | 75 | return(out) | 
|  | 76 | } | 
| Hao Zhu | 72917f9 | 2019-03-15 18:41:42 -0400 | [diff] [blame] | 77 |  | 
|  | 78 | get_fixed_thead <- function(x) { | 
|  | 79 | if (is.logical(x)) { | 
|  | 80 | if (x) return(list(enabled = TRUE, background = "#FFFFFF")) | 
|  | 81 | return(list(enabled = FALSE)) | 
|  | 82 | } | 
|  | 83 | return(x) | 
|  | 84 | } |