thiagogps
thiagogps

Reputation: 489

Correct way to customize color of rhandsontable inside a Shiny app

So, I'm creating a shiny app and I'd like to color some rows in a table generated with rhandsontable.

I'm following this very good tutorial: https://jrowen.github.io/rhandsontable/

Specifically, I'm interested in this part:

library(rhandsontable)
DF = data.frame(val = 1:10, bool = TRUE, big = LETTERS[1:10],
                small = letters[1:10],
                dt = seq(from = Sys.Date(), by = "days", length.out = 10),
                stringsAsFactors = FALSE)

col_highlight = 2
row_highlight = c(5, 7)

rhandsontable(DF, col_highlight = col_highlight, 
              row_highlight = row_highlight,
              width = 550, height = 300) %>%
  hot_cols(renderer = "
    function(instance, td, row, col, prop, value, cellProperties) {
      Handsontable.TextCell.renderer.apply(this, arguments);

      tbl = this.HTMLWidgets.widgets[0]

      hcols = tbl.params.col_highlight
      hcols = hcols instanceof Array ? hcols : [hcols] 
      hrows = tbl.params.row_highlight
      hrows = hrows instanceof Array ? hrows : [hrows] 

      if (hcols.includes(col) && hrows.includes(row)) {
        td.style.background = 'red';
      }
      else if (hcols.includes(col)) {
        td.style.background = 'lightgreen';
      }
      else if (hrows.includes(row)) {
        td.style.background = 'pink';
      }

      return td;
  }")

This code works in RStudio, but not on Shiny (the table simply doesn't show up). There is an explanation in the website, saying that if using this on Shiny, we should add that part to the code:

HTMLWidgets.widgets.filter(function(widget) {
  // this should match the table id specified in the shiny app
  return widget.name === "hot"
})[0];

However, since I know nothing about javascript, I'm a little lost as to where should this part go. I tried many things, including:

 rhandsontable(DF, col_highlight = col_highlight, 
                  row_highlight = row_highlight,
                  width = 550, height = 300) %>%
      hot_cols(renderer = "
        function(instance, td, row, col, prop, value, cellProperties) {
          Handsontable.TextCell.renderer.apply(this, arguments);
          HTMLWidgets.widgets.filter(function(widget) {
            // this should match the table id specified in the shiny app
            return widget.name === \"hot\"
          })[0];
      ..

But it's still not correct.

This is probably a very basic question for anyone familiar with js, but what is the correct way to do this?

Upvotes: 7

Views: 3504

Answers (2)

lin
lin

Reputation: 118

Follow the discussion of dealing Booleans in accepted answer. Note that hot_col can assign which columns be formatted. Hence just exclude the boolean column. For instance, the below code only used column 1 and column 2 and column 3, bool, was removed.

library(shiny)
library(rhandsontable)

ui <- shinyUI(bootstrapPage(
    rHandsontableOutput("hot")
))

server <- shinyServer(function(input, output) {
    output$hot <- renderRHandsontable({
        DF = data.frame(val = 1:10, big = LETTERS[1:10],bool=T)
        col_highlight = c(0, 1)
        row_highlight = c(3)
    
        rhandsontable(DF, col_highlight = col_highlight, row_highlight = row_highlight) %>%
        hot_col(col=c(1,2),renderer = "
            function(instance, td, row, col, prop, value, cellProperties) {
                Handsontable.renderers.NumericRenderer.apply(this, arguments);
                if (instance.params) {
                    hcols = instance.params.col_highlight
                    hcols = hcols instanceof Array ? hcols : [hcols]
                    hrows = instance.params.row_highlight
                    hrows = hrows instanceof Array ? hrows : [hrows]
                }
                if (instance.params && hcols.includes(col)) td.style.background = 'red';
                if (instance.params && hrows.includes(row)) td.style.background = 'yellow';
            }")
    })
})

shinyApp(ui, server)

The results are as:

Results for dealing with bool

Upvotes: 1

Kipras Kančys
Kipras Kančys

Reputation: 1779

Simple example of colouring columns and rows.

library(shiny)
library(rhandsontable)

ui <- shinyUI(bootstrapPage(
    rHandsontableOutput("hot")
))

server <- shinyServer(function(input, output) {
    output$hot <- renderRHandsontable({
        DF = data.frame(val = 1:10, big = LETTERS[1:10])
        col_highlight = c(0, 1)
        row_highlight = c(3)
    
        rhandsontable(DF, col_highlight = col_highlight, row_highlight = row_highlight) %>%
        hot_cols(renderer = "
            function(instance, td, row, col, prop, value, cellProperties) {
                Handsontable.renderers.NumericRenderer.apply(this, arguments);
                if (instance.params) {
                    hcols = instance.params.col_highlight
                    hcols = hcols instanceof Array ? hcols : [hcols]
                    hrows = instance.params.row_highlight
                    hrows = hrows instanceof Array ? hrows : [hrows]
                }
                if (instance.params && hcols.includes(col)) td.style.background = 'red';
                if (instance.params && hrows.includes(row)) td.style.background = 'yellow';
            }")
    })
})

shinyApp(ui, server)

Upvotes: 11

Related Questions