2

Using R Shiny and DT : can one easily highlight/unhighlight interactively cells ?

I have been looking at the DT input$dt_cell_clicked to catch the row and the column that is clicked. I plan to then store that value in another column to highlight conditionally to that value (TRUE/FALSE).

My question is : can one do better + quicker with another option/function ?

library(shiny)
library(shinyjs)

library(dplyr)
library(DT)

options(DT.options = list(pageLength = 5))
df = as.data.frame(
        cbind(
                matrix(round(rnorm(50), 3), 10),
                sample(0:1, 10, TRUE),
                rep(FALSE, 10)
        )
)
# getwd()
setwd(here::here())
# write.csv(df, "data/df_test.csv")

ui <- fluidPage(
        h2("Last clicked:"),
        verbatimTextOutput("last_clicked"),
        actionButton("reset", "Reset clicked value"),
        h2("Datatable:"),
        DT::dataTableOutput("dt"),
        useShinyjs(),
        extendShinyjs(text = paste0("shinyjs.resetDTClick = function() { Shiny.onInputChange('dt_cell_clicked', null); }"))
)

server <- function(input, output) {

        # the last clicked value
        output$last_clicked <- renderPrint({
                str(input$dt_cell_clicked)
        })

        df_new <- reactive({

                # res <- read.csv("data/df_test.csv")
                res <- df
                res
        })

        output$dt <- DT::renderDataTable({
                # DT::datatable(head(mtcars, 2))
                DT::datatable(df_new(), select = "none", editable = TRUE) %>% formatStyle(
                        'V1', 'V6',
                        backgroundColor = styleEqual(c(0, 1), c('gray', 'yellow'))
                )
        })

        observeEvent(input$dt_cell_clicked, {
                validate(need(length(input$dt_cell_clicked) > 0, ''))
                # alert("You clicked something!")

                if(!is.null(input$dt_cell_clicked)){
                        # df[input$dt_cell_clicked$row, input$dt_cell_clicked$column] <- ifelse(0, 1, 0)
                        cat("changing value")
                        df_test <- df_new()
                        df_test[input$dt_cell_clicked$row, input$dt_cell_clicked$column] <- ifelse(0, 1, 0)
                        write.csv(df_test, "data/df_test.csv")
                        rm(df_test)
                        # i
                }
        })

        # use dt_cell_clicked to infer on bool cell

        # df_new <- eventReactive(input$dt_cell_clicked, {
        # df_new <- reactive({
        #
        # })

        observeEvent(input$reset, {
                js$resetDTClick()
        })
}

shinyApp(ui, server)

Expected (not yet implemented) : When clicked a cell highlight/unhighlight.

This code is mixed from : How to change the cell color of a cell of an R Shiny data table dependent on it's value? DataTables DT: reset value of clicked cell

NelsonGon
  • 13,015
  • 7
  • 27
  • 57
cbo
  • 1,664
  • 1
  • 12
  • 27

1 Answers1

3

You could simply use single cell selection for highlighting:

library(shiny)
library(DT)

options(DT.options = list(pageLength = 5))

DF = as.data.frame(
  cbind(
    matrix(round(rnorm(50), 3), 10),
    sample(0:1, 10, TRUE),
    rep(FALSE, 10)
  )
)

ui <- shinyUI(
  fluidRow(
    tags$style(HTML('table.dataTable tr.selected td, table.dataTable td.selected {background-color: lightgreen !important;}')),
    DT::dataTableOutput("myDT")
  )
)

server <- shinyServer(function(input, output, session) {

  output$myDT <- DT::renderDataTable({
    DT::datatable(DF, selection = list(mode="single", target="cell"), editable = TRUE) %>% formatStyle(
      'V1', 'V6',
      backgroundColor = styleEqual(c(0, 1), c('gray', 'yellow'))
    )
  })

})

shinyApp(ui, server)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78