Color a whole row in rhandsontable based on a string value in one column

橙三吉。 提交于 2019-12-11 05:34:40

问题


I have an rhandsontable and I want the WHOLE ROW to be yellow if the cell in the text in the last column ("Comments") includes string "missed".

The code below highlights any cell that has a value 'missed', but not the whole row. Besides, I'd like the row to turn yellow when a cell in the last column CONTAINS "missed" - even inside a longer string, and not just when it contains only "missed" - as it is written now - I just don't know how to match strings in JavaScript.

DF = data.frame(a = 1:2, b = 3:4, Comments = c("missed etc", "missed"))
rhandsontable(DF, width = 550, height = 300) %>%
  hot_cols(renderer = " function (instance, td, row, col, prop, value, cellProperties) { 
                     Handsontable.renderers.TextRenderer.apply(this, arguments); 
                     if(value == 'missed') { 
                     td.style.background = 'yellow' } 
                     }")

Thank you very much!

To clarify, in reality, I am dealing with a larger table that I am rendering in rShiny. So, ideally the solution that works for the little data frame above should also work here. Currently it is not (nothing shows up at all):

    output$session_table <- renderRHandsontable({
        req(input$select_a_patient)
        patient_nr <- which(patient_names_reactive$names %in% input$select_a_patient)

        row_highlight = which(grepl("missed", 
sessions_reactive$sessions[[patient_nr]]$Comments))-1

        rhandsontable(sessions_reactive$sessions[[patient_nr]],
                      row_highlight = row_highlight,
                      width = 1000, height = 500) %>% 
            hot_rows(fixedRowsTop = 1) %>%
            hot_table(highlightCol = TRUE, highlightRow = TRUE) %>% 
            hot_validate_numeric(cols = c(3, 5), min = 0, max = 500) %>% 
            hot_col(c(1, 3, 5, 6, 8), valign = 'htCenter') %>%
            hot_cols(renderer = " 
            function (instance, td, row, col, prop, value, cellProperties) { 
                     Handsontable.renderers.TextRenderer.apply(this, arguments); 

                     tbl = this.HTMLWidgets.widgets[0]
                     hrows = tbl.params.row_highlight
                     hrows = hrows instanceof Array ? hrows : [hrows]

                     if (hrows.includes(row)) { 
                       td.style.background = 'yellow' } 
                     }") %>% hot_col(c(5, 8), renderer = " 
                        function (instance, td, row, col, prop, value, cellProperties) {
                           Handsontable.renderers.TextRenderer.apply(this, arguments);
                           td.style.fontWeight = 'bold';
                           td.style.color = '#fc0f03';}"
            )

回答1:


Based on the tutorial using a custom renderer:

https://jrowen.github.io/rhandsontable/

you could do the following (doing the string match outside of the js).

DF = data.frame(a = 1:4, b = 3:6, Comments = c("missed etc", "", "missed", ""))

rhandsontable(DF, row_highlight = which(grepl("missed", DF$Comments))-1, width = 550, height = 300) %>%
  hot_cols(renderer = "function (instance, td, row, col, prop, value, cellProperties) { 
                     Handsontable.renderers.TextRenderer.apply(this, arguments); 

                     tbl = this.HTMLWidgets.widgets[0]

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

                     if (hrows.includes(row)) { 
                       td.style.background = 'yellow' } 
                     }")

Edit: This apparently requires additional modification if used as a shiny app. As noted in documentation:

When using this approach in a shiny app or in a document with more than one widget, the widget search logic will need to be more robust.

If instance.params is available, we can try the following:

library(shiny)
library(rhandsontable)

DF = data.frame(a=1:10, b=3:12, c=c("Dog", "Cat", "Mouse", 5:11), d=3:12, e=1:10, f=1:10, g=1:10, h=2:11, Comments = c("missed etc", rep("", 7), "missed", ""))

ui <- fluidPage(
  mainPanel(
    rHandsontableOutput('table')
  )
)

server = function(input, output, session) {

  output$table <- renderRHandsontable({
    row_highlight = which(grepl("missed", DF$Comments))-1
    col_highlight = c(5,8)-1
    rhandsontable(DF, row_highlight = row_highlight, col_highlight = col_highlight, width = 550, height = 300) %>%
      hot_rows(fixedRowsTop = 1) %>%
      hot_table(highlightCol = TRUE, highlightRow = TRUE) %>% 
      hot_validate_numeric(cols = c(3, 5), min = 0, max = 500) %>% 
      hot_col(c(1, 3, 5, 6, 8), valign = 'htCenter') %>%
      hot_cols(renderer = "
            function (instance, td, row, col, prop, value, cellProperties) {
                     Handsontable.renderers.TextRenderer.apply(this, arguments);

                     if (instance.params) {
                       hrows = instance.params.row_highlight
                       hrows = hrows instanceof Array ? hrows : [hrows]
                       hcols = instance.params.col_highlight
                       hcols = hcols instanceof Array ? hcols : [hcols]

                       if (hrows.includes(row)) {
                         td.style.background = 'yellow' 
                       }

                       if (hcols.includes(col)) {
                         td.style.fontWeight = 'bold'
                         td.style.color = '#fc0f03'
                       }
                     }
            }"
      ) 
  })
}

shinyApp(ui, server)

Edit1: Integrated second renderer with the first one, so that column formatting doesn't overwrite row background color.

Edit2: Adding explanation regarding col_highlight added.

Starting at the beginning we have col_highlight = c(5,8)-1 which creates a vector storing the columns we wish to have different formatting (bold, red font). We subtract one since arrays in javascript are zero-based.

The following line for rhandsontable allows us to pass in col_highlight = col_highlight so that we can later access these selected columns through instance.params.col_highlight in the renderer function later on. Once we access them and assign them to hcols, we make sure it is an array if it wasn't already.

The statement if (hcols.includes(col)) checks to see if the hcols array contains the column (col) being rendered. If the column rendered is 5, this is contained in the vector (5, 8), and the td.style would be set to bold and red.

Note that since hrows would only change background color, and hcols would only change font bold and color, one does not overwrite the other, and can be used together.



来源:https://stackoverflow.com/questions/58142090/color-a-whole-row-in-rhandsontable-based-on-a-string-value-in-one-column

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!