R rhandsontable conditional formatting of several checkbox columns

Viewed 44

I am creating a Shiny App in which I have a rhandsontable; the last 2 columns of this table are filled with checkboxes. I would like to apply conditional formatting: green background when checkbox is true, red background when checkbox is false.

Inspired by the post How to change the colour of some rows with rhansontable and checkbox?, I was able to achieve formatting of 1 column. For example:

library(shiny)
library(rhandsontable)
ui <- fluidPage(
  rHandsontableOutput('table')
)
server <- function(input, output) {
  df <- data.frame(alphabet = letters[1:10],
                   include = TRUE,
                   include2 = FALSE)
  output$table <- rhandsontable::renderRHandsontable({
    col_highlight <- 2
    rhandsontable(df, height = 500) %>%
      hot_col(col_highlight,
              renderer = "             
              function (instance, td, row, col, prop, value, cellProperties) {
                    Handsontable.renderers.CheckboxRenderer.apply(this, arguments);
                    var col_value = instance.getData()[row][1]
                    if ( col_value ) {
                        td.style.background = '#C3FA9A';
                    } 
                    if ( !col_value) {
                        td.style.background ='#ff4d4d'
                    }}") })}
shinyApp(ui, server)

but when I try to do it for mutliple columns with hot_cols in a similar way as I did other kinds of conditional formating in the past, it does not work anymore. I am really newbie in javascript, I suspect something is wrong in the col_value definition, but am not able to figure out what... Here my code so far:

library(shiny)
library(rhandsontable)
# Define UI for application that draws a histogram
ui <- fluidPage(
  rHandsontableOutput('table')
)
# Define server logic required to draw a histogram
server <- function(input, output) {
  df <- data.frame(alphabet = letters[1:10],
                   include = TRUE,
                   include2 = FALSE)
  output$table <- rhandsontable::renderRHandsontable({
    col_highlight <- 2:3    
    rhandsontable(df, height = 500, col_highlight=col_highlight-1) %>%
      hot_cols(
              renderer = "
                function (instance, td, row, col, prop, value, cellProperties) {
                    Handsontable.renderers.CheckboxRenderer.apply(this, arguments);
                   if (instance.params) {
                       hcols = instance.params.col_highlight;
                       hcols = hcols instanceof Array ? hcols : [hcols];
                  }
                    var col_value = instance.getData()[row][1]
                    if (instance.params && hcols.includes(col) && col_value ) {
                        td.style.background = '#C3FA9A';
                    } 
                    if (instance.params && hcols.includes(col) && ! col_value) {
                        td.style.background ='#ff4d4d'
                    }}")})}
shinyApp(ui, server)

I imagine I could use repeatedly hot_col, but don't find this way very elegant... If anyone could help to solve it with hot_cols, I would be very very grateful !

Thanks in advance

1 Answers

ah I finally figure out what was the issue... I did not remove the question in case this could help someone else... The following code makes the job:

library(shiny)
library(rhandsontable)

ui <- fluidPage(
  rHandsontableOutput('table')
)
server <- function(input, output) {
  df <- data.frame(alphabet = letters[1:10],
                   include = TRUE,
                   include2 = FALSE)
  output$table <- rhandsontable::renderRHandsontable({
    
    col_highlight <- 2:3
    
    rhandsontable(df, height = 500, col_highlight=col_highlight-1 ) %>%
      hot_cols(
              renderer = "             
              function (instance, td, row, col, prop, value, cellProperties) {
                
                    Handsontable.renderers.CheckboxRenderer.apply(this, arguments);
                   if (instance.params) {
                       hcols = instance.params.col_highlight;
                       hcols = hcols instanceof Array ? hcols : [hcols];
                  }
                    if (instance.params && hcols.includes(col) && value ) {
                    
                        td.style.background = '#C3FA9A';
                    }  else if (instance.params && hcols.includes(col) && ! value) {
                        td.style.background ='#ff4d4d'
                    } else {
        // render as text
        Handsontable.renderers.TextRenderer.apply(this, arguments);
      }
                    }

            ") 
  })
}
shinyApp(ui, server)
Related